import { createHash, randomInt } from "crypto"; import { sql } from "@/lib/db"; import { sendEmail } from "@/lib/mailer"; const hashCode = (email: string, code: string): string => createHash("sha256").update(`${email}:${code}`).digest("hex"); export async function POST(req: Request) { const { email } = await req.json(); if (!email?.trim()) { return Response.json({ error: "Email is required." }, { status: 400 }); } const normalized = email.trim().toLowerCase(); try { const users = await sql<{ id: string }>` SELECT id FROM users WHERE email = ${normalized} `; // Don't reveal whether the address is registered: always answer the same. if (!users[0]) { return Response.json({ data: { sent: false } }); } const code = String(randomInt(0, 1_000_000)).padStart(6, "0"); await sql` INSERT INTO password_reset_codes (email, code_hash, expires_at) VALUES ( ${normalized}, ${hashCode(normalized, code)}, CURRENT_TIMESTAMP + INTERVAL '15 minutes' ) ON CONFLICT (email) DO UPDATE SET code_hash = EXCLUDED.code_hash, expires_at = EXCLUDED.expires_at, attempts = 0 `; const delivered = await sendEmail( normalized, "Reset your Waseel password", `We received a request to reset your Waseel password.\n\nYour reset code is: ${code}\n\nIt expires in 15 minutes. If you didn't ask for this, you can ignore this email.`, ); return Response.json({ data: { sent: delivered, // Without SMTP configured there is nothing to receive, so surface the // code to keep the reset flow usable on a self-hosted box. ...(delivered ? {} : { devCode: code }), }, }); } catch (error) { console.error("[FORGOT_PASSWORD]: ", error); return Response.json({ error: "Internal Server Error" }, { status: 500 }); } }