feat(system-config): proxy the public system config from both adapters - #143
Merged
Conversation
Both adapters serve routes from an explicit list, so the auth API's new GET /system-config/public is unreachable through them until it is added here. The route returns the configured loginMethods to a signed-out caller. That is what lets the bundled sign-in screens offer the methods an instance actually has enabled rather than a hardcoded guess, and lets them tell whether declining a passkey during registration would leave a user with no way back in. getPublicSystemConfigHandler forwards no identity: no authorization header and no service token, matching how upstream serves the route and how the existing public GET /oauth/providers already behaves. A signed-out browser is the expected caller, so attaching a session would only put a stale cookie in the path of the one call that client has to make. The parity suite covers the new route in both adapters, including an upstream failure passing through, and asserts neither adapter sends an identity even when a valid access cookie is present. Verified with the core, express, and fastify suites: 214, 150, and 43 passing.
Bccorb
marked this pull request as ready for review
July 31, 2026 02:54
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.
Third of four PRs adding the ability to skip passkey registration.
Draft: blocked on the auth API route (fells-code/seamless-auth-api#136), which is itself blocked on fells-code/seamless-auth-types#23. Nothing here breaks without them, the proxied route just 404s upstream until the API ships it.
Why this repo is in the chain at all
I did not expect it to be. Both adapters serve routes from an explicit allowlist, not a catch-all proxy, so a new upstream route is simply unreachable through them until it is added here. Without this PR the React SDK's call would 404 at the adapter and never reach the auth API.
What
getPublicSystemConfigHandlerin core, wired into the Express adapter'screateServerand the Fastify adapter'sauthRoutes.It forwards no identity: no authorization header, no service token. That matches how upstream serves the route and how the existing public
GET /oauth/providersalready behaves here. A signed-out browser is the expected caller, so attaching a session would only put a stale cookie in the path of the one call that client has to make.No change needed in
ensureCookies: itsCOOKIE_REQUIREMENTSmap is prefix-matched, and/system-config/publicmatches none of the existing/system-config/*entries, so it correctly falls through as ungated. Worth knowing if anyone later adds a bare/system-configentry, which would silently capture this route.Tests
Three cases added to the parity suite:
authorizationorx-seamless-service-token, asserted with a valid access cookie present, so a future refactor cannot quietly start attaching oneThat last one deliberately compares header names rather than the full header objects: Express and Fastify report the test loopback socket differently (
::ffff:127.0.0.1against127.0.0.1), which is the harness rather than anything either adapter decides.Verification
core 214 passing, express 150 passing, fastify 43 passing. All three packages build.
Next
seamless-auth-react: consume this, gate a skip control on the passkey registration screen, and drop the hardcoded method fallback.