Skip to main content

Guards

Ubicados en src/app/core/guards/.

AuthGuard — auth.guard.ts​

Protege rutas que requieren sesión de usuario activa.

Cómo funciona:

  1. Extrae el token del header x-api-key
  2. Verifica y decodifica el JWT con JwtService
  3. Consulta el usuario en BD mediante UserService
  4. Valida que user.isActive === true y que el tenant del usuario esté operativo
  5. Inyecta el usuario en request.user

Uso:

@UseGuards(AuthGuard)
// o con el decorador abreviado:
@Auth()

Errores que lanza:

  • 401 Unauthorized — header x-api-key ausente, token inválido o expirado, usuario no encontrado, usuario inactivo o tenant no operativo

ApiKeyGuard — api-key.guard.ts​

Protege endpoints destinados a clientes externos (integraciones de terceros).

Cómo funciona:

  1. Extrae apiKey del body y lo elimina de request.body (el resto del body sigue disponible)
  2. Calcula el hash de la key (hashApiKey) y la busca por ese código (ApiKeyService.findByCode)
  3. Valida que isActive sea true y que dateExpiration no haya pasado
  4. Busca el tenant de la key (TenantService.findByMongoId) y valida que exista y que isActive sea true
  5. Si tenant.domainWhitelist no está vacío, toma el dominio del header Origin (o, si falta, de Referer) y exige que termine con alguno de los dominios de la lista; si la lista está vacía, no se valida el dominio
  6. Adjunta request.tenant y request.apiKey

Uso:

@UseGuards(ApiKeyGuard)
// o:
@ApiKeyAuth()

Errores que lanza:

  • 401 Unauthorized — Missing apiKey in body, Invalid API key, API key is inactive, API key has expired, Tenant not found o Tenant is inactive
  • 403 Forbidden — Domain not allowed: la whitelist del tenant tiene dominios y el origen falta o no coincide

:::note Comparación de dominio La coincidencia usa origin.endsWith(dominio) sobre el hostname, no una igualdad exacta: un dominio de la lista como example.com también admite miexample.com. :::


Diferencia entre los dos guards​

AuthGuardApiKeyGuard
Usado porUsuarios internos (agentes)Clientes externos / integraciones
CredencialJWT en header x-api-keyAPI Key en body
Validación extrauser.isActive y tenant operativoEstado de la key, expiración, tenant activo y whitelist de dominios (si existe)

PermissionsGuard — permissions.guard.ts​

Autoriza el acceso según el permiso declarado con @RequirePermission. Es el guard de autorización fina del CRM: el AuthGuard solo dice quién es el usuario; este decide qué puede hacer.

Cómo funciona:

  1. Lee el acrónimo requerido con Reflector.getAllAndOverride sobre el handler y la clase (el del handler tiene prioridad).
  2. Si no hay @RequirePermission, deja pasar (true): una ruta sin el decorador solo exige lo que apliquen los demás guards.
  3. Toma request.user y exige que tenga tenantId y roleId; si falta alguno lanza 403.
  4. Llama a PermissionResolverService.resolve(tenantId, roleId), que devuelve el conjunto de acrónimos del rol (con caché de 10 segundos; ver RBAC).
  5. Si el conjunto no contiene el acrónimo requerido, lanza 403.

Uso:

@UseGuards(PermissionsGuard)
@Auth()
@Controller(...)
export class UserController {
@RequirePermission('USER_READ')
@Get('get-all')
findAll() { ... }
}

Errores que lanza:

  • 403 Forbidden (Forbidden resource) — el usuario no tiene tenantId o roleId, o su rol no incluye el permiso

:::note Orden de guards PermissionsGuard depende de request.user, que solo establece AuthGuard. Por eso los controladores combinan @UseGuards(PermissionsGuard) con @Auth(). Si no hay usuario, el resultado sería 403 y no 401. :::

El guard y el resolvedor se exportan desde CorePermissionsModule (src/app/core/permissions/), que cada módulo con rutas protegidas debe importar.


RolesGuard — roles.guard.ts​

Compara request.user.userType con la lista de @Roles. Sin @Roles (o con lista vacía) permite el paso; si el usuario no tiene userType o no está en la lista, lanza 403.


PlatformAdminGuard — platform-admin.guard.ts​

Permite el acceso solo si request.user.isPlatformAdmin === true; en otro caso lanza 403. Se aplica con @PlatformAdmin(), que lo combina con AuthGuard.