UNPKG

@dvsa/appdev-api-common

Version:

Utils library for common API functionality

53 lines (52 loc) 2.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JWTAuthChecker = void 0; const http_status_codes_1 = require("../api/http-status-codes"); const auth_errors_1 = require("./auth-errors"); const verify_jwt_1 = require("./verify-jwt"); // biome-ignore lint/complexity/noStaticOnlyClass: this class will be extended in the future class JWTAuthChecker { /** * Perform a JWT token verification and role check * @param {RoutingControllersRequest} request * @param {string | string[]} roles * @returns {Promise<boolean>} */ static async execute({ request }, roles = []) { // if running locally, skip the token auth and role check if (process.env.IS_OFFLINE === "true" && process.env.FORCE_LOCAL_AUTH !== "true") return true; // extract the token from the request headers const headers = request?.apiGateway.event .headers; const token = headers?.Authorization || headers?.authorization; // if no token is found, then deny access to resource if (!token || token.trim()?.length === 0) { throw new auth_errors_1.AuthError(http_status_codes_1.HttpStatus.UNAUTHORIZED, "Missing Authorization header"); } // create an instance of the JwtAuthoriser class const authoriser = new verify_jwt_1.JwtAuthoriser(); // Validate the token and extract the roles from it const { roles: tokenRoles } = await authoriser.verify(token); // check if a singular or list of roles were passed into the @Authorized decorator & remove nullish values const requiredRoles = (Array.isArray(roles) ? roles : [roles]).filter((role) => !!role); // if there are no requiredRoles, then any valid token can access the resource, so return true if (requiredRoles.length === 0) return true; // if there are no roles in JWT token but roles are required, then deny access if (!tokenRoles || !Array.isArray(tokenRoles) || tokenRoles.length === 0) { throw new auth_errors_1.AuthError(http_status_codes_1.HttpStatus.UNAUTHORIZED, "No roles found in token", "MISSING_ROLES"); } // check if one of the required roles is present in JWT token const success = requiredRoles.some((role) => tokenRoles.includes(role)); if (!success) { throw new auth_errors_1.AuthError(http_status_codes_1.HttpStatus.UNAUTHORIZED, "Insufficient permissions", "UNAUTHORIZED", { required: requiredRoles, actual: tokenRoles, }); } return true; } } exports.JWTAuthChecker = JWTAuthChecker;