workspace-v1/shared/catalog/auth/_reference/roles.guard.reference.ts
rckrdmrd cb4c0681d3 feat(workspace): Add new projects and update architecture
New projects created:
- michangarrito (marketplace mobile)
- template-saas (SaaS template)
- clinica-dental (dental ERP)
- clinica-veterinaria (veterinary ERP)

Architecture updates:
- Move catalog from core/ to shared/
- Add MCP servers structure and templates
- Add git management scripts
- Update SUBREPOSITORIOS.md with 15 new repos
- Update .gitignore for new projects

Repository infrastructure:
- 4 main repositories
- 11 subrepositorios
- Gitea remotes configured

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 04:43:28 -06:00

90 lines
2.4 KiB
TypeScript

/**
* ROLES GUARD - REFERENCE IMPLEMENTATION
*
* @description Guard de autorización basado en roles (RBAC).
* Verifica que el usuario tenga uno de los roles requeridos.
*
* @usage
* ```typescript
* @Get('admin')
* @UseGuards(JwtAuthGuard, RolesGuard)
* @Roles('admin', 'super_admin')
* adminOnly(@Request() req) {
* return { message: 'Admin data' };
* }
* ```
*
* @origin gamilit/apps/backend/src/modules/auth/guards/roles.guard.ts
*/
import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
/**
* Metadata key para roles requeridos
*/
export const ROLES_KEY = 'roles';
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private readonly reflector: Reflector) {}
/**
* Verificar si el usuario tiene los roles requeridos
*
* @description
* 1. Obtiene los roles requeridos del decorador @Roles()
* 2. Si no hay roles definidos, permite el acceso
* 3. Compara el rol del usuario con los roles permitidos
*/
canActivate(context: ExecutionContext): boolean {
// Obtener roles requeridos de handler y class
const requiredRoles = this.reflector.getAllAndOverride<string[]>(ROLES_KEY, [
context.getHandler(),
context.getClass(),
]);
// Si no hay roles definidos, permitir acceso
if (!requiredRoles || requiredRoles.length === 0) {
return true;
}
// Obtener usuario del request (inyectado por JwtAuthGuard)
const { user } = context.switchToHttp().getRequest();
if (!user || !user.role) {
throw new ForbiddenException('Usuario sin rol asignado');
}
// Verificar si el usuario tiene alguno de los roles requeridos
const hasRole = requiredRoles.includes(user.role);
if (!hasRole) {
throw new ForbiddenException(
`Acceso denegado. Roles requeridos: ${requiredRoles.join(', ')}`,
);
}
return true;
}
}
// ============ DECORADOR ROLES ============
import { SetMetadata } from '@nestjs/common';
/**
* Decorador para definir roles requeridos en una ruta
*
* @param roles - Lista de roles que pueden acceder
*
* @usage
* ```typescript
* @Roles('admin', 'teacher')
* @UseGuards(JwtAuthGuard, RolesGuard)
* @Get('teachers')
* getTeacherData() { ... }
* ```
*/
export const Roles = (...roles: string[]) => SetMetadata(ROLES_KEY, roles);