/** * Authentication Middleware * JWT token verification and user authentication */ import jwt from 'jsonwebtoken'; import logger from '../utils/logger.js'; const JWT_SECRET = process.env.JWT_SECRET; if (!JWT_SECRET) { throw new Error('JWT_SECRET must be set in environment variables'); } /** * Verify JWT token and attach user to request * @param {Request} req - Express request * @param {Response} res - Express response * @param {Function} next - Next middleware */ export function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN if (!token) { return res.status(401).json({ error: 'Authentication required' }); } try { const user = jwt.verify(token, JWT_SECRET); req.user = user; next(); } catch (error) { return res.status(403).json({ error: 'Invalid or expired token' }); } } /** * Optional authentication - attaches user if token present * @param {Request} req - Express request * @param {Response} res - Express response * @param {Function} next - Next middleware */ export function optionalAuth(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (token) { try { const user = jwt.verify(token, JWT_SECRET); req.user = user; } catch (error) { // Token invalid, but don't fail - continue without user logger.debug('AUTH_TOKEN_INVALID', { error: error.message }); } } next(); } export default { authenticateToken, optionalAuth };