"use server"; import { createHash, randomBytes } from "crypto"; import { db } from "@/lib/db"; import { sendMail } from "@/lib/mail"; import { checkRateLimit } from "@/lib/rate-limit"; export type RecuperarSenhaState = { ok: boolean; message?: string; }; function hashToken(token: string) { return createHash("sha256").update(token).digest("hex"); } export async function solicitarRecuperacao( _state: RecuperarSenhaState, formData: FormData ): Promise { const email = formData.get("email")?.toString().trim().toLowerCase(); const genericMessage = "Se o e-mail estiver cadastrado, enviaremos as instrucoes de redefinicao."; const limit = checkRateLimit(`recuperar-senha:${email ?? "sem-email"}`, 5, 60 * 60 * 1000); if (!limit.allowed) { return { ok: true, message: genericMessage }; } if (!email) { return { ok: true, message: genericMessage }; } const user = await db.user.findUnique({ where: { email }, select: { id: true, email: true } }); if (!user) { return { ok: true, message: genericMessage }; } const token = randomBytes(32).toString("base64url"); const tokenHash = hashToken(token); const expiraEm = new Date(Date.now() + 60 * 60 * 1000); await db.passwordResetToken.create({ data: { userId: user.id, tokenHash, expiraEm } }); const baseUrl = process.env.APP_URL ?? "http://localhost:3000"; const resetUrl = `${baseUrl}/redefinir-senha?token=${token}`; await sendMail({ to: user.email, subject: "Redefinicao de senha - Briefing SeConectai", text: `Use o link abaixo para redefinir sua senha. Ele expira em 1 hora.\n\n${resetUrl}` }); return { ok: true, message: genericMessage }; } export { hashToken };