diff --git a/src/middlewares/routeRequiresAuthorization.ts b/src/middlewares/routeRequiresAuthorization.ts index 9197e85..b5c8e00 100644 --- a/src/middlewares/routeRequiresAuthorization.ts +++ b/src/middlewares/routeRequiresAuthorization.ts @@ -19,11 +19,11 @@ export function routeRequiresAuthorization( } return (req: Request, res: Response, next: NextFunction) => { - const requestRoles = authenticator.getRoles(req, res); - if (debuggerInstance.enabled) debuggerInstance('Validating authentication roles: <%j>.', requestRoles); + const rawUserRoles = authenticator.getRoles(req, res); + if (debuggerInstance.enabled) debuggerInstance('Validating authentication roles: <%j>.', rawUserRoles); - const transformedRoles = requestRoles.map(transformUserRole); - const isAuthorized = permittedRoles.some((permittedRole) => isRoleMatched(permittedRole, transformedRoles)); + const userRoles = rawUserRoles.map(Role.from); + const isAuthorized = permittedRoles.some((r) => isRoleMatched(r, userRoles)); if (!isAuthorized) { next(new Errors.ForbiddenError('You are not allowed to access this endpoint.')); return; @@ -33,20 +33,31 @@ export function routeRequiresAuthorization( }; } -function isRoleMatched(permittedRole: string, userRoles: Array): boolean { - for (const userRole of userRoles) { - const isMatch = userRole.test(permittedRole); - if (isMatch) return true; +function isRoleMatched(permittedRole: string, userRoles: Array): boolean { + return userRoles.some((userRole) => userRole.matches(permittedRole)); +} + +class Role { + private roleRegex: RegExp; + + private constructor(role: string) { + this.roleRegex = this.transformUserRole(role); } - return false; -} + public static from(role: string): Role { + return new Role(role); + } + + private transformUserRole(userRole: string): RegExp { + if (!userRole.includes('*')) return new RegExp(`^${userRole}$`); -function transformUserRole(userRole: string): RegExp { - 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}$`); + } - const regexString = userRole - .replaceAll('**', '[a-zA-Z0-9_-]+(:[a-zA-Z0-9_-]+){0,}') - .replaceAll('*', '[a-zA-Z0-9_-]+'); - return new RegExp(`^${regexString}$`); + public matches(permittedRole: string): unknown { + return this.roleRegex.test(permittedRole); + } }