diff options
author | Minteck <contact@minteck.org> | 2022-11-28 17:14:38 +0100 |
---|---|---|
committer | Minteck <contact@minteck.org> | 2022-11-28 17:14:38 +0100 |
commit | 18efd30a263ec0d79a26a82cbd8c90c9f81056b7 (patch) | |
tree | aea01bf3506dda706719fc68eb37b77ed9ef3fe8 /src/core/Authentication.ts | |
download | autoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.tar.gz autoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.tar.bz2 autoreport-18efd30a263ec0d79a26a82cbd8c90c9f81056b7.zip |
Diffstat (limited to 'src/core/Authentication.ts')
-rw-r--r-- | src/core/Authentication.ts | 93 |
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 |