fix(firebaseauth): send CORS headers on the emulator endpoints and always vary on Origin - #186
Open
ianpardal wants to merge 3 commits into
Open
fix(firebaseauth): send CORS headers on the emulator endpoints and always vary on Origin#186ianpardal wants to merge 3 commits into
ianpardal wants to merge 3 commits into
Conversation
|
| Filename | Overview |
|---|---|
| src/main/java/io/floci/gcp/services/firebaseauth/FirebaseAuthCorsRouteFilter.java | Extends existing CORS behavior to emulator routes and makes origin variance unconditional. |
| src/test/java/io/floci/gcp/services/firebaseauth/FirebaseAuthCorsRestIntegrationTest.java | Verifies CORS headers for emulator preflight and deletion requests, plus unconditional origin variance. |
Reviews (3): Last reviewed commit: "style(firebaseauth): drop the Vary comme..." | Re-trigger Greptile
…ints `FirebaseAuthEmulatorController` is browser-callable from the Emulator UI, but `/emulator/v1` was missing from the CORS route filter's prefixes, so its preflight came back without any `Access-Control-*` headers. firebase-tools' Auth Emulator installs its CORS middleware globally, ahead of every route registration, so its own `/emulator/v1` routes answer preflights the same way the Identity Toolkit ones do.
The filter returned early on a missing `Origin` and emitted no headers at all, so an origin-less response was cacheable as if it were origin-independent. A shared cache could then serve it — stripped of `Access-Control-Allow-Origin` — to a browser request that did carry an `Origin`, and the browser would block it. expressjs/cors, which firebase-tools' Auth Emulator uses, adds `Vary: Origin` unconditionally: only the header *value* is dropped when there is no origin to reflect, never the `Vary` that describes the negotiation.
ianpardal
force-pushed
the
fix/firebaseauth-cors-followups
branch
from
September 7, 2026 09:18
0bda5ea to
69cd262
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The two follow-ups from the review on #153, both in
FirebaseAuthCorsRouteFilter. One PR rather than two, since they land in the same 20-line file and its test — one commit each so they still read separately.1.
/emulator/v1now sends CORS headers.FirebaseAuthEmulatorController(DELETE /emulator/v1/projects/{project}/accounts) is browser-callable from the Emulator UI, but the prefix was missing fromPATH_PREFIXES, so its preflight came back with noAccess-Control-*headers at all. firebase-tools' Auth Emulator installscors({ origin: true })withapp.use(...)ahead of every route registration (server.ts#L137), so/emulator/v1is covered there for the same reason the Identity Toolkit paths are.2.
Vary: Originis now unconditional. The filter returned early on a missingOriginand emitted nothing, so an origin-less response was cacheable as if it were origin-independent. A shared cache could then hand that response — with noAccess-Control-Allow-Originon it — to a browser request that did carry anOrigin, and the browser would block it. Inexpressjs/cors,configureOriginpushesVary: Originunconditionally andapplyHeadersonly drops falsy header values, soAccess-Control-Allow-Origin: undefineddisappears while theVarydescribing the negotiation stays (lib/index.js#L64-L71, #L232-L246).Follow-up to #153 (review)
Type of change
fix:)feat:)feat!:orfix!:)GCP Compatibility
Both changes were read off the
expressjs/cors@2.8.5andfirebase-toolssources linked above, which is the same reference #153 was built against.Verified in a packaged build with curl:
OPTIONS /emulator/v1/projects/p/accountswith anOrigin→204carryingAccess-Control-Allow-Origin,-Allow-Methods,-Allow-HeadersandVary: Origin, Access-Control-Request-Headers; the actualDELETEcarriesAccess-Control-Allow-OriginandVary: Origin.POST /identitytoolkit.googleapis.com/v1/accounts:signUpwith noOrigin→ still200, still noAccess-Control-Allow-Origin, now withVary: Origin.One deliberate divergence left in place, since it is outside what the review asked for:
expressjs/corsanswers an origin-lessOPTIONSwith its own204, whereas this filter still falls through to Quarkus' automatic-OPTIONS routing. A browser never sends a preflight without anOrigin, and absorbing everyOPTIONSon these three prefixes atInteger.MIN_VALUE + 1is exactly the app-wide preflight absorption #153 removed fromGcsCorsFilter. Happy to take it in a further PR if you'd rather match byte-for-byte.Checklist
./mvnw testpasses locally (969 tests, 0 failures)