iamolegga/nestjs-roles

View on GitHub
src/index.ts

Summary

Maintainability
A
0 mins
Test Coverage
A
100%
import { CanActivate, ExecutionContext, SetMetadata } from '@nestjs/common';
import { Reflector } from '@nestjs/core';

import { checkRoles } from './check-roles';
import { roleReflectionToken } from './role-reflection-token';
import { RolesGuardStatic } from './roles-guard-static';

export function createRolesGuard<R>(
  getRole: (
    context: ExecutionContext,
  ) => R | R[] | undefined | Promise<R | R[] | undefined>,
): RolesGuardStatic<R> {
  return class RolesGuard implements CanActivate {
    static readonly Params = (...allowedRoles: [R, ...R[]] | [boolean]) =>
      SetMetadata(roleReflectionToken, allowedRoles);

    constructor(private readonly reflector: Reflector) {}

    async canActivate(context: ExecutionContext) {
      const requiredRoles = this.reflector.getAllAndOverride<
        [R, ...R[]] | [boolean] | undefined
      >(roleReflectionToken, [context.getHandler(), context.getClass()]);

      // roles are not set - handler is allowed for all
      if (!requiredRoles) {
        return true;
      }

      const role = await getRole(context);

      return checkRoles(requiredRoles, role);
    }
  };
}