Files
THE-TIP-TOP/backend/src/middlewares/auth.middleware.js
Emma781227 2201446ee6 changement
2026-09-14 22:30:40 +02:00

64 lines
1.9 KiB
JavaScript

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;