All files / services/shared jwtAuth.js

59.01% Statements 36/61
40% Branches 2/5
33.33% Functions 1/3
59.01% Lines 36/61

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 621x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x     1x 1x 1x 1x 1x 1x 1x 1x 1x 1x           1x 1x 1x 1x 1x             1x 1x 1x 1x 1x                         1x 1x  
const jwt = require('jsonwebtoken');
 
const JWT_SECRET = process.env.JWT_SECRET;
 
/**
 * Middleware Express : vérifie la signature JWT avec jwt.verify.
 * Ne JAMAIS utiliser jwt.decode pour authentifier (la signature n'est pas vérifiée).
 * À utiliser AVANT toute route qui exige un utilisateur authentifié.
 */
function requireAuth(req, res, next) {
  const authHeader = req.headers['authorization'];
  const token = authHeader && authHeader.split(' ')[1];
 
  if (!token) {
    return res.status(401).json({ success: false, message: 'Access token required' });
  }
 
  try {
    const decoded = jwt.verify(token, JWT_SECRET);
    req.userId = decoded.userId;
    req.userEmail = decoded.email || null;
    req.userRole = decoded.role || null;
    req.organizationId = decoded.organizationId || null;
    req.authMethod = 'jwt';
    next();
  } catch (error) {
    if (error.name === 'TokenExpiredError') {
      return res.status(401).json({ success: false, message: 'Token expired' });
    }
    return res.status(403).json({ success: false, message: 'Invalid token' });
  }
}
 
/**
 * Middleware : exige le rôle admin (à utiliser APRÈS requireAuth).
 */
function requireAdmin(req, res, next) {
  if (req.userRole !== 'admin') {
    return res.status(403).json({ success: false, message: 'Admin access required' });
  }
  next();
}
 
/**
 * Décode le userId sans vérifier la signature (pour logs/traçabilité uniquement).
 * ⚠️ Ne PAS utiliser pour l'authentification — jwt.decode ne vérifie pas la signature.
 */
function peekUserId(req) {
  const authHeader = req.headers['authorization'];
  if (!authHeader) return null;
  const token = authHeader.split(' ')[1];
  if (!token) return null;
  try {
    const decoded = jwt.decode(token);
    return decoded?.userId || null;
  } catch {
    return null;
  }
}
 
module.exports = { requireAuth, requireAdmin, peekUserId };