mirror of
https://github.com/SyncrowIOT/backend.git
synced 2025-11-26 20:24:54 +00:00
68 lines
2.0 KiB
TypeScript
68 lines
2.0 KiB
TypeScript
import {
|
|
Injectable,
|
|
ExecutionContext,
|
|
UnauthorizedException,
|
|
} from '@nestjs/common';
|
|
import { AuthGuard } from '@nestjs/passport';
|
|
import { Reflector } from '@nestjs/core';
|
|
import { RolePermissions } from '@app/common/constants/role-permissions';
|
|
import { RoleType } from '@app/common/constants/role.type.enum';
|
|
|
|
@Injectable()
|
|
export class PermissionsGuard extends AuthGuard('jwt') {
|
|
constructor(private reflector: Reflector) {
|
|
super();
|
|
}
|
|
|
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
|
// First, run the AuthGuard logic to validate the JWT
|
|
const isAuthenticated = await super.canActivate(context);
|
|
if (!isAuthenticated) {
|
|
return false;
|
|
}
|
|
|
|
// Authorization logic
|
|
const requiredPermissions = this.reflector.get<string[]>(
|
|
'permissions',
|
|
context.getHandler(),
|
|
);
|
|
|
|
if (!requiredPermissions) {
|
|
return true; // Allow if no permissions are specified
|
|
}
|
|
|
|
const request = context.switchToHttp().getRequest();
|
|
const user = request.user; // User is now available after AuthGuard
|
|
|
|
const userRole = user?.role?.type as RoleType;
|
|
if (!userRole || !RolePermissions[userRole]) {
|
|
throw new UnauthorizedException({
|
|
message: `Only ${this.getAllowedRoles(requiredPermissions)} role(s) can access this route.`,
|
|
});
|
|
}
|
|
|
|
const userPermissions = RolePermissions[userRole];
|
|
const hasRequiredPermissions = requiredPermissions.every((perm) =>
|
|
userPermissions.includes(perm),
|
|
);
|
|
|
|
if (!hasRequiredPermissions) {
|
|
throw new UnauthorizedException({
|
|
message: `Only ${this.getAllowedRoles(requiredPermissions)} role(s) can access this route.`,
|
|
});
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
private getAllowedRoles(requiredPermissions: string[]): string {
|
|
const allowedRoles = Object.entries(RolePermissions)
|
|
.filter(([, permissions]) =>
|
|
requiredPermissions.every((perm) => permissions.includes(perm)),
|
|
)
|
|
.map(([role]) => role);
|
|
|
|
return allowedRoles.join(', ');
|
|
}
|
|
}
|