import jwt from 'jsonwebtoken'; import { env } from '../config/env.js'; import { pool } from '../config/db.js'; import { fail } from '../utils/http.js'; import { loadModules } from './modules.js'; import { validateSession } from '../modules/auth/sessions-service.js'; export async function requireAuth(req, res, next) { const header = req.headers.authorization || ''; const token = header.startsWith('Bearer ') ? header.slice(7) : null; if (!token) return fail(res, 401, 'No autenticado'); let payload; try { payload = jwt.verify(token, env.jwtSecret); } catch { return fail(res, 401, 'Token invalido o expirado'); } // Revalidar en cada request que la cuenta siga activa (un JWT firmado no basta). const [rows] = await pool.query( `SELECT u.id, u.name, u.email, u.is_active, u.session_version, u.department_id, d.name AS department_name, r.code AS role_code, r.name AS role_name FROM users u JOIN roles r ON r.id = u.role_id LEFT JOIN departments d ON d.id = u.department_id WHERE u.id = ? LIMIT 1`, [payload.sub] ); const user = rows[0]; if (!user || !user.is_active || payload.sv !== user.session_version) return fail(res, 401, 'Sesion invalida o revocada', 'SESSION_REVOKED'); // Token emitido antes de las sesiones registradas (sin sid): se trata como vencido, no como cerrado. if (!payload.sid) return fail(res, 401, 'Sesion vencida'); const session = await validateSession(payload.sid, user.id); if (!session) return fail(res, 401, 'Sesion cerrada o vencida', 'SESSION_REVOKED'); req.currentUser = { id: user.id, name: user.name, email: user.email, roleCode: user.role_code, roleName: user.role_name, departmentId: user.department_id, departmentName: user.department_name, modules: await loadModules(user.id, user.role_code), sessionId: session.id, sessionPublicId: payload.sid, }; next(); } export function requireRole(...roleCodes) { return (req, res, next) => { if (!req.currentUser) return fail(res, 401, 'No autenticado'); if (!roleCodes.includes(req.currentUser.roleCode)) { return fail(res, 403, 'No tienes permisos para esta accion'); } next(); }; } export const ROLES = { SUPERADMIN: 'superadmin', ADMIN: 'admin', IT_MANAGER: 'it_manager', PROJECT_LEAD: 'project_lead', COLLABORATOR: 'collaborator', VIEWER: 'viewer', }; export const CAN_MANAGE_CATALOGS = [ROLES.SUPERADMIN]; export const CAN_MANAGE_USERS = [ROLES.SUPERADMIN, ROLES.ADMIN]; export const CAN_MANAGE_SMTP = [ROLES.SUPERADMIN]; export const CAN_MANAGE_SETTINGS = [ROLES.SUPERADMIN]; export const CAN_WRITE = [ROLES.SUPERADMIN, ROLES.ADMIN, ROLES.IT_MANAGER, ROLES.PROJECT_LEAD, ROLES.COLLABORATOR]; export const CAN_EDIT_DEVICES = [ROLES.SUPERADMIN, ROLES.ADMIN, ROLES.IT_MANAGER]; export const CAN_MANAGE_DEVICES = [ROLES.SUPERADMIN, ROLES.ADMIN];