@dvsa/appdev-api-common
Version:
Utils library for common API functionality
53 lines (52 loc) • 2.7 kB
JavaScript
;
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;