feat(signup): open registration — drop invite gate, kill switch, cap pow captcha (#49, #50) #51

Sammanfogat
supernaut sammanfogade 3 incheckningar från open-registration in i main 2026-07-17 21:43:20 +00:00
Ägare

Web half of the Open registration epic (bitborg-docs#27; ADR 0029). Closes #49, closes #50. Companion: bitborg-infra#86 (must be applied for the env/secret plumbing — CAP_SECRET, KANIDM_TIER_GROUP, SIGNUPS_OPEN=true).

  • Invite gate removed end-to-end (form, API, admin issuance, i18n); invite_codes table kept for audit. nanoid dep dropped.
  • Real SIGNUPS_OPEN kill switch: closed → /signup 302s home, signup + captcha APIs 404, CTAs hidden. Default open.
  • Cap PoW captcha, embedded + fully first-party: capjs-core challenge/redeem routes (rate-limited), single-use token enforcement (in-memory, single-process), fail-closed in prod without CAP_SECRET; cap-widget bundled with SELF-HOSTED wasm/pako via Vite ?url (jsDelivr defaults overridden before module load — verified in built output); CSP additions scoped to /signup only (wasm-unsafe-eval, worker-src blob:, hashed widget style).
  • Copy: participant framing sv/en (never "free tier"); style-guide checked.

Verified server-side (built server + curl): challenge→PoW→redeem→signup round-trip; redeem/token replay rejected; prod-without-secret fails closed; kill switch closes everything; CSP header correct; pnpm check/build/test/lint all green (29/29 tests).

Needs a browser before/at merge (5 min): open /signup, confirm the widget renders + solves under the CSP and devtools shows ZERO third-party requests.

Web half of the Open registration epic (bitborg-docs#27; ADR 0029). Closes #49, closes #50. Companion: bitborg-infra#86 (must be applied for the env/secret plumbing — CAP_SECRET, KANIDM_TIER_GROUP, SIGNUPS_OPEN=true). - **Invite gate removed** end-to-end (form, API, admin issuance, i18n); `invite_codes` table kept for audit. `nanoid` dep dropped. - **Real `SIGNUPS_OPEN` kill switch**: closed → `/signup` 302s home, signup + captcha APIs 404, CTAs hidden. Default open. - **Cap PoW captcha, embedded + fully first-party**: `capjs-core` challenge/redeem routes (rate-limited), single-use token enforcement (in-memory, single-process), fail-closed in prod without `CAP_SECRET`; `cap-widget` bundled with SELF-HOSTED wasm/pako via Vite `?url` (jsDelivr defaults overridden before module load — verified in built output); CSP additions scoped to /signup only (`wasm-unsafe-eval`, `worker-src blob:`, hashed widget style). - Copy: participant framing sv/en (never "free tier"); style-guide checked. **Verified server-side** (built server + curl): challenge→PoW→redeem→signup round-trip; redeem/token replay rejected; prod-without-secret fails closed; kill switch closes everything; CSP header correct; `pnpm check/build/test/lint` all green (29/29 tests). **Needs a browser before/at merge** (5 min): open /signup, confirm the widget renders + solves under the CSP and devtools shows ZERO third-party requests.
supernaut lade till 3 incheckningar 2026-07-17 17:17:53 +00:00
Open registration (ADR 0029): the sign-up form no longer asks for an
invite code, and the admin invite-issuance surface (API route, lib,
account-panel section, i18n strings) is retired. The invite_codes table
stays for audit. A runtime SIGNUPS_OPEN kill switch (default open) lets
one infra var + restart close sign-up: pages redirect home, POST
/api/signup 404s, CTAs are hidden. Sign-up copy reframed around the
participant account.
Gate sign-up behind Cap (capjs-core embedded in the app — no extra
container), with challenge/redeem API routes, single-use in-memory
token state, and a fail-closed CAP_SECRET requirement in production
(dev bypasses so local testing needs no secret). The cap-widget is
bundled through the normal client build with the wasm solver and pako
fallback self-hosted via ?url imports — the browser makes zero
third-party requests on /signup. CSP additions are scoped to the
sign-up page: 'wasm-unsafe-eval' (WebAssembly.compile), worker-src
blob: (solver workers) and the hash of the widget's shadow-root
stylesheet.
docs: retire invite references in design doc and schema comments (#49)
Alla kontroller lyckades
ci / ci (pull_request) Successful in 53s
4a3a648732
supernaut sammanfogade incheckning b9bbaffa1e till main 2026-07-17 21:43:20 +00:00
supernaut tog bort grenen open-registration 2026-07-17 21:43:21 +00:00
Logga in för att delta i denna konversation.
Inga granskare
Ingen milstolpe
Inget projekt
Inga tilldelade
1 deltagare
Notiser
Förfallodatum
Förfallodatumet är ogiltigt eller utanför gränserna. Använd formatet "åååå-mm-dd".

Inget förfallodatum satt.

Beroenden

Inga beroenden satta

Referens
bitborg/bitborg-web!51
Ingen beskrivning angiven.