Files
Wabenhain/src/lib/email-verification.ts
T
Nick Szaunig c7927f2883 feat: Wabenhain Honig-Shop Anwendung
Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei:
Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich
(Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare
Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung,
PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma-
Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
2026-08-17 14:30:28 +02:00

34 lines
1.4 KiB
TypeScript

import { randomBytes, createHash } from "node:crypto";
import { prisma } from "@/lib/prisma";
import { sendMail } from "@/lib/mail";
import { emailVerificationEmail } from "@/lib/email-templates";
import { getBaseUrl } from "@/lib/url";
import { getLocale } from "@/i18n/locale";
const VERIFICATION_TOKEN_TTL_MS = 24 * 60 * 60 * 1000; // 24 Stunden
export function hashVerificationToken(token: string): string {
return createHash("sha256").update(token).digest("hex");
}
/**
* Erzeugt einen einmaligen E-Mail-Bestaetigungs-Token und verschickt den
* Link. Wird nach der Selbst-Registrierung aufgerufen sowie ueber den
* "Link erneut senden"-Button auf /konto, solange das Konto unbestaetigt ist.
*/
export async function createAndSendVerificationEmail(customer: { id: string; email: string }): Promise<void> {
const rawToken = randomBytes(32).toString("hex");
await prisma.emailVerificationToken.deleteMany({ where: { customerId: customer.id, usedAt: null } });
await prisma.emailVerificationToken.create({
data: {
customerId: customer.id,
tokenHash: hashVerificationToken(rawToken),
expiresAt: new Date(Date.now() + VERIFICATION_TOKEN_TTL_MS),
},
});
const verifyUrl = `${getBaseUrl()}/api/konto/email-bestaetigen?token=${rawToken}`;
const { subject, html, text } = await emailVerificationEmail(await getLocale(), verifyUrl);
await sendMail({ to: customer.email, subject, html, text });
}