Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2.3 KiB
phase, fixed_at, review_path, iteration, findings_in_scope, fixed, skipped, status
| phase | fixed_at | review_path | iteration | findings_in_scope | fixed | skipped | status |
|---|---|---|---|---|---|---|---|
| 12-initial-setup-wizard | 2026-06-15T16:46:00Z | .planning/phases/12-initial-setup-wizard/12-REVIEW.md | 3 | 1 | 1 | 0 | all_fixed |
Phase 12: Code Review Fix Report
Fixed at: 2026-06-15T16:46:00Z Source review: .planning/phases/12-initial-setup-wizard/12-REVIEW.md Iteration: 3
Summary:
- Findings in scope: 1
- Fixed: 1
- Skipped: 0
Fixed Issues
WR-01: upsertUser inserts new OIDC users with claimed=false (schema default); the TOCTOU guard queries WHERE claimed = false without oidcIss IS NULL
Files modified: apps/api/src/auth/user.ts, apps/api/src/routes/setup.ts, apps/api/tests/auth/user.test.ts, apps/api/tests/routes/setup.test.ts
Commit: 687f9dc
Applied fix: Both recommended fixes applied for defense-in-depth:
-
apps/api/src/auth/user.ts— upsertUser step 5: Addedclaimed: trueto the insert values for fresh OIDC users. An OIDC-created user is identity-bound at insert time and is never a pending wizard bootstrap user; the explicit flag prevents any future path from treating it as unclaimed. The first-login-claims path (step 2) is unaffected — it updates a pre-existingoidcIss=nullrow; this change only touches the brand-new OIDC insert path. -
apps/api/src/routes/setup.ts— TOCTOU guard in POST /credential: ChangedWHERE claimed = false FOR UPDATEtoWHERE oidc_iss IS NULL AND claimed = false FOR UPDATE. This matches the precise semantic definition of a "pending wizard bootstrap user" and is consistent with theisSetupLockedsentinel and the claim query inupsertUser. -
apps/api/tests/auth/user.test.ts: AddedWR-01unit test asserting that the fresh OIDC insert values includeclaimed: true(and thatoidcIss/oidcSubare set, distinguishing it from a wizard bootstrap row). -
apps/api/tests/routes/setup.test.ts: AddedWR-01integration test that seeds an OIDC user withclaimed=falseandoidcIss NOT NULL, then verifies POST /credential still returns 200 — confirming the narrowed guard ignores the OIDC row and only counts true wizard bootstrap rows.
Verification: All 402 API tests (29 files) and 253 PWA tests (21 files) pass. pnpm -r typecheck clean.
Fixed: 2026-06-15T16:46:00Z Fixer: Claude (gsd-code-fixer) Iteration: 3