docs(readme): add a clear Cloudflare Turnstile setup section
CI / check (push) Successful in 39s
CI / tests-imaging-browsers (push) Successful in 1m38s
CI / tests-integration (push) Successful in 2m18s
CI / tests-unit (push) Successful in 2m31s
CI / tests-ui (push) Failing after 4m2s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
CI / check (push) Successful in 39s
CI / tests-imaging-browsers (push) Successful in 1m38s
CI / tests-integration (push) Successful in 2m18s
CI / tests-unit (push) Successful in 2m31s
CI / tests-ui (push) Failing after 4m2s
CI / preflight (push) Skipped
CI / deploy (push) Skipped
Explain where the captcha is configured, how the admin panel and env vars resolve (with a precedence table), step-by-step Turnstile setup, that the site key is public while the secret must never be committed, and how to verify. Also link it from Optional Integrations.
This commit is contained in:
1 parent
d64d864175
commit
918134df69
1 file changed
+79
@@ -851,6 +851,78 @@ Open **DevOps → Anti-DDoS protection**
|
||||
|
||||
---
|
||||
|
||||
## Captcha (Cloudflare Turnstile)
|
||||
|
||||
The **register**, **login**, **forgot-password** and **resend-verification**
|
||||
forms can be protected by a captcha. **Cloudflare Turnstile** is the supported
|
||||
provider and is free; reCAPTCHA and hCaptcha are also wired up. If you only
|
||||
read one thing, read the precedence table below.
|
||||
|
||||
### Where the captcha is configured (and who wins)
|
||||
|
||||
There are two places, and the **admin panel always wins**:
|
||||
|
||||
1. **Admin panel** — *Admin → CMS Settings → Captcha* (stored in the database).
|
||||
2. **Environment variables** — used **only** as a fallback when the admin panel
|
||||
has no value.
|
||||
|
||||
Resolution order, highest first:
|
||||
|
||||
| Admin panel `captcha_provider` | Env `CAPTCHA_PROVIDER` | What happens |
|
||||
| --- | --- | --- |
|
||||
| `turnstile` | anything | **Turnstile** (panel wins) |
|
||||
| `none` (set explicitly) | `turnstile` | **Off** — an explicit panel value wins |
|
||||
| *empty / never set* | `turnstile` | **Turnstile** (env fallback) |
|
||||
| *empty / never set* | *empty / never set* | **Off** |
|
||||
|
||||
In short: **enable it in the admin panel and the env vars are ignored; leave the
|
||||
panel empty and the env vars take over.** An explicit `none` in the panel turns
|
||||
the captcha **off** even when `CAPTCHA_PROVIDER=turnstile` is set.
|
||||
|
||||
### Option A — configure with environment variables (per deploy)
|
||||
|
||||
1. Create a Turnstile widget in the
|
||||
[Cloudflare dashboard](https://dash.cloudflare.com/?to=/:account/turnstile):
|
||||
**Add widget**, name it, and add the hostnames your hotel is served on
|
||||
(e.g. `epicnabbo.nl`, `www.epicnabbo.nl`). *Managed* mode is fine. Copy the
|
||||
**Site Key** and the **Secret Key**.
|
||||
2. Put them in your real `.env` (never commit this file):
|
||||
|
||||
```dotenv
|
||||
CAPTCHA_PROVIDER=turnstile
|
||||
TURNSTILE_SITE_KEY=<your site key> # public — safe to expose
|
||||
TURNSTILE_SECRET_KEY=<your secret key> # SECRET — server-side only
|
||||
```
|
||||
|
||||
- The **site key** is **public**: it is rendered into the page for the
|
||||
browser.
|
||||
- The **secret key** is **secret**: only the server uses it to call
|
||||
Cloudflare's `siteverify` endpoint. **Never commit it** — keep it in the
|
||||
host `.env`, or a **masked CI/CD variable** if you deploy from CI.
|
||||
3. Restart the container so the new env is picked up.
|
||||
|
||||
### Option B — configure in the admin panel
|
||||
|
||||
**Admin → CMS Settings → Captcha**: pick the provider and paste the site key and
|
||||
secret. This overrides the env vars and takes effect **without a restart**.
|
||||
|
||||
### Verify
|
||||
|
||||
- Open `/register`. When active, the Turnstile widget appears above the submit
|
||||
button.
|
||||
- The e2e suite can assert the widget contract:
|
||||
`E2E_EXPECT_CAPTCHA=turnstile pnpm test:e2e` (spec: `e2e/register.spec.ts`).
|
||||
|
||||
### Notes
|
||||
|
||||
- **Fail-closed**: if the provider is Turnstile but no secret key is available,
|
||||
verification fails and the form is blocked — it never silently lets bots in.
|
||||
- The Content-Security-Policy already allows `https://challenges.cloudflare.com`
|
||||
(`src/lib/csp.ts`), so no header changes are needed.
|
||||
- Turnstile does **not** require the Cloudflare proxy (orange cloud); it works
|
||||
independently of the anti-DDoS layer above.
|
||||
|
||||
---
|
||||
|
||||
## Production Deployment (blue/green)
|
||||
|
||||
@@ -1181,6 +1253,13 @@ pnpm jobs:worker # or: npm run jobs:worker / yarn jobs:worker
|
||||
|
||||
Optional OpenAI-powered moderation for comments and guestbook posts. Set `OPENAI_API_KEY`.
|
||||
|
||||
### Captcha — Cloudflare Turnstile
|
||||
|
||||
Protect the register, login, forgot-password and resend-verification forms.
|
||||
Set `CAPTCHA_PROVIDER=turnstile` plus the Turnstile keys in `.env`, or configure
|
||||
it in **Admin → CMS Settings**. Full setup, precedence and verification:
|
||||
[Captcha (Cloudflare Turnstile)](#captcha-cloudflare-turnstile).
|
||||
|
||||
### Byparr (Cloudflare Bypass)
|
||||
|
||||
Some clone sources are protected by Cloudflare. Byparr (a FlareSolverr successor) solves these challenges automatically.
|
||||
|
||||
Reference in new issue
Block a user