113 lines
8.1 KiB
Markdown
113 lines
8.1 KiB
Markdown
# WebUI Phase P — P2 Data + Auth Scratchpad
|
|
|
|
**Task ID:** WEBUI-P2
|
|
**Tracking ref:** stacked on PR #1143 (`feat/webui-p1-vite-skeleton`); no separate issue specified in the author brief
|
|
**Branch:** `feat/webui-p2-data-auth`
|
|
**Started:** 2026-08-09
|
|
**Role:** P2 author worker (must not modify `docs/TASKS.md`)
|
|
|
|
## Original tasking
|
|
|
|
> Read `/home/jwoltje/briefs/P2-brief.md` and execute it fully in `/home/jwoltje/src/stack-p1` on branch `feat/webui-p2-data-auth`. Run every listed verification gate, commit locally only, and do not push.
|
|
|
|
Container path mapping:
|
|
|
|
- Brief: `/home/jwoltje/distrobox-homes/mosaic-dev/briefs/P2-brief.md`
|
|
- Repo: `/home/jwoltje/distrobox-homes/mosaic-dev/src/stack-p1`
|
|
|
|
## Objective
|
|
|
|
Make the P1 Vite SPA authenticate against the Mosaic Gateway by same-origin relative paths, replace guest-route placeholders with real login/register/SSO callback pages, and enforce guest/authenticated route guards without modifying the parallel Next app tree except for unavoidable shared-library import fixes.
|
|
|
|
## Scope and invariants
|
|
|
|
- All SPA HTTP and Socket.IO access remains origin-relative (`/api/...`, `/api/auth/...`, `/chat`).
|
|
- No `NEXT_PUBLIC_*`, `VITE_*` origin setting, or hard-coded `http://localhost:14242` under `apps/web/src/`.
|
|
- Verify the Gateway BetterAuth mount path from source before choosing auth-client configuration.
|
|
- Delete the legacy static SSO-provider discovery module and test; runtime `/api/sso/providers` is canonical.
|
|
- Preserve the Next build while adding React Router guest pages and session guards.
|
|
- Never push; stage named files only; do not touch the modified `.mosaic/orchestrator/session.lock`.
|
|
|
|
## Plan
|
|
|
|
1. Inspect P1 SPA structure, shared libraries, legacy Next auth pages/components, Gateway auth mount, and current test setup.
|
|
2. Add/adjust tests first for relative API behavior, auth-client origin configuration, relative Socket.IO singleton behavior, and all guard session states; run focused tests and capture expected RED failures.
|
|
3. Implement shared-library relative networking and remove the legacy SSO-provider module/imports.
|
|
4. Port login, register, and provider callback pages to React Router and wire routes.
|
|
5. Implement session-aware guest/auth guards and satisfy focused tests.
|
|
6. Run focused tests, all brief verification gates, invariant searches, and an independent code/security review; remediate and re-run affected gates.
|
|
7. Update this scratchpad with evidence, stage named files only, and commit locally.
|
|
|
|
## Testing strategy
|
|
|
|
- TDD is required because this increment changes authentication/session behavior.
|
|
- Primary situational evidence: jsdom router guard state tests plus guest-page/auth-flow contract tests already present or added as needed.
|
|
- Baseline gates: web tests, Vite build, Next build, typecheck, lint, and root format check exactly as listed in the brief.
|
|
- Browser automation is not required by the brief for P2; if used, it will be headless only.
|
|
|
|
## Budget
|
|
|
|
No explicit user token cap was provided. Working soft cap: **30K tokens**, derived from a multi-file auth/frontend increment with tests, dual builds, review, and remediation. Keep implementation within the brief; no unrelated refactors or dependencies.
|
|
|
|
## Progress / evidence
|
|
|
|
- [x] Loaded mission protocol, active MVP manifest/scratchpad, top-level tasks, PRD, relevant frontend/auth/testing/type/review guides, and matching skills.
|
|
- [x] Resolved host paths to the Distrobox-mapped repo and brief.
|
|
- [x] Confirmed branch `feat/webui-p2-data-auth`, stacked at P1 commit `068d0f9b`.
|
|
- [x] Source and Gateway mount inspection complete.
|
|
- [x] RED tests observed.
|
|
- [x] Implementation complete.
|
|
- [x] Independent review complete and findings remediated.
|
|
- [x] Verification gates complete.
|
|
- [x] Local implementation commit created: `46d68e1f`.
|
|
|
|
### Source decisions
|
|
|
|
- Gateway source mounts BetterAuth at `/api/auth/` in `apps/gateway/src/auth/auth.controller.ts`; `packages/auth/src/auth.ts` configures `basePath: '/api/auth'`.
|
|
- BetterAuth 1.5.5 defaults its browser client to `/api/auth` when `baseURL` is omitted. `src/lib/auth-client.ts` therefore omits `baseURL`, preserving same-origin behavior without encoding any gateway origin.
|
|
- The only `src/app/` edit is the transitional Next provider redirect page. Deleting `src/lib/sso-providers.ts` required that mechanical consumer migration; it now uses the same runtime `/api/sso/providers` discovery and callback sanitizer as the SPA.
|
|
- GuestGuard pending behavior intentionally follows the approved brief: if no session object exists (including pending), render `<Outlet />`; only a present session redirects to `/chat`. AuthGuard alone renders the specified pending treatment.
|
|
|
|
### TDD evidence
|
|
|
|
- Initial focused run: 9 expected failures, proving absolute API/auth/socket origins, P1 guest placeholders, and missing guard redirects/loading behavior.
|
|
- After implementation: focused contract suite 15/15 passed.
|
|
- Security remediation RED: `%2F%0A%2F%2Fevil.example` reached `signIn.oauth2` as an external-normalizing callback target before the fix.
|
|
- Security remediation GREEN: shared `resolveAuthCallbackURL` unit suite 9/9 plus SPA callback regression 1/1 passed; both SPA and Next consumers use the shared helper.
|
|
|
|
### Independent review
|
|
|
|
- Primary Codex wrappers could not run because `jq` is absent; direct Codex fallback then failed authentication with HTTP 401. No review result was claimed from those attempts.
|
|
- Independent Claude Sonnet code review found no implementation-scope blocker, one pending-state UX suggestion, and one pre-existing `api.ts` type-assertion suggestion. The pending-state suggestion was rejected because it contradicts the brief's explicit GuestGuard contract; the API cleanup is outside P2's preserve-contract scope.
|
|
- Independent Claude Sonnet security review found a high-severity control-character open redirect in the callback prefix check shared by the newly ported SPA logic and transitional Next consumer.
|
|
- Remediation centralized WHATWG URL parsing plus exact current-origin comparison in `src/lib/auth-redirect.ts`, returns only path/search/hash, and added the RED-first regression above.
|
|
- Fresh code re-review: `approve`, 0 blockers, 0 should-fix findings.
|
|
- Fresh security re-review: `low`, 0 critical/high/medium/low findings.
|
|
|
|
### Documentation checklist disposition
|
|
|
|
- `docs/PRD.md` exists and P2 aligns to FR-8 / AC-7 authentication requirements.
|
|
- No Gateway endpoint, DTO, permission, or API schema changed; existing `/api/auth/*` and `/api/sso/providers` contracts are consumed unchanged, so OpenAPI/API-index updates are not applicable.
|
|
- Route paths were already present in the P1 route table; P2 replaces placeholders without changing site-map navigation, so `docs/SITEMAP.md` is unchanged.
|
|
- User/admin auth behavior is parity with the still-live Next implementation, not a new workflow. Implementation decisions, failure behavior, testing, and migration compatibility are documented here; no publishing action is in scope.
|
|
- Documentation remains in-repo; no generated publishing output was created.
|
|
|
|
### Final verification evidence
|
|
|
|
Run fresh after remediation from the locations required by the brief:
|
|
|
|
- `apps/web: pnpm test` — PASS: `Test Files 9 passed (9)`; `Tests 27 passed (27)`.
|
|
- `apps/web: pnpm build:vite` — PASS: `✓ 113 modules transformed`; `✓ built in 565ms`.
|
|
- `apps/web: pnpm build` — PASS: `✓ Compiled successfully in 4.6s`; 10/10 static pages generated; dynamic provider/project routes retained.
|
|
- `apps/web: pnpm typecheck` — PASS: `tsc --noEmit` exited 0.
|
|
- `apps/web: pnpm lint` — PASS: `eslint src` exited 0.
|
|
- Root `pnpm format:check` — PASS: `All matched files use Prettier code style!`.
|
|
- Invariant scan — PASS: no `NEXT_PUBLIC_*`, `VITE_*`, `GATEWAY_URL`, `http://localhost:14242`, or `sso-providers` references under `apps/web/src`.
|
|
- `git diff --check` — PASS.
|
|
- All six required gates above were repeated successfully after implementation commit `46d68e1f`, proving the exact committed source tree.
|
|
|
|
## Risks / blockers
|
|
|
|
- `.mosaic/orchestrator/session.lock` is modified by the active harness and must remain unstaged.
|
|
- P2 changes shared `src/lib/` modules consumed by both Vite and Next, so the Next build is a required compatibility gate.
|