76 lines
2.2 KiB
TypeScript
76 lines
2.2 KiB
TypeScript
import { NextResponse } from "next/server";
|
|
import crypto from "crypto";
|
|
import { prisma } from "@/lib/prisma";
|
|
|
|
function safeCompareSecret(provided: string | null, expected: string | undefined): boolean {
|
|
if (!provided || !expected) return false;
|
|
const bufA = Buffer.from(provided);
|
|
const bufB = Buffer.from(expected);
|
|
if (bufA.length !== bufB.length) return false;
|
|
return crypto.timingSafeEqual(bufA, bufB);
|
|
}
|
|
|
|
/**
|
|
* Route pour le nettoyage automatique des comptes
|
|
* À appeler via une tâche cron (ex: chaque nuit à minuit)
|
|
* Supporte `Authorization: Bearer <CRON_SECRET>` ou `?key=<CRON_SECRET>`
|
|
*/
|
|
export async function GET(request: Request) {
|
|
const { searchParams } = new URL(request.url);
|
|
const authHeader = request.headers.get("authorization");
|
|
const bearerToken = authHeader?.startsWith("Bearer ")
|
|
? authHeader.slice("Bearer ".length).trim()
|
|
: null;
|
|
const key = bearerToken || searchParams.get("key");
|
|
|
|
if (!safeCompareSecret(key, process.env.CRON_SECRET)) {
|
|
return NextResponse.json({ error: "Non autorisé" }, { status: 401 });
|
|
}
|
|
|
|
try {
|
|
const now = new Date();
|
|
|
|
// 1. Trouver les utilisateurs dont le délai est passé
|
|
const usersToDelete = await prisma.user.findMany({
|
|
where: {
|
|
deletionScheduledAt: {
|
|
lte: now
|
|
}
|
|
}
|
|
});
|
|
|
|
if (usersToDelete.length === 0) {
|
|
return NextResponse.json({ message: "Aucun compte à supprimer" });
|
|
}
|
|
|
|
const userIds = usersToDelete.map(u => u.id);
|
|
|
|
// 2. Préserver les avis rédigés en les dissociant du compte (deviennent anonymes / "Utilisateur supprimé")
|
|
await prisma.rating.updateMany({
|
|
where: {
|
|
userId: { in: userIds }
|
|
},
|
|
data: {
|
|
userId: null
|
|
}
|
|
});
|
|
|
|
// 3. Suppression définitive des comptes utilisateurs
|
|
const deleteResult = await prisma.user.deleteMany({
|
|
where: {
|
|
id: {
|
|
in: userIds
|
|
}
|
|
}
|
|
});
|
|
|
|
return NextResponse.json({
|
|
message: `${deleteResult.count} compte(s) supprimé(s) définitivement`,
|
|
deletedIds: usersToDelete.map(u => u.id)
|
|
});
|
|
} catch (error) {
|
|
console.error("Cron Cleanup Error:", error);
|
|
return NextResponse.json({ error: "Erreur lors du nettoyage" }, { status: 500 });
|
|
}
|
|
}
|