miinventario-v2/apps/backend/src/common/guards/roles.guard.ts
rckrdmrd 1a53b5c4d3 [MIINVENTARIO] feat: Initial commit - Sistema de inventario con análisis de video IA
- Backend NestJS con módulos de autenticación, inventario, créditos
- Frontend React con dashboard y componentes UI
- Base de datos PostgreSQL con migraciones
- Tests E2E configurados
- Configuración de Docker y deployment

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-13 02:25:48 -06:00

45 lines
1.4 KiB
TypeScript

import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { UserRole } from '../../modules/users/entities/user.entity';
import { ROLES_KEY } from '../decorators/roles.decorator';
// Role hierarchy - higher number = more permissions
const ROLE_HIERARCHY: Record<UserRole, number> = {
[UserRole.USER]: 0,
[UserRole.VIEWER]: 1,
[UserRole.MODERATOR]: 2,
[UserRole.ADMIN]: 3,
[UserRole.SUPER_ADMIN]: 4,
};
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<UserRole[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
const { user } = context.switchToHttp().getRequest();
if (!user || !user.role) {
throw new ForbiddenException('No tienes permisos para acceder a este recurso');
}
const userRoleLevel = ROLE_HIERARCHY[user.role as UserRole] ?? 0;
const minRequiredLevel = Math.min(...requiredRoles.map(role => ROLE_HIERARCHY[role]));
if (userRoleLevel < minRequiredLevel) {
throw new ForbiddenException('No tienes permisos suficientes para esta accion');
}
return true;
}
}