feat: Cloudflare Turnstile on auth, CSP fixes, admin/SEO/analytics additions
Turnstile bot protection (sign-in, sign-up, password-reset): - Register Better Auth's captcha plugin with the cloudflare-turnstile provider; endpoints listed explicitly rather than relying on defaults. /reset-password is intentionally excluded — it is reached only via a single-use emailed token. - Add an explicit-render Turnstile widget component. Tokens are single-use, so each form resets the challenge after a failed submit; submit stays disabled until a token is held. - Read the site key server-side and pass it down as a prop, so rotating it does not require a rebuild. - Fail fast in production when TURNSTILE_SECRET_KEY is missing, and when a secret is set without a site key (that combination would demand a token no form can produce, locking every user out). - Pass a throwaway secret during `next build` in the Dockerfile, mirroring the existing BETTER_AUTH_SECRET treatment, so image builds don't need it. CSP fixes in middleware (these blocked Turnstile entirely): - Add frame-src for challenges.cloudflare.com. Without it the widget's iframe fell back to default-src 'self' and was blocked outright. - Allow 'unsafe-eval' and websockets in DEVELOPMENT only. `next dev` compiles with eval(), so the strict policy threw EvalError and killed hydration — no client JS ran at all, which also meant form submit handlers never fired. Production policy is unchanged and still strict. Also included (concurrent work in the tree): - Admin organizations pages and lib/admin/orgs. - Episode moderation migration, SEO metadata (sitemap, robots, JSON-LD, OG/Twitter images, manifest), Umami analytics, not-found page. Local dev database: docker-compose.dev.yml provisions Postgres 18 on port 5443 (5432-5442 are in use by other local projects). Note: `npx tsc --noEmit` currently fails in app/(app)/team/page.tsx — an `invitations` prop the component does not accept. This predates the commit and will fail `next build` until fixed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
35379212fb
commit
3e9ba07175
@@ -1,7 +1,17 @@
|
||||
import type { Metadata } from "next";
|
||||
import { LegalDoc, type LegalSection } from "@/components/marketing/legal-doc";
|
||||
import { pageMetadata } from "@/lib/seo";
|
||||
|
||||
export const metadata: Metadata = { title: "Privacy Policy" };
|
||||
/** Shared by the page metadata and the document's structured data. */
|
||||
const PATH = "/privacy";
|
||||
const DESCRIPTION =
|
||||
"How Podcast Distribution AI collects, uses, stores and protects your personal data and generated content — and the rights you have over it.";
|
||||
|
||||
export const metadata: Metadata = pageMetadata({
|
||||
title: "Privacy Policy",
|
||||
description: DESCRIPTION,
|
||||
path: PATH,
|
||||
});
|
||||
|
||||
const UPDATED = "June 7, 2026";
|
||||
|
||||
@@ -102,6 +112,8 @@ export default function PrivacyPage() {
|
||||
updated={UPDATED}
|
||||
intro="This Privacy Policy explains what information Podcast Distribution AI collects, how we use it, who we share it with, and the choices you have. It applies to your use of the Podcast Distribution AI website and application."
|
||||
sections={SECTIONS}
|
||||
path={PATH}
|
||||
description={DESCRIPTION}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user