Commit Graph
1075 Commits
Author SHA1 Message Date
Lucas Berger 28cf79754a docs(17): add validation strategy 2026-06-18 11:19:24 -04:00
Lucas Berger f789a67f95 docs(17): research phase domain 2026-06-18 11:17:44 -04:00
Lucas Berger a1457a5b30 docs(17): UI design contract 2026-06-18 10:59:25 -04:00
Lucas Berger efeee02a36 Merge remote-tracking branch 'origin/main' into gsd/phase-17-ui-optimization-polish
# Conflicts:
#	.planning/STATE.md
2026-06-18 10:08:45 -04:00
Lucas BergerandClaude Opus 4.8 cfe84715d5 docs: add developer profile section to CLAUDE.md
Publish / publish (push) Successful in 11s
Generated by /gsd-profile-user from session analysis (8 dimensions).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 10:07:03 -04:00
luckberg 07787177d4 Update CLAUDE.md
Publish / publish (push) Successful in 11s
Added local auth
2026-06-18 07:12:17 -04:00
Lucas Berger 1e2cc52659 docs: refresh project documentation against current codebase
Publish / publish (push) Successful in 26s
2026-06-18 06:44:29 -04:00
luckberg 18d3ee6a4f Merge pull request 'Phase 19: Local Auth (No-OIDC Mode)' (#23) from gsd/phase-19-local-auth-no-oidc-mode into main
Publish / publish (push) Successful in 1m25s
Reviewed-on: #23
2026-06-18 06:24:58 -04:00
Lucas BergerandClaude Opus 4.8 b6490feff4 fix(19): satisfy CI fast-checks + secret scan
CI / changes (pull_request) Successful in 9s
CI / api (pull_request) Successful in 3m2s
CI / fast-checks (pull_request) Successful in 4m20s
CI / security (pull_request) Successful in 1m14s
CI / harness (pull_request) Successful in 6m56s
CI / gate (pull_request) Successful in 2s
Lint (eslint --max-warnings 0):
- index.ts: disable no-unsafe-argument on the type-only Context mismatch when
  delegating to the OIDC handler inside the local-session skip wrapper
- localAuth.ts: handleLogout is sync (no await) — drop async (require-await)
- devBypass.ts: disable detect-possible-timing-attacks on the public well-known
  dev-placeholder string compare (not a secret comparison)
- remove dead code / unused bindings flagged by no-unused-vars: makeTestApp
  (localSession.test), makeUnauthContext + BrowserContext import (login.spec),
  unused memberId (admin.test), unused txSelectCount counter (me.test)
- localAuthMiddleware.test / me.test: fix unused + reflow-detached
  eslint-disable directives

Format: prettier --write across the 20 Phase-19 files that were never formatted.

Secret scan (gitleaks): allowlist two false positives — the synthetic >=32-char
TEST_SECRET in localSession.test.ts, and .planning/ design prose (a generic-api-key
regex hit on "credential atomically, 409-equivalent"). Neither is a real secret.

Verified locally: format:check, lint, typecheck, md:lint, gitleaks (no leaks),
PWA 266/266, API 452/452.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 23:05:15 -04:00
Lucas Berger 91ab9d1f78 docs(19): ship phase 19 — PR #23 2026-06-17 22:49:45 -04:00
Lucas Berger abf7be782a docs(phase-19): add security threat verification (28/28 closed, threats_open: 0)
CI / changes (pull_request) Successful in 10s
CI / fast-checks (pull_request) Failing after 2m17s
CI / api (pull_request) Successful in 2m51s
CI / security (pull_request) Failing after 12s
CI / harness (pull_request) Successful in 5m9s
CI / gate (pull_request) Failing after 2s
2026-06-17 22:47:45 -04:00
Lucas Berger f3af130e9e docs(17): add workstream D — 4 UI findings from Phase 19 UAT (logout button, admin feedback, popup centering, admin nav) 2026-06-17 22:34:18 -04:00
Lucas Berger af0a70ccec test(19): complete UAT — Tests 1-3 pass live, 4 resolved-by-fix, 5→ship; 4 UI findings routed to Phase 17 2026-06-17 22:32:52 -04:00
Lucas Berger 73dd6a2383 docs(19): re-review after fixes — status clean (0 critical/warning, 2 info) 2026-06-17 20:50:25 -04:00
Lucas Berger 9cccf17ef9 chore: enable MemPalace discuss-time recall + KG mirror 2026-06-17 20:45:39 -04:00
Lucas Berger 5f74ae965d docs(19): add code review fix report 2026-06-17 20:42:51 -04:00
Lucas Berger cef2c66de5 merge(19): land code-review fixes (CR-01..04, BL-01..04, WR-01..07, IN-01..04) 2026-06-17 20:39:49 -04:00
Lucas Berger 2691dd0f95 fix(19): IN-04 enforce single-use OIDC-link nonce to prevent state replay 2026-06-17 20:37:09 -04:00
Lucas Berger 83e23d760d docs(state): record phase 17 context session 2026-06-17 20:37:02 -04:00
Lucas Berger 3784762817 docs(17): capture phase context (layout polish + branding + theme groundwork; dark mode/styling deferred) 2026-06-17 20:37:02 -04:00
Lucas Berger f02521dd02 fix(19): IN-03 evict stale loginAttempts entries to bound in-memory map growth 2026-06-17 20:35:43 -04:00
Lucas Berger e392bf2eb7 fix(19): IN-02 add lockstep test pinning inlined scrypt params against canonical verifyPassword 2026-06-17 20:34:58 -04:00
Lucas Berger f2fc1404d4 fix(19): IN-01 validate LOCAL_SESSION_EXPIRES coercion (fallback on NaN/non-positive) 2026-06-17 20:34:14 -04:00
Lucas Berger 916fb34f17 docs: add backlog items 999.20 (dark mode/theming) + 999.21 (styling refresh) 2026-06-17 20:34:02 -04:00
Lucas Berger 4bd6b2c057 fix(19): WR-05 add no-echo tests for admin create-member and me password hook sites 2026-06-17 20:33:46 -04:00
Lucas Berger 32bdd1e92d fix(19): WR-07 reject route ids with trailing garbage via strict integer parse 2026-06-17 20:32:26 -04:00
Lucas Berger 4cf2ad4bff fix(19): WR-06 stop sliding the rate-limit cooldown window on rejected attempts 2026-06-17 20:31:07 -04:00
Lucas Berger 30ad25c026 fix(19): WR-03 make scrypt hashing async (threadpool) to avoid event-loop starvation DoS 2026-06-17 20:30:28 -04:00
Lucas Berger 322929aebe fix(19): WR-02+WR-04 centralize OIDC config (env-or-app_config) and discover auth endpoint 2026-06-17 20:26:47 -04:00
Lucas Berger c4d8d76a4c fix(19): WR-01 parse reset-admin flags explicitly and stop echoing username 2026-06-17 20:25:18 -04:00
Lucas Berger 40666e1cc5 fix(19): BL-04 keep context oidcIss/oidcSub null for local users (no fabricated identity sentinels) 2026-06-17 20:24:01 -04:00
Lucas Berger 71537601ce fix(19): BL-03 reject OIDC-link bind on empty iss/sub or mismatched local session (takeover guard) 2026-06-17 20:22:37 -04:00
Lucas Berger cd095e5b67 fix(19): BL-02 match Secure attribute on logout cookie deletion to issue-time logic 2026-06-17 20:21:51 -04:00
Lucas Berger 3674b255b2 fix(19): BL-01 enforce LOCAL_SESSION_SECRET length floor in devSessionCookieMiddleware 2026-06-17 20:21:17 -04:00
Lucas Berger b083cb7193 fix(19): CR-04 scope login lockout to username, add TTL auto-expiry + admin-reset unlock 2026-06-17 20:20:43 -04:00
Lucas Berger 6ef8e03f8c fix(19): CR-03 return 403 for wrong current password so change-password does not log user out 2026-06-17 20:17:32 -04:00
Lucas Berger 93c47b38aa fix(19): CR-02 send initialPassword + map 409 conflict in fetchCreateMember 2026-06-17 20:15:58 -04:00
Lucas Berger 1688f229e0 fix(19): CR-01 align OIDC-link client contract with server (authorizationUrl) 2026-06-17 20:15:23 -04:00
Lucas BergerandClaude Opus 4.8 46eaf070ea chore: enable MemPalace for project and ignore per-project files
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:12:50 -04:00
Lucas Berger 4b635784e4 docs(19): add code review report 2026-06-17 20:08:26 -04:00
Lucas Berger 37fd896ce9 docs(phase-19): mark phase complete (verification passed, 5/5 plans) 2026-06-17 20:00:21 -04:00
Lucas Berger 0aca22f743 docs(19): verification passed (21/21) after blocker fix; UAT for live/CI items 2026-06-17 20:00:00 -04:00
Lucas BergerandClaude Opus 4.8 53da4be62b fix(19): correct admin reset-password client URL (AUTH-LOCAL-08 blocker)
VERIFICATION.md found a cross-layer URL mismatch: fetchAdminResetPassword
POSTed to /api/admin/members/:id/reset-password but the API registers the
route as /api/admin/members/:id/password (admin.ts), so the Admin reset sheet
404'd on every submit. Confirmed live: old path -> 404, correct path -> 400
(route reached). Unit tests missed it because API tests hit the real path
directly and PWA tests mock the fetcher — no test crossed both layers.

Fix the client URL and add a URL-contract regression test that pins the exact
path (asserts fetch is called with /api/admin/members/:id/password).

PWA 266/266 (+1), typecheck clean.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 19:58:17 -04:00
Lucas Berger 9b10d875d4 docs(phase-19): update tracking after wave 4 2026-06-17 17:44:10 -04:00
Lucas BergerandClaude Opus 4.8 17a531550a fix(19): resolve post-merge wave-4 harness integration gaps
Two issues surfaced only when plans 19-04 (login UI) and 19-05 (Option C
bypass + login.spec) were merged together and run against the real stack —
neither executor could catch them in isolation:

1. LOCAL_SESSION_SECRET was added to the CI harness (ci.yml) but not to the
   local dev stack (docker-compose.dev.yml). Without it the real-login success
   path (POST /api/auth/local/login) 503s when signing the session cookie, so
   the e2e round-trip failed. Add the same fixed dev-only value to the dev
   compose override (dev-only target; never a production secret).

2. login.spec test 1 assumed clearing the local-session cookie yields a
   logged-out state, but under the always-on DEV_AUTH_BYPASS devAuthBypass()
   injects DEV_USER into /api/me regardless of any cookie — a logged-out state
   is architecturally unreachable in this bypass-only harness. Reframe the test
   to drive /login directly (validating the real-browser render of all brand +
   form surfaces) and move the unauthenticated root->/login redirect-gate
   coverage to a unit test in App.test.tsx where meQuery.isError is controllable.

Result: API 446/446, PWA 265/265 (+2 gate tests), e2e desktop 42 passed / 3
skipped (all login specs green).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 17:43:11 -04:00
Lucas Berger 11977fddf4 chore: merge executor worktree (worktree-agent-ad5628ea37541e256) 2026-06-17 17:28:49 -04:00
Lucas Berger c7142b5fe5 chore: merge executor worktree (worktree-agent-a71adf90ed21b044c) 2026-06-17 17:28:48 -04:00
Lucas Berger 63beb74650 docs(19-04): complete PWA login UI + account management surfaces plan 2026-06-17 17:26:07 -04:00
Lucas Berger eba0bb095d docs(19-05): complete dev-bypass rework + harness + CI plan (checkpoint) 2026-06-17 17:22:39 -04:00
Lucas Berger 19c45eb069 feat(19-04): AdminPage LOCAL ACCOUNTS + SettingsSheet change-password / link-OIDC
- Add hasLocalCredential to AdminMember type (mirrors API extension from plan 19-02)
- Add createMember mutation + Surface 11A inline add-member form in AdminPage
- Add Surface 11B Reset-password button in MemberRow (hasLocalCredential gate)
- Add ResetPasswordSheet component (bottom-sheet, role=dialog, focus-managed, Escape closes)
- Add Surface 12 Change-password row in SettingsSheet (hasLocalCredential gate)
- Add Surface 13 Link-OIDC identity row in SettingsSheet (hasLocalCredential + oidcEnabled gate)
- Add ChangePasswordSheet component (current/new/confirm fields, change-password mutation)
- Add LinkOidcSheet component (confirmation dialog; uses generic OIDC copy per D-06, no provider branding)
- Fix: update InstructionSheet.test.tsx to wrap with QueryClientProvider (Rule 1 - now uses useQuery)
- Fix: remove stale eslint-disable in App.test.tsx (lint --max-warnings 0 would fail)
- All 263 tests pass; typecheck clean; lint clean
2026-06-17 17:21:20 -04:00