Overview

Enforce role requirements on routes. Works with @Roles() decorator.

Features

  • OR logic (any role)
  • AND logic (all roles)
  • Custom error messages
  • Reflector integration

Installation

npx hanma add roles-guard --framework nest

Code

import {
  Injectable,
  CanActivate,
  ExecutionContext,
  ForbiddenException,
} from "@nestjs/common";
import { Reflector } from "@nestjs/core";
import { ROLES_KEY, ROLES_ALL_KEY, Role } from "../decorators/roles.decorator";

@Injectable()
export class RolesGuard implements CanActivate {
  constructor(private reflector: Reflector) {}

  canActivate(context: ExecutionContext): boolean {
    // Get required roles from decorator
    const requiredRoles = this.reflector.getAllAndOverride<Role[]>(ROLES_KEY, [
      context.getHandler(),
      context.getClass(),
    ]);

    const requiredAllRoles = this.reflector.getAllAndOverride<Role[]>(
      ROLES_ALL_KEY,
      [context.getHandler(), context.getClass()]
    );

    // No roles required - allow access
    if (!requiredRoles?.length && !requiredAllRoles?.length) {
      return true;
    }

    const request = context.switchToHttp().getRequest();
    const user = request.user;

    if (!user) {
      throw new ForbiddenException("No user found in request");
    }

    const userRoles: Role[] = user.roles || [];

    // Check if user has any of the required roles (OR logic)
    if (requiredRoles?.length) {
      const hasRole = requiredRoles.some((role) => userRoles.includes(role));
      if (!hasRole) {
        throw new ForbiddenException(
          `Requires one of these roles: ${requiredRoles.join(", ")}`
        );
      }
    }

    // Check if user has all required roles (AND logic)
    if (requiredAllRoles?.length) {
      const hasAllRoles = requiredAllRoles.every((role) =>
        userRoles.includes(role)
      );
      if (!hasAllRoles) {
        throw new ForbiddenException(
          `Requires all of these roles: ${requiredAllRoles.join(", ")}`
        );
      }
    }

    return true;
  }
}

Usage

@Roles(Role.ADMIN)
@UseGuards(JwtAuthGuard, RolesGuard)
@Get('admin')
adminRoute() {}

Dependencies

No external dependencies required.

Frequently Asked Questions

How do I install Roles Guard?
Run the following command: npx hanma add roles-guard --framework nest
How do I use this snippet?
Copy the code and paste it into your project. The snippet will be saved to src/guards/roles.guard.ts.
Can I customize this snippet?
Yes! All snippets are copy-paste code that you own. Feel free to modify them to fit your needs.
Does this work with other frameworks?
This snippet is designed for the specific framework. Check the other framework pages for equivalent implementations.