UNPKG

@nmshd/typescript-rest

Version:

A Library to create RESTFul APIs with Typescript

44 lines 1.99 kB
"use strict"; 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