major changes to docker and npm config
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { SignJWT, jwtVerify } from "jose";
|
||||
import env from "dotenv";
|
||||
import { verifyAPIKeyDB } from "./database.js";
|
||||
import { checkIfServiceIsActive2 } from "./functions.js";
|
||||
env.config();
|
||||
|
||||
const api_service = "API";
|
||||
const user_frontend_service = "User Frontend";
|
||||
|
||||
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 authenticateAdmin(req, res, next) {
|
||||
const authHeader = req.headers["authorization"];
|
||||
if (!authHeader) {
|
||||
return res.status(401).json({ message: "Unauthorized" });
|
||||
}
|
||||
|
||||
const [scheme, token] = authHeader.split(" ");
|
||||
if (!/^Bearer$/i.test(scheme) || !token) {
|
||||
return res.status(401).json({ message: "Unauthorized" });
|
||||
}
|
||||
|
||||
try {
|
||||
const payload = await verifyToken(token);
|
||||
if (!payload?.admin) {
|
||||
return res.status(403).json({ message: "Forbidden: admin only" });
|
||||
}
|
||||
req.user = payload;
|
||||
return next();
|
||||
} catch {
|
||||
return res.status(403).json({ message: "Forbidden 403" });
|
||||
}
|
||||
}
|
||||
|
||||
export async function authenticate(req, res, next) {
|
||||
const authHeader = req.headers["authorization"];
|
||||
const apiKey = req.params.key;
|
||||
|
||||
if (authHeader) {
|
||||
const serviceActive = await checkIfServiceIsActive2(user_frontend_service);
|
||||
if (!serviceActive) {
|
||||
return res
|
||||
.status(503)
|
||||
.json({ message: "User Frontend is currently unavailable." });
|
||||
}
|
||||
|
||||
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.status(403).json({ message: "Present token invalid" }); // present token invalid
|
||||
}
|
||||
} else if (apiKey) {
|
||||
const serviceActive = await checkIfServiceIsActive2(api_service);
|
||||
if (!serviceActive) {
|
||||
return res
|
||||
.status(503)
|
||||
.json({ message: "API Service is currently unavailable." });
|
||||
}
|
||||
|
||||
try {
|
||||
await verifyAPIKey(apiKey);
|
||||
return next();
|
||||
} catch {
|
||||
return res.status(403).json({ message: "API Key invalid" }); // fix: don't chain after sendStatus
|
||||
}
|
||||
} else {
|
||||
return res.status(401).json({ message: "Unauthorized" }); // no credentials
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyAPIKey(apiKey) {
|
||||
const result = await verifyAPIKeyDB(apiKey);
|
||||
|
||||
if (result.valid) {
|
||||
return;
|
||||
} else {
|
||||
throw new Error("Invalid API Key");
|
||||
}
|
||||
}
|
||||
|
||||
async function verifyToken(token) {
|
||||
const { payload } = await jwtVerify(token, secret, {
|
||||
algorithms: ["HS256"],
|
||||
});
|
||||
return payload;
|
||||
}
|
||||
Reference in New Issue
Block a user