62 lines
1.9 KiB
TypeScript
62 lines
1.9 KiB
TypeScript
import {
|
|
CanActivate,
|
|
ExecutionContext,
|
|
ForbiddenException,
|
|
Injectable,
|
|
} from '@nestjs/common';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { ROLES_KEY } from '../decorators/roles.decorators';
|
|
import { Roles } from '.prisma/client';
|
|
|
|
|
|
|
|
interface RequestWithUser extends Request {
|
|
// TODO: Create an actual user model based on OAuth signin
|
|
user: any;
|
|
}
|
|
|
|
@Injectable()
|
|
export class RolesGuard implements CanActivate {
|
|
constructor(private reflector: Reflector) { }
|
|
|
|
/**
|
|
* @swagger
|
|
* @function canActivate
|
|
* @description
|
|
* Authorization guard that checks whether the current user has one of the required roles
|
|
* to access a specific route handler. It uses metadata defined by the `@Roles()` decorator
|
|
* and verifies the user's role accordingly.
|
|
*
|
|
* If no roles are specified for the route, access is granted by default.
|
|
* If the user is not authenticated or does not have a required role, access is denied.
|
|
*
|
|
* @param {ExecutionContext} ctx - The current execution context, which provides access
|
|
* to route metadata and the HTTP request.
|
|
*
|
|
* @returns {boolean} - Returns `true` if access is allowed, otherwise throws a `ForbiddenException`
|
|
* or returns `false` if the user is not authenticated.
|
|
*/
|
|
canActivate(ctx: ExecutionContext): boolean {
|
|
const requiredRoles = this.reflector.getAllAndOverride<Roles[]>(
|
|
ROLES_KEY,
|
|
[ctx.getHandler(), ctx.getClass()],
|
|
);
|
|
//for "deny-by-default" when role is wrong or unavailable
|
|
if (!requiredRoles || requiredRoles.length === 0) {
|
|
return true;
|
|
}
|
|
const request = ctx.switchToHttp().getRequest<RequestWithUser>();
|
|
const user = request.user;
|
|
|
|
if (!user) {
|
|
return false;
|
|
}
|
|
if (!requiredRoles.includes(user.role)) {
|
|
throw new ForbiddenException(
|
|
`The role ${user.role} is not authorized to access this resource.`,
|
|
);
|
|
}
|
|
return true;
|
|
}
|
|
}
|