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>
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
/**
|
|
* JWT AUTH GUARD - REFERENCE IMPLEMENTATION
|
|
*
|
|
* @description Guard de autenticación JWT para proteger rutas.
|
|
* Activa la estrategia JWT y maneja errores de autenticación.
|
|
*
|
|
* @usage
|
|
* ```typescript
|
|
* @Get('protected')
|
|
* @UseGuards(JwtAuthGuard)
|
|
* getProtectedData(@Request() req) {
|
|
* return req.user;
|
|
* }
|
|
* ```
|
|
*
|
|
* @origin gamilit/apps/backend/src/modules/auth/guards/jwt-auth.guard.ts
|
|
*/
|
|
|
|
import { Injectable, ExecutionContext, UnauthorizedException } from '@nestjs/common';
|
|
import { AuthGuard } from '@nestjs/passport';
|
|
import { Reflector } from '@nestjs/core';
|
|
|
|
/**
|
|
* Metadata key para rutas públicas
|
|
*/
|
|
export const IS_PUBLIC_KEY = 'isPublic';
|
|
|
|
@Injectable()
|
|
export class JwtAuthGuard extends AuthGuard('jwt') {
|
|
constructor(private readonly reflector: Reflector) {
|
|
super();
|
|
}
|
|
|
|
/**
|
|
* Determinar si la ruta requiere autenticación
|
|
*
|
|
* @description Verifica el decorador @Public() antes de activar el guard.
|
|
* Si la ruta es pública, permite el acceso sin token.
|
|
*/
|
|
canActivate(context: ExecutionContext) {
|
|
// Verificar si la ruta tiene @Public()
|
|
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
|
context.getHandler(),
|
|
context.getClass(),
|
|
]);
|
|
|
|
if (isPublic) {
|
|
return true;
|
|
}
|
|
|
|
// Activar validación JWT normal
|
|
return super.canActivate(context);
|
|
}
|
|
|
|
/**
|
|
* Manejar resultado de autenticación
|
|
*
|
|
* @description Personaliza el mensaje de error cuando falla la autenticación.
|
|
*/
|
|
handleRequest(err: Error | null, user: any, info: Error | null) {
|
|
if (err || !user) {
|
|
if (info?.message === 'jwt expired') {
|
|
throw new UnauthorizedException('Token expirado');
|
|
}
|
|
if (info?.message === 'No auth token') {
|
|
throw new UnauthorizedException('Token no proporcionado');
|
|
}
|
|
throw new UnauthorizedException('No autorizado');
|
|
}
|
|
return user;
|
|
}
|
|
}
|
|
|
|
// ============ DECORADOR PUBLIC ============
|
|
|
|
import { SetMetadata } from '@nestjs/common';
|
|
|
|
/**
|
|
* Decorador para marcar rutas como públicas
|
|
*
|
|
* @usage
|
|
* ```typescript
|
|
* @Public()
|
|
* @Get('health')
|
|
* healthCheck() {
|
|
* return { status: 'ok' };
|
|
* }
|
|
* ```
|
|
*/
|
|
export const Public = () => SetMetadata(IS_PUBLIC_KEY, true);
|