From 63176d1863c585d6a5d4e8d39d7547d28f2b9f69 Mon Sep 17 00:00:00 2001 From: M1000fr Date: Thu, 5 Dec 2024 12:15:28 +0100 Subject: [PATCH] feat: change Role decorator to accept multiples roles --- src/modules/auth/decorators/roles.decorator.ts | 2 +- src/modules/auth/guards/role.guard.ts | 14 ++++++++++---- src/modules/user/user.controller.ts | 12 ++++++------ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/src/modules/auth/decorators/roles.decorator.ts b/src/modules/auth/decorators/roles.decorator.ts index 5f17e66..0aeb9b1 100644 --- a/src/modules/auth/decorators/roles.decorator.ts +++ b/src/modules/auth/decorators/roles.decorator.ts @@ -1,4 +1,4 @@ import { SetMetadata } from "@nestjs/common"; import { $Enums } from "@prisma/client"; -export const Role = (role: $Enums.Role) => SetMetadata("role", role); +export const Roles = (roles: $Enums.Role[]) => SetMetadata("roles", roles); diff --git a/src/modules/auth/guards/role.guard.ts b/src/modules/auth/guards/role.guard.ts index ab25dc9..4d3d48a 100644 --- a/src/modules/auth/guards/role.guard.ts +++ b/src/modules/auth/guards/role.guard.ts @@ -12,8 +12,11 @@ export class RolesGuard implements CanActivate { constructor(private readonly reflector: Reflector) {} canActivate(context: ExecutionContext): boolean { - const role = this.reflector.get("role", context.getHandler()); - if (!role) { + const Roles = this.reflector.get( + "roles", + context.getHandler(), + ); + if (!Roles) { return true; } @@ -24,10 +27,13 @@ export class RolesGuard implements CanActivate { throw new ForbiddenException("User not authenticated"); } - const hasRole = role === user.role; + const hasRole = Roles.some((role) => user.role?.includes(role)); + if (!hasRole) { throw new UnauthorizedException( - `You need to have the role ${role} to access this resource`, + `You need to have the role ${Roles.map((role) => role).join( + " or ", + )}`, ); } diff --git a/src/modules/user/user.controller.ts b/src/modules/user/user.controller.ts index bac9350..265780b 100644 --- a/src/modules/user/user.controller.ts +++ b/src/modules/user/user.controller.ts @@ -15,7 +15,7 @@ import { ApiUnauthorizedResponse, } from "@nestjs/swagger"; -import { Role } from "@/modules/auth/decorators/roles.decorator"; +import { Roles } from "@/modules/auth/decorators/roles.decorator"; import { JwtAuthGuard } from "@/modules/auth/guards/jwt.guard"; import { RolesGuard } from "@/modules/auth/guards/role.guard"; @@ -40,7 +40,7 @@ export class UserController { constructor(private readonly userService: UserService) {} @Get("users") - @Role("ADMIN") + @Roles(["ADMIN"]) @ApiOkResponse({ type: UserEntity, isArray: true, @@ -61,7 +61,7 @@ export class UserController { } @Get("user") - @Role("ADMIN") + @Roles(["ADMIN"]) @ApiOkResponse({ type: UserEntity, description: "The user has been successfully found.", @@ -83,7 +83,7 @@ export class UserController { } @Post("user") - @Role("ADMIN") + @Roles(["ADMIN"]) @ApiOkResponse({ type: UserEntity, description: "The user has been successfully created.", @@ -114,7 +114,7 @@ export class UserController { } @Delete("user") - @Role("ADMIN") + @Roles(["ADMIN"]) @ApiOkResponse({ type: UserEntity, description: "The user has been successfully deleted.", @@ -140,7 +140,7 @@ export class UserController { } @Delete("users") - @Role("ADMIN") + @Roles(["ADMIN"]) @ApiOkResponse({ description: "The users have been successfully deleted.", examples: {