API: - AuthModule: register, login, refresh, logout, MFA/TOTP setup+verify - JwtStrategy + JwtAuthGuard + RolesGuard + CurrentUser decorator - PackagesModule: CRUD paquetes + historial de estados - PreAlertsModule: pre-alertas por usuario - UsersModule: gestión de usuarios + roles + activación - B2BModule: solicitudes de carga pesada/cotización - ValidationPipe global + CORS configurado Web (Next.js 15): - globals.css completo (design system + utility classes) - Layout raíz con WhatsApp flotante - /login + /registro funcionales con JWT y redirección por rol - /portal: dashboard, mi-casillero, mis-paquetes, pre-alerta, calculadora, perfil - /admin: dashboard, usuarios (gestión roles/activación), tarifas, reportes, auditoría - /bodega: dashboard, paquetes (crear+actualizar estado), verificación, despacho - /tracking: tracking real con progreso visual + historial - /calculadora: calculadora interactiva real (API SENAE §15) - /como-funciona, /tarifas, /quienes-somos, /casillero - /carga-pesada + /carga-pesada/cotizacion (formulario B2B) - lib/api.ts: cliente HTTP con auto-refresh de token Roles sincronizados con schema: SUPER_ADMIN, ADMIN_EMPRESA, OPERADOR_BODEGA, AGENTE_ADUANERO, CLIENTE, SOPORTE
23 lines
973 B
TypeScript
23 lines
973 B
TypeScript
import { Injectable, UnauthorizedException } from "@nestjs/common";
|
|
import { PassportStrategy } from "@nestjs/passport";
|
|
import { ExtractJwt, Strategy } from "passport-jwt";
|
|
import { ConfigService } from "@nestjs/config";
|
|
import { PrismaService } from "../prisma/prisma.service";
|
|
|
|
@Injectable()
|
|
export class JwtStrategy extends PassportStrategy(Strategy) {
|
|
constructor(config: ConfigService, private prisma: PrismaService) {
|
|
super({
|
|
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
|
|
ignoreExpiration: false,
|
|
secretOrKey: config.get<string>("JWT_SECRET", "change-me"),
|
|
});
|
|
}
|
|
|
|
async validate(payload: { sub: string; email: string; role: string; tenantId: string }): Promise<any> {
|
|
const user = await this.prisma.client.user.findUnique({ where: { id: payload.sub } });
|
|
if (!user || !user.isActive) throw new UnauthorizedException();
|
|
return { id: user.id, email: user.email, role: user.role, tenantId: user.tenantId };
|
|
}
|
|
}
|