fix(gateway): send sign-in to den-web and approve the gateway return URL without an org - #3207
Merged
Merged
Conversation
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
benjaminshafii
force-pushed
the
fix/gateway-handoff-return
branch
from
July 27, 2026 21:39
b21ef98 to
e5dcdbf
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.
Two defects found by driving the real sign-in flow against the deployed gateway. Both block sign-in entirely; neither was caught by unit tests.
1. Sign-in pointed at the gateway instead of den-web
resolveRequestBaseUrlroutes every/api/*path tobaseUrl, and gateway mode setbaseUrlto the gateway origin — but the gateway only proxies/api/den/*. Measured on the live gateway:/api/auth/get-session200 <!doctype html>200 nullSo better-auth calls received SPA HTML, and the sign-in button navigated to the gateway origin instead of the Den sign-in UI.
Now the gateway's same-origin override is scoped to the Den API only:
apiBaseUrl=<gatewayOrigin>/api/den, whilebaseUrlstays the configured Den web origin (already defaults tohttps://app.openworklabs.com). This requiredresolveDenBaseUrlsto stop forcingapiBaseUrlto be derived frombaseUrl; non-gateway callers that pass noapiBaseUrlstill derive it exactly as before. Note this is a deliberate contract change: an explicitly passedapiBaseUrlis now honored rather than ignored.Verified on the deployed gateway — the button now opens:
2. The gateway return URL could never be approved for a new user
resolveApprovedWebHandoffReturnUrlreturned early when the session had noactiveOrganizationId, before ever consultingDEN_GATEWAY_ORIGIN. That guard is right for signed preview origins, which are per-organization, butDEN_GATEWAY_ORIGINis a single operator-configured deployment constant. A freshly signed-up user has no active org yet, so sign-in through the gateway always failed with "The Cloud web handoff return URL is not approved for this organization."Reproduced end to end in production: signed up
ben+cloudgw@openworklabs.comon den-web, entered the emailed code, reached "Signed in as ..." and then hit exactly that error.The configured gateway origin is now matched independently of the org. The signed-preview path is unchanged and still requires
multi_org, an active organization, and per-org signed preview URLs. Still exact-origin only, no wildcards; unsetDEN_GATEWAY_ORIGINapproves nothing. This is safe because the origin is operator-configured rather than user input, and approving a redirect target grants nothing by itself — the Cloud gate still independently requirescapabilities.cloud === true.Why unit tests missed both
The slice-3 tests called
approveWebHandoffReturnUrlwithgatewayOriginpassed in directly, so they never exercised the wrapper that computes it. The new test asserts the wrapper approves the gateway origin withactiveOrganizationId: null, and it fails on the pre-fix code:Tests
cd apps/app && bun test --isolate tests/desktop-handoff-public-url+cloud-instance-routepnpm --filter @openwork-ee/den-gateway run testtsc --noEmit(app, den-api)Added coverage: gateway
baseUrl/apiBaseUrlsplit, auth URL origin +webAuthReturn,/api/authvs/v1request routing, gateway MCP URL, and the handoff approvals above.Not verified yet
The full signed-in journey (instance provisioning, the Cloud capability gate in the UI) is still unproven — it was blocked behind these two bugs. I am continuing that against the deployed gateway now and will post the frames.