summaryrefslogtreecommitdiff
path: root/src/core/Authentication.ts
diff options
context:
space:
mode:
authorMinteck <contact@minteck.org>2022-11-28 17:14:38 +0100
committerMinteck <contact@minteck.org>2022-11-28 17:14:38 +0100
commit18efd30a263ec0d79a26a82cbd8c90c9f81056b7 (patch)
treeaea01bf3506dda706719fc68eb37b77ed9ef3fe8 /src/core/Authentication.ts
downloadautoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.tar.gz
autoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.tar.bz2
autoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.zip
Open sourceHEADmane
Diffstat (limited to 'src/core/Authentication.ts')
-rw-r--r--src/core/Authentication.ts93
1 files changed, 93 insertions, 0 deletions
diff --git a/src/core/Authentication.ts b/src/core/Authentication.ts
new file mode 100644
index 0000000..f298bdf
--- /dev/null
+++ b/src/core/Authentication.ts
@@ -0,0 +1,93 @@
+import AutoreportBase from "./AutoreportBase";
+import axios from "axios";
+import { readFileSync, writeFileSync } from "node:fs";
+import { randomBytes } from "crypto";
+
+export default class Authentication extends AutoreportBase {
+ public static getToken(token) {
+ let tokens = JSON.parse(readFileSync(AutoreportBase.getRoot() + "/data/tokens.json").toString());
+
+ if (Object.keys(tokens).includes(token) && new Date(tokens[token].date).getTime() - new Date().getTime() <= 31000000) {
+ return tokens[token].info;
+ } else {
+ return false;
+ }
+ }
+
+ private static saveToken(userInfo) {
+ let tokens = JSON.parse(readFileSync(AutoreportBase.getRoot() + "/data/tokens.json").toString());
+ let token = randomBytes(64).toString("base64url");
+
+ tokens[token] = {
+ date: new Date().getTime(),
+ info: userInfo
+ };
+ writeFileSync(AutoreportBase.getRoot() + "/data/tokens.json", JSON.stringify(tokens));
+
+ return token;
+ }
+
+ public static startFlow(req, res) {
+ res.redirect(`${AutoreportBase.config.authentication.server}/api/rest/oauth2/auth?client_id=${AutoreportBase.config.authentication.id}&response_type=code&redirect_uri=${AutoreportBase.config.authentication.redirect}&scope=Hub&request_credentials=default&access_type=offline`);
+ }
+
+ public static checkAuthentication(req) {
+ let _cookies = req.headers.cookie ?? "";
+ let _tokens = _cookies.split(";").map(i => i.trim().split("=")).filter(i => i[0] === "AutoreportToken");
+ let __tokens = _tokens[0] ?? [];
+ let token = __tokens[1] ?? null;
+
+ return !(!token || !this.getToken(token));
+ }
+
+ public static async callback(req, res) {
+ if (!req.query.code) {
+ res.redirect("/");
+ }
+
+ let token = (await axios.post(`${AutoreportBase.config.authentication.server}/api/rest/oauth2/token`, `grant_type=authorization_code&redirect_uri=${encodeURIComponent(AutoreportBase.config.authentication.redirect)}&code=${req.query.code}`, {
+ headers: {
+ 'Authorization': `Basic ${Buffer.from(`${AutoreportBase.config.authentication.id}:${AutoreportBase.config.authentication.secret}`).toString("base64")}`,
+ 'Accept': "application/json",
+ 'Content-Type': "application/x-www-form-urlencoded"
+ }
+ })).data.access_token;
+
+ let userInfo = (await axios.get(`${AutoreportBase.config.authentication.server}/api/rest/users/me`, {
+ headers: {
+ 'Authorization': `Bearer ${token}`,
+ 'Accept': "application/json"
+ }
+ })).data;
+
+ let userToken = Authentication.saveToken(userInfo);
+ res.cookie('AutoreportToken', userToken, { maxAge: 31000000, httpOnly: true });
+ res.redirect("/");
+ }
+
+ public static testEndpoint(req, res) {
+ if (Authentication.checkAuthentication(req)) {
+ res.send("Authenticated");
+ } else {
+ res.send("NOT authenticated");
+ }
+ }
+
+ public static protectedAPI(req, res, next) {
+ if ([null, undefined, ""].includes(req.get("authorization"))) {
+ return res.status(401).json({
+ code: 401,
+ message: "Please provide an Authorization header."
+ });
+ }
+
+ if (req.get("authorization") !== AutoreportBase.config.api.token) {
+ return res.status(403).json( {
+ code: 403,
+ message: "You do not have permission to use this endpoint."
+ });
+ }
+
+ next();
+ }
+} \ No newline at end of file