Repository navigation
Offer the first app for the workspace picked on the server picker - #1449
Merged
Merged
Conversation
A user in several workspaces who picks an empty one on "Choose what to connect" now gets the first-connector page for that workspace, and the page (and POST /auth/first-app) use the workspace granted to the client instead of the user's primary organization. The Etsy app-pending panel no longer claims the app is unapproved: Etsy answers the same 403 for a wrong shared secret of an active app.
helpcodeai
enabled auto-merge (squash)
November 2, 2026 12:51
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
What and why
Two problems seen in an end-to-end test on Cloud after #1440 and #1441.
1. Post-approve page after "Choose what to connect"
A user in several workspaces gets the "Choose what to connect" picker. If they picked an empty workspace where they are ADMIN or EDITOR, they went straight back to the client and never saw the first-connector page. There were two reasons:
POST /auth/select-serversalways redirected to/callback. Only the no-picker path calledmaybeOfferFirstConnector.maybeOfferFirstConnectorcounted connectors and checked the role inusers.organizationId(the primary workspace), not in the workspace granted to this client.Changes in
packages/backend/src/auth/login.controller.ts:grantedWorkspace(clientId, userId, fallback). It resolves the one workspace this connection reaches, the same way the shared endpoint does:users.organizationId;none, or servers spread over several workspaces, gives null. With no single workspace, nothing is offered.maybeOfferFirstConnectoruses that workspace for the connector count, the role check, the trial lookup and the product event.handleServerSelectioncallsmaybeOfferFirstConnectorafter a valid selection. It falls back to the old redirect when there is nothing to offer. The CSRF check and the signedpending_grantidentity check stay in front of it, unchanged.continueWith=dashboard links) is kept across the picker. It travels in a signed, httpOnlypending_grant_socialcookie and is checked against the enabled providers when read.POST /auth/first-appresolves the org through the same helper, so the app is installed into the workspace the page was offered for. The connector still lands on the granted servers of that workspace. Its CSRF cookie check, the signedlogin_usercheck, the pending-authorization check and the role/plan checks (canSetUp) are unchanged. One behaviour change: a grant whose servers span two workspaces now answers 403 ("page expired") instead of installing into the first server's workspace. The page is never offered for such a grant.Single-workspace behaviour does not change. The picker is not shown there, the silent grant points at the user's own workspace, and the helper resolves to that workspace as before.
Cloud / self-hosted: the first-connector page and
/auth/first-appstay Cloud-only (isCloud()guards, unchanged). On self-hosted, the picker submission still redirects straight to/callback. A spec covers this.2. Etsy "app pending" panel
Etsy returns the same 403 for an app that is still Pending and for an active app with a wrong shared secret. The panel's headline said " has not approved your app yet", which is wrong in the second case. The headline is now neutral and the body covers both cases:
The backend
appPendingflag and the EtsyverifyHints["403"]already name both cases, so no logic changes. Only the comments oncheckAppKeysand on theappPendingtype inapi.tsnow say the flag means "maybe pending". The Playwright test inconnector-guided-setup.spec.tsasserts the new text.Not changed: the guided setup's "Wait for Etsy's approval" step (
connectorGuide, "Etsy has not approved your app yet"). It already has its own "Already approved, but this still waits" path back to the keys.Cloud cherry-pick note: the Cloud branch has no i18n, and its
page.tsxstill has the old English strings inline. A cherry-pick of this PR there must put the new English title and body inline inpackages/frontend/src/app/connectors/setup/[slug]/page.tsxinstead of the message files.Tests
New specs in
packages/backend/src/auth/login.controller.spec.ts:organizationId./callback./callback.first-appinstalls into the granted workspace, not the primary one. It falls back to the user's own workspace when there is no grant. It refuses anonegrant and a grant spanning two workspaces.Commands run
packages/backendnpx jest --maxWorkers=2 src/auth/login.controller src/auth/server-pickerpackages/backendnpx eslint src/auth/login.controller.ts src/auth/login.controller.spec.ts src/adapters/adapters.service.tspackages/backendnpx tsc --noEmit -p tsconfig.jsonbasic-ftp,ssh2,@aws-sdk/client-s3,picomatchtypes) from a stale localnode_modules, not from this changepackages/backendnpx jest src/adapters/adapters.service.specnode_modulespicomatchtyping error (only a comment changed in that file); left to CIpackages/frontendnpx tsc --noEmit -p tsconfig.jsonpackages/frontendnpx eslint src/lib/api.ts tests/e2e/connector-guided-setup.spec.tspackages/frontendnpx playwright test tests/e2e/connector-guided-setup.spec.tsnext devdid not start in this worktree (missing.nextbuild manifest); left to CInode scripts/validate-adapters.mjsnode --test scripts/validate-adapters.test.mjs scripts/adapter-new.test.mjs scripts/generate-llms-txt.test.mjsnode --test scripts/satellites/satellites.test.mjsnode scripts/adapter-count.mjs --checknode scripts/generate-llms-txt.mjs --checknode scripts/regenerate-catalog.mjsNo
ee/change.