/** * Middleware di autenticazione per API REST. * Supporta tre modalità: * - x-api-key (service-to-service, INTERNAL_API_KEY) * - cookie auth_token (utenti loggati dal browser, SSO via .mebboat.it) * - Authorization: Bearer * * Il JWT viene firmato da auth.mebboat.it con JWT_SECRET e verificato localmente. * Il cookie è condiviso tra i sottodomini grazie a domain=.mebboat.it */ const jwt = require('jsonwebtoken'); const SECRET = process.env.JWT_SECRET; const INTERNAL_KEY = process.env.INTERNAL_API_KEY; function extractToken(req) { const header = req.headers.authorization; const bearer = header && header.startsWith('Bearer ') ? header.slice(7) : null; return (req.cookies && req.cookies.auth_token) || bearer || null; } function verifyToken(token) { if (!token || typeof token !== 'string' || token.length > 2048) return null; try { const p = jwt.verify(token, SECRET, { algorithms: ['HS256'] }); return { user_id: p.sub, username: p.username, session_id: p.session_id, iat: p.iat, exp: p.exp }; } catch { return null; } } /** * Accetta utente loggato (cookie/bearer) o chiamata interna (x-api-key). * Imposta req.user con i dati dell'utente, oppure req.internal = true. */ function requireAuth(req, res, next) { // 1. Service-to-service const apiKey = req.headers['x-api-key']; if (apiKey && INTERNAL_KEY && apiKey === INTERNAL_KEY) { req.internal = true; return next(); } // 2. User auth (cookie o Bearer) const user = verifyToken(extractToken(req)); if (!user) return res.status(401).json({ error: 'unauthorized' }); req.user = user; next(); } /** * Solo service-to-service (x-api-key). */ function requireInternal(req, res, next) { const apiKey = req.headers['x-api-key']; if (!INTERNAL_KEY || !apiKey || apiKey !== INTERNAL_KEY) { return res.status(403).json({ error: 'forbidden' }); } req.internal = true; next(); } module.exports = { requireAuth, requireInternal, verifyToken, extractToken };