49 lines
1.6 KiB
TypeScript
49 lines
1.6 KiB
TypeScript
// roles.guard.ts
|
|
import {
|
|
CanActivate,
|
|
ExecutionContext,
|
|
Injectable,
|
|
ForbiddenException,
|
|
} from '@nestjs/common';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { ROLES_KEY } from '../decorators/roles.decorator';
|
|
import * as jwt from 'jsonwebtoken';
|
|
import { UnauthorizedException } from 'src/exceptions/unauthorized.exception';
|
|
|
|
@Injectable()
|
|
export class RolesGuard implements CanActivate {
|
|
constructor(private reflector: Reflector) { }
|
|
|
|
canActivate(context: ExecutionContext): boolean {
|
|
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
|
|
context.getHandler(),
|
|
context.getClass(),
|
|
]);
|
|
if (!requiredRoles || requiredRoles.length === 0) return true;
|
|
|
|
const request = context.switchToHttp().getRequest();
|
|
const token = request.cookies?.access_token; // Token is stored as HttpOnly cookie
|
|
|
|
if (!token) {
|
|
throw new UnauthorizedException('Authentication Failed');
|
|
}
|
|
|
|
try {
|
|
const decoded: any = jwt.decode(token);
|
|
|
|
const roles: string[] = decoded?.resource_access?.['carnet-app']?.roles || [];
|
|
const hasRole = requiredRoles.some(role => roles.includes(role));
|
|
|
|
if (!hasRole) {
|
|
throw new ForbiddenException('Unauthorized : Please Request Access for this Resource');
|
|
}
|
|
|
|
return true;
|
|
} catch (err: any) {
|
|
console.log("from roles guard : ", err.message);
|
|
|
|
throw new UnauthorizedException('Authentication Failed');
|
|
}
|
|
}
|
|
}
|