Add rate limiting, sliding sessions, email verification, GDPR self-service, order cancellation/returns, and critical-error alerting
Complements Payload's per-account login lockout with per-IP rate limiting on auth routes; proxy.ts silently refreshes an active customer's session via Payload's built-in refresh-token endpoint instead of a long-lived token. Registration now sends a non-blocking email-verification link (doesn't gate login, since checkout registers and immediately logs in mid-purchase). /konto/profil gets GDPR export/delete; order detail pages get self-service cancel/return-request, backed by a Payload hook that closes a real gap (a customer's JWT could previously PATCH any field of their own order, not just status). Checkout failures now email an alert independent of Payload's own health, since Kuma's uptime checks can't see an order silently failing to persist. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import { validateDiscountCode, redeemDiscountCode } from "../../lib/discountServ
|
||||
import { createOrder } from "../../lib/orderServer";
|
||||
import { getSessionCustomer, registerCustomer, setSessionCookie, type CustomerSummary } from "../../lib/customerAuth";
|
||||
import { fetchProductsBySlug } from "../../lib/productsServer";
|
||||
import { sendCriticalAlert } from "../../lib/alertAdmin";
|
||||
|
||||
type CheckoutBody = {
|
||||
cart: CartItem[];
|
||||
@@ -137,7 +138,21 @@ export async function POST(request: Request) {
|
||||
discountAmount,
|
||||
total,
|
||||
});
|
||||
if (!order) return NextResponse.json({ ok: false, reason: "Bestellung konnte nicht gespeichert werden." }, { status: 500 });
|
||||
if (!order) {
|
||||
// The worst-case failure in this whole flow: the customer went
|
||||
// through checkout believing they bought something, and nothing was
|
||||
// persisted. Kuma's uptime checks can't see this (the site is up,
|
||||
// this route just returned a 500) — this is the one alert path that
|
||||
// can.
|
||||
sendCriticalAlert("Bestellung konnte nicht gespeichert werden", {
|
||||
customerId: customer.id,
|
||||
customerEmail: body.email,
|
||||
cart: body.cart,
|
||||
total,
|
||||
timestamp: new Date().toISOString(),
|
||||
});
|
||||
return NextResponse.json({ ok: false, reason: "Bestellung konnte nicht gespeichert werden." }, { status: 500 });
|
||||
}
|
||||
|
||||
return NextResponse.json({
|
||||
ok: true,
|
||||
|
||||
Reference in New Issue
Block a user