const jwt = require('jsonwebtoken'); const axios = require('axios'); // JWT token verification middleware const verifyToken = async (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1]; if (!token) { return res.status(401).json({ success: false, message: 'Access token required', error: 'No token provided' }); } // Verify JWT token const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; // Add user context to headers for downstream services req.headers['x-user-id'] = decoded.id || decoded.userId; req.headers['x-user-email'] = decoded.email; req.headers['x-user-role'] = decoded.role || 'user'; next(); } catch (error) { console.error('Token verification failed:', error.message); if (error.name === 'TokenExpiredError') { return res.status(401).json({ success: false, message: 'Token expired', error: 'Please login again' }); } if (error.name === 'JsonWebTokenError') { return res.status(401).json({ success: false, message: 'Invalid token', error: 'Token verification failed' }); } return res.status(401).json({ success: false, message: 'Authentication failed', error: error.message }); } }; // Forward user context to downstream services const forwardUserContext = (req, res, next) => { if (req.user) { // Add gateway headers for service identification req.headers['x-gateway-request-id'] = req.requestId; req.headers['x-gateway-timestamp'] = new Date().toISOString(); req.headers['x-forwarded-by'] = 'api-gateway'; req.headers['x-forwarded-for'] = req.ip; req.headers['x-forwarded-proto'] = req.protocol; req.headers['x-forwarded-host'] = req.get('host'); } next(); }; // Optional token verification (doesn't fail if no token) const verifyTokenOptional = async (req, res, next) => { try { const token = req.headers.authorization?.split(' ')[1]; if (token) { const decoded = jwt.verify(token, process.env.JWT_SECRET); req.user = decoded; // Add user context to headers req.headers['x-user-id'] = decoded.id || decoded.userId; req.headers['x-user-email'] = decoded.email; req.headers['x-user-role'] = decoded.role || 'user'; } next(); } catch (error) { // Continue without authentication for optional routes console.log('Optional token verification failed:', error.message); next(); } }; // Role-based authorization middleware const requireRole = (roles) => { return (req, res, next) => { if (!req.user) { return res.status(401).json({ success: false, message: 'Authentication required' }); } const userRole = req.user.role || 'user'; const allowedRoles = Array.isArray(roles) ? roles : [roles]; if (!allowedRoles.includes(userRole)) { return res.status(403).json({ success: false, message: 'Insufficient permissions', required_roles: allowedRoles, user_role: userRole }); } next(); }; }; module.exports = { verifyToken, forwardUserContext, verifyTokenOptional, requireRole };