mise a jour

This commit is contained in:
Emma781227
2026-07-08 07:10:49 +02:00
parent 68a9650223
commit 65d6b23233
12 changed files with 603 additions and 182 deletions

View File

@@ -34,8 +34,8 @@ const register = async (req, res) => {
const hashedPassword = await bcrypt.hash(password, 10);
const emailVerifyToken = crypto.randomBytes(32).toString("hex");
const emailVerifyExpires = new Date(Date.now() + 1000 * 60 * 60); // 1h
const emailVerifyToken = String(Math.floor(1000 + Math.random() * 9000));
const emailVerifyExpires = new Date(Date.now() + 1000 * 60 * 15); // 15 min
const user = await prisma.user.create({
data: {
@@ -62,23 +62,25 @@ const register = async (req, res) => {
},
});
const verifyUrl = `${process.env.APP_URL}/api/auth/verify-email/${emailVerifyToken}`;
await transporter.sendMail({
from: process.env.MAIL_FROM,
to: email,
subject: "Validation de votre compte Thé Tip Top",
subject: "Votre code de validation Thé Tip Top",
html: `
<h2>Bienvenue ${firstname}</h2>
<p>Merci pour votre inscription.</p>
<p>Veuillez cliquer sur le lien ci-dessous pour valider votre compte :</p>
<a href="${verifyUrl}">Valider mon compte</a>
<p>Ce lien expire dans 1 heure.</p>
<div style="font-family:sans-serif;max-width:480px;margin:auto">
<h2 style="color:#006B6B">Bienvenue ${firstname} !</h2>
<p>Merci pour votre inscription sur Thé Tip Top.</p>
<p>Voici votre code de validation à 4 chiffres :</p>
<div style="font-size:36px;font-weight:bold;letter-spacing:12px;color:#006B6B;text-align:center;padding:20px 0">
${emailVerifyToken}
</div>
<p style="color:#888;font-size:13px">Ce code expire dans <strong>15 minutes</strong>.</p>
</div>
`,
});
return res.status(201).json({
message: "Inscription réussie. Un email de validation a été envoyé.",
message: "Inscription réussie. Un code de validation a été envoyé par email.",
user,
});
} catch (error) {
@@ -148,7 +150,7 @@ const login = async (req, res) => {
});
}
if (!user.isEmailVerified) {
if (!user.isEmailVerified && user.role === "CLIENT") {
return res.status(403).json({
message: "Veuillez valider votre adresse email avant de vous connecter.",
});
@@ -298,12 +300,106 @@ const resetPassword = async (req, res) => {
}
};
const verifyCode = async (req, res) => {
try {
const { email, code } = req.body;
if (!email || !code) {
return res.status(400).json({ message: "Email et code requis." });
}
const user = await prisma.user.findUnique({ where: { email } });
if (!user) {
return res.status(404).json({ message: "Compte introuvable." });
}
if (user.isEmailVerified) {
return res.status(400).json({ message: "Ce compte est déjà vérifié." });
}
if (!user.emailVerifyToken || user.emailVerifyToken !== String(code)) {
return res.status(400).json({ message: "Code invalide." });
}
if (new Date() > user.emailVerifyExpires) {
return res.status(400).json({ message: "Code expiré. Veuillez vous réinscrire." });
}
await prisma.user.update({
where: { id: user.id },
data: { isEmailVerified: true, emailVerifyToken: null, emailVerifyExpires: null },
});
const token = jwt.sign(
{ id: user.id, role: user.role },
process.env.JWT_SECRET,
{ expiresIn: "24h" }
);
return res.json({
message: "Compte vérifié avec succès.",
token,
user: {
id: user.id,
firstname: user.firstname,
lastname: user.lastname,
email: user.email,
role: user.role,
},
});
} catch (error) {
console.error("Erreur verifyCode:", error);
return res.status(500).json({ message: "Erreur serveur lors de la vérification." });
}
};
const me = async (req, res) => {
return res.json({
user: req.user,
});
};
const deleteAccount = async (req, res) => {
try {
const userId = req.user.id;
await prisma.$transaction(async (tx) => {
// 1. Supprimer le grand gagnant si c'est lui
await tx.grandPrizeWinner.deleteMany({ where: { userId } });
// 2. Récupérer les participations pour supprimer leurs claims
const participations = await tx.participation.findMany({
where: { userId },
select: { id: true },
});
const participationIds = participations.map((p) => p.id);
// 3. Supprimer les claims
if (participationIds.length > 0) {
await tx.claim.deleteMany({ where: { participationId: { in: participationIds } } });
}
// 4. Supprimer les participations
await tx.participation.deleteMany({ where: { userId } });
// 5. Libérer les tickets utilisés par ce user
await tx.ticket.updateMany({
where: { userId },
data: { userId: null, isUsed: false, usedAt: null },
});
// 6. Supprimer l'utilisateur
await tx.user.delete({ where: { id: userId } });
});
return res.json({ message: "Compte supprimé avec succès." });
} catch (error) {
console.error("Erreur deleteAccount:", error);
return res.status(500).json({ message: "Erreur serveur lors de la suppression du compte." });
}
};
const changePassword = async (req, res) => {
try {
const { currentPassword, newPassword } = req.body;
@@ -339,7 +435,9 @@ module.exports = {
login,
me,
verifyEmail,
verifyCode,
resetPassword,
forgotPassword,
changePassword,
deleteAccount,
};