@nmshd/typescript-rest
Version:
A Library to create RESTFul APIs with Typescript
44 lines • 1.99 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.routeRequiresAuthorization = routeRequiresAuthorization;
const debug = require("debug");
const Errors = require("../server/model/errors");
const debuggerInstance = debug('typescript-rest:middlewares:routeRequiresAuthorization');
function routeRequiresAuthorization(authenticator, ...permittedRoles) {
if (permittedRoles.length === 0)
throw new Error('At least one permitted role must be specified.');
const roleRegex = /^[a-zA-Z0-9_-]+(:[a-zA-Z0-9_-]+){0,}$/;
const nonMatchingRoles = permittedRoles.filter((role) => !roleRegex.test(role));
if (nonMatchingRoles.length > 0) {
throw new Error(`Invalid permitted role(s) specified: ${nonMatchingRoles.join(', ')}. Roles must match the pattern: ${roleRegex}.`);
}
return (req, res, next) => {
const requestRoles = authenticator.getRoles(req, res);
if (debuggerInstance.enabled)
debuggerInstance('Validating authentication roles: <%j>.', requestRoles);
const transformedRoles = requestRoles.map(transformUserRole);
const isAuthorized = permittedRoles.some((permittedRole) => isRoleMatched(permittedRole, transformedRoles));
if (!isAuthorized) {
next(new Errors.ForbiddenError('You are not allowed to access this endpoint.'));
return;
}
next();
};
}
function isRoleMatched(permittedRole, userRoles) {
for (const userRole of userRoles) {
const isMatch = userRole.test(permittedRole);
if (isMatch)
return true;
}
return false;
}
function transformUserRole(userRole) {
if (!userRole.includes('*'))
return new RegExp(`^${userRole}$`);
const regexString = userRole
.replaceAll('**', '[a-zA-Z0-9_-]+(:[a-zA-Z0-9_-]+){0,}')
.replaceAll('*', '[a-zA-Z0-9_-]+');
return new RegExp(`^${regexString}$`);
}
//# sourceMappingURL=routeRequiresAuthorization.js.map