Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | 2x 2x 2x 2x 5x 6x 6x 5x 5x 3x 3x 2x 1x | import {
CanActivate,
ExecutionContext,
ForbiddenException,
Injectable,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import type { Request } from 'express';
import {
AuthenticatedUser,
IS_PUBLIC_KEY,
ROLES_KEY,
UserRole,
} from './auth.decorators';
/**
* Authorization, after authentication: routes without @Roles() accept any
* authenticated user; with it, the JWT's role must be in the list. 401 means
* "who are you?", 403 means "I know who you are - you can't do this".
*/
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
context.getHandler(),
context.getClass(),
]);
if (isPublic) return true;
const required = this.reflector.getAllAndOverride<UserRole[] | undefined>(
ROLES_KEY,
[context.getHandler(), context.getClass()],
);
if (!required || required.length === 0) return true;
const { user } = context
.switchToHttp()
.getRequest<Request & { user?: AuthenticatedUser }>();
if (!user || !required.includes(user.role)) {
throw new ForbiddenException(
`requires one of roles: ${required.join(', ')}`,
);
}
return true;
}
}
|