import { randomBytes, createHash } from "node:crypto"; import { prisma } from "@/lib/prisma"; import { sendMail } from "@/lib/mail"; import { passwordResetEmail } from "@/lib/email-templates"; import { getBaseUrl } from "@/lib/url"; import { getLocale } from "@/i18n/locale"; const RESET_TOKEN_TTL_MS = 60 * 60 * 1000; // 1 Stunde export function hashResetToken(token: string): string { return createHash("sha256").update(token).digest("hex"); } /** * Erzeugt einen einmaligen Passwort-Reset-Token und verschickt den Link per * E-Mail. Gemeinsam genutzt vom Kunden-Self-Service ("Passwort vergessen") * und der Admin-Benutzerverwaltung (statt dass ein Admin dort direkt ein * neues Passwort setzen kann, bekommt der Kunde immer nur diesen Link). */ export async function createAndSendPasswordResetEmail(customer: { id: string; email: string }): Promise { const rawToken = randomBytes(32).toString("hex"); await prisma.passwordResetToken.deleteMany({ where: { customerId: customer.id, usedAt: null } }); await prisma.passwordResetToken.create({ data: { customerId: customer.id, tokenHash: hashResetToken(rawToken), expiresAt: new Date(Date.now() + RESET_TOKEN_TTL_MS), }, }); const resetUrl = `${getBaseUrl()}/konto/passwort-zuruecksetzen?token=${rawToken}`; const { subject, html, text } = await passwordResetEmail(await getLocale(), resetUrl); return sendMail({ to: customer.email, subject, html, text }); }