const jwt = require('jsonwebtoken'); const {getUserById} = require('./db'); const JWT_SECRET = 'THISISTOTALLYSECRETDONTLOOK'; const JWT_EXPIRATION = '24h'; /** * Generate a JWT token for a user * @param {Object}- User object from database * @returns {string} - signed JWT token */ function generateToken(user) { const payload = { id: user.id, email: user.email, username: user.username, display_name: user.display_name, auth_provider: user.auth_provider, role: user.role }; const token = jwt.sign(payload, JWT_SECRET, {expiresIn: JWT_EXPIRATION}); return token; } /** * Verify and decode a JWT token * @param {string} token - JWT token to verify * @returns {Object} - Decoded token payload * @throws {Error} - If token is invalid or expired */ function verifyToken(token) { try { const decoded = jwt.verify(token, JWT_SECRET); return decoded; } catch (error) { throw new Error('Invalid or expired token'); } } /** * Express middleware to authenticate requests using JWT * Extracts token from Authorization header, verfies it, and attaches user to req.user */ function authenticateToken(req, res, next) { const authHeader = req.headers['authorization']; const token = authHeader && authHeader.split(' ')[1]; if (!token) { return res.status(401).json({error: 'Access token required'}); } try { const decoded = verifyToken(token); const user = getUserById(decoded.id); if (!user) { return res.status(403).json({error: 'User not found'}); } req.user = { id: user.id, email: user.email, username: user.username, display_name: user.display_name, auth_provider: user.auth_provider, role: user.role }; next(); } catch (error) { return res.status(403).json({error: 'Invalid or expired token', details: error.message}); } } /** * Middleware to check if user has required role * @param {Array} allowedRoles - Array of roles that can acces the route */ function authorizeRoles(...allowedRoles) { return (req, res, next) => { if (!req.user) { return res.status(401).json({error: 'Authentication requried'}); } if (!allowedRoles.includes(req.user.role)) { return res.status(403).json({ error: 'Insufficient permissions', required: allowedRoles, current: req.user.role }); } next(); }; } module.exports = { generateToken, verifyToken, authenticateToken, authorizeRoles, JWT_SECRET };