import crypto from 'crypto'; import { getDB, getSession, deleteSession as deleteSessionFromDB, deleteUserSessions as deleteUserSessionsFromDB, getUser } from '../services/mongodb.js'; // Duración de la sesión en milisegundos (24 horas) const SESSION_DURATION = 24 * 60 * 60 * 1000; // Generar token seguro function generateToken() { return crypto.randomBytes(32).toString('hex'); } // Autenticación por token Middleware export async function authMiddleware(req, res, next) { const db = getDB(); if (!db) { return res.status(500).json({ error: 'MongoDB no está disponible. La autenticación requiere MongoDB.' }); } const authHeader = req.headers.authorization; if (!authHeader) { return res.status(401).json({ error: 'Authentication required', message: 'Se requiere autenticación para esta operación' }); } const [scheme, token] = authHeader.split(' '); if (scheme !== 'Bearer' || !token) { return res.status(400).json({ error: 'Bad request', message: 'Se requiere un token Bearer' }); } try { // Verificar token en MongoDB const session = await getSession(token); if (!session) { return res.status(401).json({ error: 'Invalid token', message: 'Token inválido o sesión expirada' }); } // Verificar que la sesión no haya expirado if (session.expiresAt && new Date(session.expiresAt) < new Date()) { await deleteSessionFromDB(token); return res.status(401).json({ error: 'Invalid token', message: 'Sesión expirada' }); } // Verificar que el usuario aún existe const user = await getUser(session.username); if (!user) { // Eliminar sesión si el usuario ya no existe await deleteSessionFromDB(token); return res.status(401).json({ error: 'Invalid token', message: 'Usuario no encontrado' }); } // Actualizar expiración de la sesión (refresh) const sessionsCollection = db.collection('sessions'); const newExpiresAt = new Date(Date.now() + SESSION_DURATION); await sessionsCollection.updateOne( { token }, { $set: { expiresAt: newExpiresAt } } ); // Autenticación exitosa - incluir rol en req.user req.user = { username: session.username, role: user.role || 'user' // Por defecto 'user' si no tiene rol }; req.token = token; next(); } catch (error) { console.error('Error en autenticación:', error); res.status(500).json({ error: 'Internal server error', message: 'Error procesando autenticación' }); } } // Alias para mantener compatibilidad export const basicAuthMiddleware = authMiddleware; // Función para crear sesión export async function createSession(username, fingerprint = null, deviceInfo = null) { const { createSession: createSessionInDB } = await import('../services/mongodb.js'); return await createSessionInDB(username, fingerprint, deviceInfo); } // Función para invalidar sesión export async function invalidateSession(token) { try { return await deleteSessionFromDB(token); } catch (error) { console.error('Error invalidando sesión:', error); return false; } } // Función para invalidar todas las sesiones de un usuario export async function invalidateUserSessions(username) { try { return await deleteUserSessionsFromDB(username); } catch (error) { console.error('Error invalidando sesiones del usuario:', error); return 0; } }