fix(security): drop wildcard CORS + redundant OPTIONS from 24 API routes (P0 #5 PARTIAL → RESOLVED) #19
No reviewers
Labels
No labels
agent-context-drift
bug
documentation
duplicate
enhancement
good first issue
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: rstillwell/deckhearth#19
Loading…
Reference in a new issue
No description provided.
Delete branch "convoy/cors-tighten"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Closes P0 #5 in
.convoys/ship-readiness.mdfrom PARTIAL → RESOLVED.fix-auth-bypassBrief 4 (commit297afca) cleaned login + register; this convoy sweeps the remaining 24pages/api/**handlers that carried the identical scaffolded wildcard-CORS + redundant-OPTIONS pattern, plus adds a blockingforbidden-cors-headersCI job to lock in the cleanup against future regression.With this merged, the only remaining P0 is #6 (rate limiting on non-auth endpoints —
add-rate-limitingconvoy).Convoy artifacts
.convoys/cors-tighten.md(architect ratified all 5 decisions self-ratifiable).convoys/cors-tighten/brief-1-sweep-wildcard-cors.mdec22b70a843736Decisions ratified (all 5 architect-self-ratifiable)
forbidden-cors-headersjob, modeled onforbidden-endpointsPattern-drift audit
Parent + architect spot-checked 14 of 24 files (zero drift). All 24 share the identical 9-11-line scaffolded block. Two safe sub-shapes:
try; deletion routes OPTIONS to the existingelse { 405 }branchBoth patterns accept the same mechanical deletion. Architect's full pattern map in
.convoys/cors-tighten/brief-1-sweep-wildcard-cors.md.Architect's most non-obvious finding
.cursor/rules/api-routes.mdcdocumentswithCollectionPermission(...)as a convention, but zeropages/api/**routes actually use it (architect grep returned empty). The stress-test concern about CORS headers being inside vs outside a permission-wrapper turned out to be moot. All 24 routes callgetUserFromRequestdirectly inside the handler body.Diff
25 files, +29 / -261. Pure deletion across 24 source files; 29 additions are the new CI job.
Precedent files explicitly untouched
pages/api/auth/login.jsandpages/api/auth/register.js(already swept by Brief 4) are byte-identical at HEAD. Architect's R7 foot-gun avoided.Verification
npm run lintnpm run test:run(vitest)git grep -nE "Access-Control-Allow-(Origin|Methods|Headers)" -- 'pages/api/**'git grep -nE "if \(req\.method === 'OPTIONS'\)" -- 'pages/api/**'ci.ymlYAML parseExpected CI behavior
forbidden-cors-headers(new job): pass (just swept; nothing to find)forbidden-endpoints(existing): pass (no change in scope)/loginand/api/healthwhich are same-origin from the Vercel preview perspective (CORS irrelevant). The login → JWT-verify flow doesn't break because the smoke spec doesn't actually submit credentials.What did NOT change
lib/**,components/**,scripts/**,test/**,package.json, lockfile,AGENTS.md,.cursor/rules/, any other workflow YAMLpages/api/auth/login.js+register.js(Brief 4's earlier sweep preserved)pages/api/auth/login.js's rate-limit gate (Brief 4) andpages/api/auth/register.js's rate-limit gate (Brief 4) — both untouchedOut of scope (deferred / flagged)
fill-vitest-handler-coverage(none of the 24 routes have vitest coverage today)add-rate-limiting(P0 #6 PARTIAL) — last remaining P0; queued for next convoyTest plan
forbidden-cors-headersjob passes (verify post-push)Made with Cursor
The latest updates on your projects. Learn more about Vercel for GitHub.
Pipeline Health
Build + CI gates
Build runs on Vercel; this CI runs lint and schema-map drift only (no duplicate build).
Role reports
See individual comments above for details. This rollup updates automatically.
Visual Diff
Screenshots and diffs uploaded as artifacts: view run
If intentional changes: update snapshots locally with
npx playwright test --project=visual --update-snapshotsand commit.