fix: harden booking and meeting flows

This commit is contained in:
2026-09-17 02:42:27 +02:00
parent cb30ecade9
commit 66710fc65c
42 changed files with 683 additions and 608 deletions
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
import { getPayload } from "payload";
import config from "@payload-config";
import { checkRateLimit, getClientIp } from "@/lib/auth/rateLimit";
import { allowVerificationEmail } from "@/lib/auth/verificationRateLimit";
import { EMAIL_VERIFICATION_TTL_MS, generateVerificationToken, hashVerificationToken, verificationExpiryISO } from "@/lib/auth/verification";
import { verificationEmail } from "@/lib/email/authTemplates";
import { sendEmail } from "@/lib/email/sendBookingEmails";
@@ -57,11 +58,12 @@ export async function POST(request: Request) {
let body: { email?: unknown } = {};
try {
body = await request.json();
if (!body || typeof body !== "object" || Array.isArray(body)) throw new Error("Invalid body");
} catch {
// no body — handled below as a missing email
}
const email = typeof body.email === "string" ? body.email.trim().toLowerCase() : "";
if (!email) {
const email = typeof body?.email === "string" ? body.email.trim().toLowerCase() : "";
if (!email || email.length > 254) {
return NextResponse.json({ error: "E-Mail-Adresse erforderlich." }, { status: 400 });
}
if (!checkRateLimit(`resend-verification:email:${email}`, { max: 3, windowMs: 60 * 60 * 1000 })) {
@@ -77,8 +79,8 @@ export async function POST(request: Request) {
}
if (customer && !customer.emailVerified) {
if (!checkRateLimit(`resend-verification:customer:${customer.id}`, { max: 3, windowMs: 60 * 60 * 1000 })) {
return NextResponse.json({ error: "Zu viele Anfragen. Bitte versuche es später erneut." }, { status: 429 });
if (!allowVerificationEmail(request, customer.email, customer.id)) {
return NextResponse.json(GENERIC_RESPONSE);
}
await issueAndSend(payload, customer);
}