diff --git a/ADMIN.md b/ADMIN.md index 548e73f..b0a3db5 100644 --- a/ADMIN.md +++ b/ADMIN.md @@ -166,7 +166,7 @@ Key settings in `backend/.env`: | `MAIL_FROM` | Sender email for verification/reset emails | | `LITELLM_API_BASE` | LiteLLM proxy URL for AI features | | `LITELLM_API_KEY` | API key for LiteLLM proxy | -| `HCAPTCHA_SITE_KEY` / `HCAPTCHA_SECRET_KEY` | hCaptcha bot protection | +| `CAP_SITE_KEY` / `CAP_SECRET_KEY` | Cap bot protection | | `BBB_SERVER_URL` / `BBB_SECRET` | BigBlueButton integration for live sessions | | `OIDC_PROVIDER_URL` | OIDC discovery URL (see SSO section below) | | `OIDC_CLIENT_ID` | OAuth client ID from your identity provider | diff --git a/README.md b/README.md index a324898..2fdb2a6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ AI-powered pediatric learning platform. Upload PDF study materials, automaticall - **Concurrent Quiz Protection**: Redis session locks prevent the same quiz from being resumed on multiple devices simultaneously - **Landing Page**: Integrated with the app — Sign In / Register open as modal overlays, shared Navbar - **PWA**: Installable on mobile/desktop (no caching — avoids stale JS issues) -- **Bot Protection**: hCaptcha on registration and contact forms +- **Bot Protection**: Cap on registration and contact forms - **Email Verification**: Required before first login; password reset via email - **Role System**: Admin / Moderator / User with optional rate-limit exemption (unthrottle) - **Admin User Management**: Delete users, change roles, toggle unthrottle — all from the admin dashboard @@ -39,7 +39,7 @@ AI-powered pediatric learning platform. Upload PDF study materials, automaticall | TTS | LiteLLM-routed local TTS, OpenAI (direct), ElevenLabs, Google Cloud TTS | | Queue | Celery + Redis (4 fork workers) | | Email | SMTP (smtp2go or any SMTP server) | -| Bot protection | hCaptcha (runtime-configurable, no rebuild needed) | +| Bot protection | Cap (runtime-configurable, no rebuild needed) | For detailed architecture documentation, see [docs/architecture.md](docs/architecture.md). @@ -101,8 +101,8 @@ MAIL_PASSWORD= MAIL_FROM=noreply@yourdomain.com MAIL_STARTTLS=true -# Bot protection — hCaptcha (backend secret) -HCAPTCHA_SECRET_KEY= +# Bot protection — Cap (backend secret) +CAP_SECRET_KEY= # Contact form admin notifications ADMIN_EMAIL=admin@yourdomain.com @@ -121,8 +121,8 @@ DEFAULT_ADMIN_PASSWORD= ### Frontend (`frontend/.env`) ```env -# Bot protection — hCaptcha (public site key) -HCAPTCHA_SITE_KEY= +# Bot protection — Cap (public site key) +CAP_SITE_KEY= ``` The frontend env file is **not** baked into the Docker image at build time. Instead, `docker-entrypoint.sh` generates a `/config.js` file from the env vars when the container **starts**. This means: @@ -131,31 +131,31 @@ The frontend env file is **not** baked into the Docker image at build time. Inst - Switch captcha providers by updating the entrypoint script and the widget component - Remove bot protection by clearing the key (empty = disabled) -## hCaptcha (Bot Protection) +## Cap (Bot Protection) ### How it works -hCaptcha protects the **registration** and **contact** forms from bot submissions. One shared component, `frontend/src/components/Captcha.jsx`, renders every widget; one backend service, `backend/app/services/captcha.py`, verifies every token. +Cap protects the **registration** and **contact** forms from bot submissions. One shared component, `frontend/src/components/Captcha.jsx`, renders every widget; one backend service, `backend/app/services/captcha.py`, verifies every token. **Flow:** ``` -1. Page loads → Captcha component loads js.hcaptcha.com/1/api.js (once) +1. Page loads → Captcha component loads js.cap.com/1/api.js (once) 2. Widget renders where the component sits on the form 3. User completes challenge → widget calls onVerify(token) 4. Frontend stores token in state → Sign Up button becomes enabled 5. User submits form → token sent as `captcha_token` in POST body -6. Backend receives token → POSTs to hCaptcha's siteverify API: - POST https://api.hcaptcha.com/siteverify - Body: { secret: HCAPTCHA_SECRET_KEY, response: captcha_token } -7. hCaptcha returns { success: true/false } +6. Backend receives token → POSTs to Cap's siteverify API: + POST https://api.cap.com/siteverify + Body: { secret: CAP_SECRET_KEY, response: captcha_token } +7. Cap returns { success: true/false } 8. If false → 400 "Bot verification failed" 9. If true → registration proceeds normally ``` A solve expires after a couple of minutes; the widget says so, the component clears the stored token, and the submit button goes back to disabled rather than sending something that will be refused. -**Where hCaptcha is active:** +**Where Cap is active:** - Register form (modal overlay on landing page) - Register form (standalone `/register` page) - Contact form (landing page) @@ -163,30 +163,30 @@ A solve expires after a couple of minutes; the widget says so, the component cle **Where it is NOT active (by design):** - Login — protected by IP-based rate limiting (10 attempts / 15 min) instead -**When hCaptcha itself is unreachable**, registration is let through and the contact form is not: an outage that blocks sign-ups costs the site its users, while a bounced message costs the sender one retry. +**When Cap itself is unreachable**, registration is let through and the contact form is not: an outage that blocks sign-ups costs the site its users, while a bounced message costs the sender one retry. ### Setup -1. Go to https://dashboard.hcaptcha.com → Sites → New Site +1. Go to https://dashboard.cap.com → Sites → New Site 2. Add your domain(s) 3. Copy the Site Key, and the account's Secret Key from Settings ```bash # frontend/.env -HCAPTCHA_SITE_KEY=10000000-ffff-... +CAP_SITE_KEY=10000000-ffff-... # backend/.env -HCAPTCHA_SECRET_KEY=ES_... +CAP_SECRET_KEY=ES_... # Restart (no rebuild needed) docker compose restart frontend backend ``` -The CSP in `frontend/nginx.conf` already allows `hcaptcha.com` and its subdomains for scripts, frames, images and XHR; a provider change means editing that header too. +The CSP in `frontend/nginx.conf` already allows `cap.com` and its subdomains for scripts, frames, images and XHR; a provider change means editing that header too. ### Testing -hCaptcha publishes a key pair that always passes: +Cap publishes a key pair that always passes: | Purpose | Site Key | Secret Key | |---|---|---| @@ -203,14 +203,14 @@ docker-compose.yml └─ frontend service: env_file: ./frontend/.env Container startup (docker-entrypoint.sh): - └─ Reads $HCAPTCHA_SITE_KEY from environment + └─ Reads $CAP_SITE_KEY from environment └─ Writes /usr/share/nginx/html/config.js: - window.__APP_CONFIG__ = { HCAPTCHA_SITE_KEY: "10000000-ffff-..." }; + window.__APP_CONFIG__ = { CAP_SITE_KEY: "10000000-ffff-..." }; Browser loads index.html: └─