const jwt = require("jsonwebtoken"); const prisma = require("../config/prisma"); // Seules routes accessibles tant qu'un mot de passe provisoire n'a pas été // remplacé : sans ce filtre côté serveur, il suffirait d'appeler l'API // directement pour contourner la page du front. const ALLOWED_WHILE_PASSWORD_CHANGE_REQUIRED = ["/api/auth/me", "/api/auth/initial-password"]; const authMiddleware = async (req, res, next) => { try { const authHeader = req.headers.authorization; if (!authHeader || !authHeader.startsWith("Bearer ")) { return res.status(401).json({ message: "Token manquant ou invalide.", }); } const token = authHeader.split(" ")[1]; const decoded = jwt.verify(token, process.env.JWT_SECRET); const user = await prisma.user.findUnique({ where: { id: decoded.id }, select: { id: true, firstname: true, lastname: true, email: true, role: true, provider: true, password: true, mustChangePassword: true, }, }); if (!user) { return res.status(401).json({ message: "Utilisateur introuvable.", }); } const route = `${req.baseUrl}${req.path}`.replace(/\/+$/, ""); if (user.mustChangePassword && !ALLOWED_WHILE_PASSWORD_CHANGE_REQUIRED.includes(route)) { return res.status(403).json({ message: "Vous devez choisir un nouveau mot de passe avant de continuer.", code: "PASSWORD_CHANGE_REQUIRED", }); } // req.user est renvoyé tel quel par /api/auth/me : on remplace le hash par // un simple booléen, qui suffit au profil pour proposer « définir » ou // « modifier » son mot de passe. const { password, ...rest } = user; req.user = { ...rest, hasPassword: Boolean(password) }; next(); } catch (error) { return res.status(401).json({ message: "Token invalide ou expiré.", }); } }; module.exports = authMiddleware;