Replaces the dev-bypass-only AuthProvider with a real backend-mediated
OIDC client. Backend ships the OIDC plumbing in
Dialectic.Backend@2463129; this SPA drives it.
Auth flow:
1. On mount: GET /api/auth/oidc/status (is OIDC configured?) + GET
/api/auth/me (who am I — reads the dialectic_session HttpOnly
cookie if present).
2. Anon + click 'login' → window.location = /api/auth/oidc/start
(backend redirects to IdP authorize URL with PKCE + state).
3. IdP returns to backend /api/auth/oidc/callback → backend redirects
here to /oidc/callback#oidc_ticket=<base64url>.
4. OidcCallbackPage POSTs the ticket to /api/auth/oidc/exchange →
backend Set-Cookie's the session JWT → refresh() AuthProvider →
navigate to /.
5. Header shows user.name + 'logout' button. Logout → POST
/api/auth/logout (cookie cleared by backend) → user state cleared.
UI changes:
- Header gets a Login button (acid primary style) when anon + OIDC
enabled; logged-in pill (name + logout) when authenticated.
- 'oidc not configured' message when backend reports
/api/auth/oidc/status enabled=false (operator needs to run
dialectic-cli config oidc first).
- Removed /agents/:id route + AgentActivity page + nav link entirely
(per user request; admin endpoint stays on backend for curl).
- Removed Link to /agents/* from TopicDetail + Verdict pages.
api.ts:
- Adds credentials:'same-origin' on every fetch so the session cookie
rides along.
- Drops the admin: opt + x-dialectic-admin-key header path (no more
AgentActivity consumer).
- Keeps dev-bypass header support gated on VITE_OIDC_DEV_BYPASS for
dev convenience — backend's OIDC_ONLY=true env disables it server-
side anyway.
types.ts: AgentSummary type removed.
Build delta: 178KB → 179KB / gzip 57.12 → 57.70 (oidc-client overhead
is just the AuthProvider polling code; no oidc-client-ts lib needed
since the backend drives the redirect flow).
Replaces the v1 CRA app (which targeted the obsolete Python Dialectic
backend) with a fresh Vite + React 18 + TypeScript scaffold that talks
to Dialectic.Backend Go v2.
Pages (all readonly — propose/signup/post are agent-only by design):
- / TopicList — filter by status, paginated
- /topics/:id TopicDetail — meta + camps + transcript
(polling every 8s)
- /topics/:id/verdict Verdict permalink (shareable)
- /agents/:id AgentActivity — admin diagnostics card
Stack:
- Vite 5 + React 18 + react-router-dom 6
- Pure ESM, NodeNext-style imports, .tsx
- Style: ~/STYLE.md tokens (IBM Plex Mono + Major Mono Display +
--acid #d8ff3e on --ink #080a0d, with subtle blueprint grid wash)
Auth:
- v1 dev-bypass only — VITE_OIDC_DEV_BYPASS auto-attaches
x-dev-bypass header. Real Keycloak OIDC redirect ships as v2.
- Admin endpoints (x-dialectic-admin-key) prompt on first visit
and store key in localStorage. Never baked into bundle. Never
sent to non-admin endpoints.
Backend pairing:
- Dialectic.Backend@0b16b52 adds GET /api/admin/agents/{id} for the
AgentActivity page. AgentActivity calls it via the admin-key
branch in api.ts.
Deploy:
- Multi-stage Dockerfile (node:22-alpine build → nginx:1.27-alpine
serve). nginx.conf reverse-proxies /api/ → dialectic-backend:8090
so the browser sees one origin (no CORS).
Reuses the existing hzhang/Dialectic.Frontend repo — old CRA contents
nuked in this commit. History preserved on master.