import jwt from 'jsonwebtoken'; function getSecret() { const s = process.env.JWT_SECRET; if (!s) throw new Error('JWT_SECRET is not set'); return s; } export function signToken(user) { return jwt.sign( { sub: user.id, email: user.email }, getSecret(), { expiresIn: process.env.JWT_EXPIRES_IN || '7d' }, ); } export function verifyToken(token) { return jwt.verify(token, getSecret()); } /** Express middleware: requires Authorization: Bearer */ export function requireAuth(req, res, next) { const header = req.headers.authorization || ''; const [scheme, token] = header.split(' '); if (scheme !== 'Bearer' || !token) { return res.status(401).json({ error: 'Missing bearer token' }); } try { const payload = verifyToken(token); req.user = { id: payload.sub, email: payload.email }; return next(); } catch { return res.status(401).json({ error: 'Invalid or expired token' }); } }