Skip to content

Commit bbaf32e

Browse files
committed
fix(salesforce): send reauthorize to the server that issued the credential
"Update access" derived its provider from the service id, which always yields the primary authorization server. A sandbox credential missing a scope sent the user to login.salesforce.com — where a sandbox-only user cannot sign in at all, and where a user who can sign in creates an orphan production account while the banner never clears. Both credential selectors now pass the selected credential's own provider id, which the connect modal already honours. Also names the alternate provider ids explicitly in the disconnect sweep. That branch is unreachable today (every caller sends an accountId), but it was catching them only by the `{base}-` prefix accident.
1 parent 5f408cc commit bbaf32e

3 files changed

Lines changed: 16 additions & 1 deletion

File tree

apps/sim/app/api/auth/oauth/disconnect/route.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { getSession } from '@/lib/auth'
1010
import { generateRequestId } from '@/lib/core/utils/request'
1111
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
1212
import { deleteCredential } from '@/lib/credentials/deletion'
13+
import { providerIdsForService } from '@/lib/oauth/utils'
1314
import { captureServerEvent } from '@/lib/posthog/server'
1415

1516
export const dynamic = 'force-dynamic'
@@ -61,7 +62,13 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
6162
? and(eq(account.userId, session.user.id), eq(account.providerId, providerId))
6263
: and(
6364
eq(account.userId, session.user.id),
64-
or(eq(account.providerId, provider), like(account.providerId, `${provider}-%`))
65+
or(
66+
// The prefix sweep already caught `{base}-{feature}` ids by
67+
// accident; an alternate authorization server shares that shape,
68+
// so name it explicitly rather than relying on the accident.
69+
inArray(account.providerId, providerIdsForService(provider)),
70+
like(account.providerId, `${provider}-%`)
71+
)
6572
)
6673

6774
const targetAccounts = await db.select({ id: account.id }).from(account).where(accountFilter)

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/credential-selector/credential-selector.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,10 @@ export function CredentialSelector({
508508
requiredScopes={getCanonicalScopesForProvider(effectiveProviderId)}
509509
newScopes={missingRequiredScopes}
510510
serviceId={serviceId}
511+
// A reauthorize must return to the authorization server that issued
512+
// the credential — deriving it from the service id would send a
513+
// sandbox user to production, where they cannot sign in at all.
514+
providerId={selectedCredential?.provider ?? effectiveProviderId}
511515
/>
512516
)}
513517

apps/sim/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/tool-input/components/tools/credential-selector.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,10 @@ export function ToolCredentialSelector({
292292
requiredScopes={getCanonicalScopesForProvider(effectiveProviderId)}
293293
newScopes={missingRequiredScopes}
294294
serviceId={serviceId}
295+
// A reauthorize must return to the authorization server that issued
296+
// the credential — deriving it from the service id would send a
297+
// sandbox user to production, where they cannot sign in at all.
298+
providerId={selectedCredential?.provider ?? effectiveProviderId}
295299
/>
296300
)}
297301
</div>

0 commit comments

Comments
 (0)