Skip to content

CORS: allow all API methods + expose response headers for browsers#85

Merged
jwicks31 merged 1 commit into
mainfrom
claude/cors-methods
Jun 13, 2026
Merged

CORS: allow all API methods + expose response headers for browsers#85
jwicks31 merged 1 commit into
mainfrom
claude/cors-methods

Conversation

@jwicks31

Copy link
Copy Markdown
Owner

What

Make CORS browser-ready for every method the API allows (and the headers it uses). Previously the cross-origin config only set origin and leaned on @fastify/cors defaults — which don't expose ETag / X-Request-Id, so the If-Match optimistic-concurrency flow and request-id correlation silently broke for browser clients on another origin.

How

@fastify/cors is now configured explicitly:

  • methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS — every method the REST API uses, so preflight passes for writes/deletes.
  • allowedHeaders: Authorization, Content-Type, If-Match, X-Project-Id, X-User-Token, X-Request-Id — the custom request headers the API reads (project keys, identity tokens, optimistic concurrency).
  • exposedHeaders: ETag, X-Request-Id, X-RateLimit-*, Retry-After, Content-Disposition — so the SDK/browser can actually read them cross-origin.
  • maxAge: caches preflight for a day.

CORS_ORIGIN still governs which origins are allowed (open by default) — unchanged.

Verification

  • SQLite 74/74 — the CORS test now also asserts the OPTIONS preflight advertises all methods + the custom headers, and that ETag / X-Request-Id appear in Access-Control-Expose-Headers.
  • Postgres 53/53. README updated.

(Interpreted "register corps … for all methods that the API allows" as CORS — let me know if you meant something else.)

https://claude.ai/code/session_018efxvWw3MRjdtvE5xgBqya


Generated by Claude Code

The cross-origin config only set `origin` and relied on @fastify/cors defaults,
which don't expose ETag / X-Request-Id — so the If-Match optimistic-concurrency
flow and request-id correlation broke for browser clients on another origin.

Configure CORS explicitly:
- methods: GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS (every method the API uses)
- allowedHeaders: Authorization, Content-Type, If-Match, X-Project-Id, X-User-Token,
  X-Request-Id (the custom request headers the API reads)
- exposedHeaders: ETag, X-Request-Id, X-RateLimit-*, Retry-After, Content-Disposition
- maxAge: cache preflight for a day

CORS_ORIGIN still governs which origins are allowed (open by default).

Verification: 74/74 SQLite (+ the cors test now asserts the preflight allows all
methods + custom headers and that ETag/X-Request-Id are exposed), 53/53 Postgres 16.
Docs updated (README).
@jwicks31 jwicks31 merged commit 03a9fb2 into main Jun 13, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants