146 lines
4.5 KiB
JavaScript
146 lines
4.5 KiB
JavaScript
"use strict";
|
|
/**
|
|
* Auth Middleware - Middleware de Autenticación
|
|
*
|
|
* Middleware para Express que valida JWT y extrae información del usuario.
|
|
* Configura el tenant_id para RLS en PostgreSQL.
|
|
*
|
|
* @module Auth
|
|
*/
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.AuthMiddleware = void 0;
|
|
exports.createAuthMiddleware = createAuthMiddleware;
|
|
class AuthMiddleware {
|
|
authService;
|
|
dataSource;
|
|
constructor(authService, dataSource) {
|
|
this.authService = authService;
|
|
this.dataSource = dataSource;
|
|
}
|
|
/**
|
|
* Middleware de autenticación requerida
|
|
*/
|
|
authenticate = async (req, res, next) => {
|
|
try {
|
|
const token = this.extractToken(req);
|
|
if (!token) {
|
|
res.status(401).json({
|
|
error: 'Unauthorized',
|
|
message: 'No token provided',
|
|
});
|
|
return;
|
|
}
|
|
const validation = this.authService.validateAccessToken(token);
|
|
if (!validation.valid || !validation.payload) {
|
|
res.status(401).json({
|
|
error: 'Unauthorized',
|
|
message: validation.error || 'Invalid token',
|
|
});
|
|
return;
|
|
}
|
|
// Establecer información en el request
|
|
req.user = validation.payload;
|
|
req.tenantId = validation.payload.tenantId;
|
|
// Configurar tenant_id para RLS en PostgreSQL
|
|
await this.setTenantContext(validation.payload.tenantId);
|
|
next();
|
|
}
|
|
catch (error) {
|
|
res.status(401).json({
|
|
error: 'Unauthorized',
|
|
message: 'Authentication failed',
|
|
});
|
|
}
|
|
};
|
|
/**
|
|
* Middleware de autenticación opcional
|
|
*/
|
|
optionalAuthenticate = async (req, _res, next) => {
|
|
try {
|
|
const token = this.extractToken(req);
|
|
if (token) {
|
|
const validation = this.authService.validateAccessToken(token);
|
|
if (validation.valid && validation.payload) {
|
|
req.user = validation.payload;
|
|
req.tenantId = validation.payload.tenantId;
|
|
await this.setTenantContext(validation.payload.tenantId);
|
|
}
|
|
}
|
|
next();
|
|
}
|
|
catch {
|
|
// Si hay error, continuar sin autenticación
|
|
next();
|
|
}
|
|
};
|
|
/**
|
|
* Middleware de autorización por roles
|
|
*/
|
|
authorize = (...allowedRoles) => {
|
|
return (req, res, next) => {
|
|
if (!req.user) {
|
|
res.status(401).json({
|
|
error: 'Unauthorized',
|
|
message: 'Authentication required',
|
|
});
|
|
return;
|
|
}
|
|
const hasRole = req.user.roles.some((role) => allowedRoles.includes(role));
|
|
if (!hasRole) {
|
|
res.status(403).json({
|
|
error: 'Forbidden',
|
|
message: 'Insufficient permissions',
|
|
});
|
|
return;
|
|
}
|
|
next();
|
|
};
|
|
};
|
|
/**
|
|
* Middleware que requiere rol de admin
|
|
*/
|
|
requireAdmin = (req, res, next) => {
|
|
return this.authorize('admin', 'super_admin')(req, res, next);
|
|
};
|
|
/**
|
|
* Middleware que requiere ser supervisor
|
|
*/
|
|
requireSupervisor = (req, res, next) => {
|
|
return this.authorize('admin', 'super_admin', 'supervisor_obra', 'supervisor_hse')(req, res, next);
|
|
};
|
|
/**
|
|
* Extraer token del header Authorization
|
|
*/
|
|
extractToken(req) {
|
|
const authHeader = req.headers.authorization;
|
|
if (!authHeader) {
|
|
return null;
|
|
}
|
|
// Bearer token
|
|
const [type, token] = authHeader.split(' ');
|
|
if (type !== 'Bearer' || !token) {
|
|
return null;
|
|
}
|
|
return token;
|
|
}
|
|
/**
|
|
* Configurar contexto de tenant para RLS
|
|
*/
|
|
async setTenantContext(tenantId) {
|
|
try {
|
|
await this.dataSource.query(`SET app.current_tenant_id = '${tenantId}'`);
|
|
}
|
|
catch (error) {
|
|
console.error('Error setting tenant context:', error);
|
|
throw new Error('Failed to set tenant context');
|
|
}
|
|
}
|
|
}
|
|
exports.AuthMiddleware = AuthMiddleware;
|
|
/**
|
|
* Factory para crear middleware de autenticación
|
|
*/
|
|
function createAuthMiddleware(authService, dataSource) {
|
|
return new AuthMiddleware(authService, dataSource);
|
|
}
|
|
//# sourceMappingURL=auth.middleware.js.map
|