/*********************************************************************************************************************************************************************** * File Name: auth.middleware.js * Type of Program: Middleware * Description: JWT authentication guard. * Reads the Bearer token from the Authorization header, * verifies it, attaches decoded payload to req.user, * and verifies the session is still active in the DB. * Author: rgrgogu * Date Created: Oct. 6, 2025 *********************************************************************************************************************************************************************** * HOW TO USE: * const { authenticate } = require('../middleware/auth.middleware'); * router.get('/profile', authenticate, handler); ***********************************************************************************************************************************************************************/ const { verifyAccessToken } = require('../utils/token.util'); const mdl_Users = require('../models/users/users.mdl'); const R = require('../utils/response.util'); /** * Validates JWT and loads user from DB. * Attaches the full user record to req.user. */ const authenticate = async (req, res, next) => { try { const authHeader = req.headers.authorization; if (!authHeader?.startsWith('Bearer ')) return R.error(res, 'No token provided.', 401); const token = authHeader.split(' ')[1]; const decoded = verifyAccessToken(token); const user = await mdl_Users.findByPk(decoded.user_id, { attributes: { exclude: ['password', 'otp_code', 'otp_expires_at'] }, }); if (!user) return R.error(res, 'User not found.', 401); if (!user.is_active) return R.error(res, 'Account is deactivated.', 403); req.user = user; next(); } catch (err) { if (err.name === 'TokenExpiredError') return R.error(res, 'Token expired. Please log in again.', 401); return R.error(res, 'Invalid token.', 401); } }; module.exports = { authenticate };