Fix #502: anonymous write interstitial #507

Merged
crueber merged 1 commit from fix/issue-502 into main 2026-09-14 00:38:45 +00:00
Owner

Anonymous visitors in OIDC anonymous-read mode browse everything but execute zero writes — every attempted write refuses server-side (uniform 401) and routes to a new log-in interstitial returning to the attempted action.

Backend (docs/go/06_server_http.md §8.6): gate() 401-for-anonymous on AuthWrite/AuthAdmin before flag checks (defect B); ssh-keys explicit anonymous check closing the defect-A leak; apiServe oidc anonymous write-assert middleware; releases/tags requireRole confirmed 401.
Client: headless web/src/lib/writeGate.js + /login-required page + per-affordance wiring (star/watch/fork, New issue/pull, composers, reactions, create forms) + SDK _call noPopupAuth opt-out.
Docs: 06 §8.6, 12_web_ui (§1.2 + §2.3), features/01 §4.1 + Decisions.

Tests: internal/api + internal/server green (-race), coverage api 95.3% / server 98.4%; node 1122/1121 (1 pre-existing live-server smoke fail, also on main); vite+esbuild green. Fixes #502.

Anonymous visitors in OIDC anonymous-read mode browse everything but execute zero writes — every attempted write refuses server-side (uniform 401) and routes to a new log-in interstitial returning to the attempted action. Backend (docs/go/06_server_http.md §8.6): gate() 401-for-anonymous on AuthWrite/AuthAdmin before flag checks (defect B); ssh-keys explicit anonymous check closing the defect-A leak; apiServe oidc anonymous write-assert middleware; releases/tags requireRole confirmed 401. Client: headless web/src/lib/writeGate.js + /login-required page + per-affordance wiring (star/watch/fork, New issue/pull, composers, reactions, create forms) + SDK _call noPopupAuth opt-out. Docs: 06 §8.6, 12_web_ui (§1.2 + §2.3), features/01 §4.1 + Decisions. Tests: internal/api + internal/server green (-race), coverage api 95.3% / server 98.4%; node 1122/1121 (1 pre-existing live-server smoke fail, also on main); vite+esbuild green. Fixes #502.
Backend (06 §8.6): gate() answers 401 for anonymous on AuthWrite/AuthAdmin
before flag checks (defect B); ssh-keys mutations carry an explicit
anonymous check closing the defect-A leak (self-service stays AuthRead,
auth-none unaffected); apiServe asserts oidc + state-changing method +
anonymous -> 401 without invoking the handler; releases/tags requireRole
copies confirmed anonymous->401.

Client (12_web_ui §1.2 + routes): headless writeGate.js, /login-required
interstitial (action/next, OIDC return, back/cancel), per-affordance wiring
(star/watch/fork, New issue/pull, composers, reactions, all create forms),
SDK _call noPopupAuth opt-out.

Docs: 06 §8.6, 12_web_ui (§1.2 + §2.3), features/01 §4.1 + Decisions.
Sign in to join this conversation.
No description provided.