const jwt = require('jsonwebtoken'); const db = require('../models'); const logger = require('../utils/logger'); const authenticate = async (req, res, next) => { try { // Get token from header const authHeader = req.header('Authorization'); if (!authHeader || !authHeader.startsWith('Bearer ')) { return res.status(401).json({ success: false, message: 'Access denied. No token provided.' }); } const token = authHeader.replace('Bearer ', ''); // Verify token const decoded = jwt.verify(token, process.env.JWT_SECRET); // Find user const user = await db.User.findByPk(decoded.id, { attributes: { exclude: ['password'] } }); if (!user) { return res.status(401).json({ success: false, message: 'Invalid token. User not found.' }); } if (user.status !== 'active') { return res.status(401).json({ success: false, message: 'User account is inactive.' }); } // Attach user to request req.user = user; req.token = token; next(); } catch (error) { logger.error('Authentication error:', error); if (error.name === 'TokenExpiredError') { return res.status(401).json({ success: false, message: 'Token expired' }); } if (error.name === 'JsonWebTokenError') { return res.status(401).json({ success: false, message: 'Invalid token' }); } res.status(500).json({ success: false, message: 'Authentication failed' }); } }; const optionalAuth = async (req, res, next) => { try { const authHeader = req.header('Authorization'); if (!authHeader || !authHeader.startsWith('Bearer ')) { return next(); } const token = authHeader.replace('Bearer ', ''); const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await db.User.findByPk(decoded.id, { attributes: { exclude: ['password'] } }); if (user && user.status === 'active') { req.user = user; req.token = token; } next(); } catch (error) { // If token is invalid/expired, just proceed without user next(); } }; module.exports = { authenticate, optionalAuth };