import * as express from "express"; import { createVerifier } from "fast-jwt"; import HttpError from "../interfaces/http-error"; import HttpStatusCode from "../interfaces/http-status"; if (!process.env.PUBLIC_KEY && !process.env.REALM_URL) { throw new Error("Require public key or realm url."); } const jwtVerify = createVerifier({ key: async () => { return `-----BEGIN PUBLIC KEY-----\n${process.env.PUBLIC_KEY}\n-----END PUBLIC KEY-----`; }, }); export async function expressAuthentication( request: express.Request, securityName: string, scopes?: string[], ) { if (process.env.AUTH_BYPASS) return { preferred_username: "bypassed" }; if (securityName !== "bearerAuth") throw new Error("Unknown authentication method."); const token = request.headers["authorization"]?.includes("Bearer ") ? request.headers["authorization"].split(" ")[1] : null; if (!token) throw new HttpError(HttpStatusCode.UNAUTHORIZED, "No token provided."); const payload = await jwtVerify(token).catch((_) => null); if (!payload) { throw new HttpError(HttpStatusCode.UNAUTHORIZED, "Invalid token provided."); } if ( scopes && scopes.length > 0 && scopes.some((v) => !payload.resource_access[payload.azp].roles.includes(v)) ) { throw new HttpError(HttpStatusCode.FORBIDDEN, "You are not allowed to perform this action."); } return payload; }