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.
This commit is contained in:
1 parent
5c76fcc266
commit
c7927f2883
240 files changed
+26096
-137
No files matched your search
@@ -0,0 +1,40 @@
|
||||
const VERIFY_URL = "https://challenges.cloudflare.com/turnstile/v0/siteverify";
|
||||
|
||||
// Nur beim ersten Modul-Laden geprueft (nicht pro Request) — macht ein in
|
||||
// Produktion vergessenes TURNSTILE_SECRET_KEY im Server-Log sichtbar, statt
|
||||
// die CAPTCHA-Pruefung stillschweigend fuer alle Formulare zu ueberspringen.
|
||||
if (process.env.NODE_ENV === "production" && !process.env.TURNSTILE_SECRET_KEY) {
|
||||
console.warn(
|
||||
"TURNSTILE_SECRET_KEY ist in Produktion nicht gesetzt — CAPTCHA-Pruefung auf Registrierung/Newsletter/Firmenanfrage ist deaktiviert."
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prueft ein Cloudflare-Turnstile-Token serverseitig gegen die Siteverify-
|
||||
* API. Ohne konfigurierten TURNSTILE_SECRET_KEY wird die Pruefung
|
||||
* uebersprungen (true) — analog zum Stripe/Google-Fallback ohne
|
||||
* Zugangsdaten, damit die Formulare auch ohne CAPTCHA-Setup nutzbar bleiben.
|
||||
*/
|
||||
export async function verifyTurnstileToken(token: string | null, remoteIp?: string): Promise<boolean> {
|
||||
const secret = process.env.TURNSTILE_SECRET_KEY;
|
||||
if (!secret) return true;
|
||||
if (!token) return false;
|
||||
|
||||
try {
|
||||
const response = await fetch(VERIFY_URL, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/x-www-form-urlencoded" },
|
||||
body: new URLSearchParams({ secret, response: token, ...(remoteIp ? { remoteip: remoteIp } : {}) }),
|
||||
});
|
||||
const data = (await response.json()) as { success: boolean };
|
||||
return data.success === true;
|
||||
} catch {
|
||||
// Anders als bei fehlendem Secret (bewusst nicht konfiguriert) ist hier
|
||||
// ein Secret vorhanden — Turnstile wurde also aktiv gewuenscht. Ein
|
||||
// Netzwerkfehler bei der Pruefung selbst darf dann nicht stillschweigend
|
||||
// als "bestanden" gewertet werden, sonst waere die Pruefung durch simples
|
||||
// Stoeren der Verbindung zu Cloudflare umgehbar. Das Rate-Limiting bleibt
|
||||
// in diesem Fall die einzige Verteidigungslinie.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user