diff --git a/backendV2/services/athentication.js b/backendV2/services/athentication.js new file mode 100644 index 0000000..41d4301 --- /dev/null +++ b/backendV2/services/athentication.js @@ -0,0 +1,65 @@ +import { SignJWT, jwtVerify } from "jose"; +import env from "dotenv"; +import { getAllApiKeys } from "./database"; +env.config(); + +const secretKey = process.env.SECRET_KEY; +if (!secretKey) { + throw new Error("Missing SECRET_KEY environment variable"); +} +const secret = new TextEncoder().encode(secretKey); + +export async function generateToken(payload) { + return await new SignJWT(payload) + .setProtectedHeader({ alg: "HS256" }) + .setIssuedAt() + .setExpirationTime("2h") + .sign(secret); +} + +export async function authenticate(req, res, next) { + const authHeader = req.headers["authorization"]; + const apiKey = req.params.apiKey; + + if (authHeader) { + const parts = authHeader.split(" "); + const scheme = parts[0]; + const token = parts[1]; + + if (!/^Bearer$/i.test(scheme) || !token) { + return res.status(401).json({ message: "Unauthorized" }); + } + + try { + const payload = await verifyToken(token); + req.user = payload; + return next(); + } catch { + return res.sendStatus(403); // present token invalid + } + } else if (apiKey) { + try { + await verifyAPIKey(apiKey); + return next(); + } catch { + return res.sendStatus(403); // API Key invalid + } + } else { + return res.status(401).json({ message: "Unauthorized" }); // no credentials + } +} + +async function verifyAPIKey(apiKey) { + const apiKeys = await getAllApiKeys(); + const validKey = apiKeys.find((k) => k.key === apiKey); + if (!validKey) { + throw new Error("Invalid API Key"); + } +} + +async function verifyToken(token) { + const { payload } = await jwtVerify(token, secret, { + algorithms: ["HS256"], + }); + return payload; +} diff --git a/backendV2/services/tokenService.js b/backendV2/services/tokenService.js deleted file mode 100644 index 6d39377..0000000 --- a/backendV2/services/tokenService.js +++ /dev/null @@ -1,25 +0,0 @@ -import { SignJWT, jwtVerify } from "jose"; -import env from "dotenv"; -env.config(); -const secret = new TextEncoder().encode(process.env.SECRET_KEY); - -export async function generateToken(payload) { - const newToken = await new SignJWT(payload) - .setProtectedHeader({ alg: "HS256" }) - .setIssuedAt() - .setExpirationTime("2h") // Token valid for 2 hours - .sign(secret); - return newToken; -} - -export async function authenticate(req, res, next) { - const authHeader = req.headers["authorization"]; - const token = authHeader && authHeader.split(" ")[1]; // Bearer - - if (token == null) return res.sendStatus(401); // No token present - - const { payload } = await jwtVerify(token, secret); - req.user = payload; - - next(); -}