Skip to content

fix(web/ee): load identity provider config once in getLinkedAccounts - #1602

Closed
Harsh23Kashyap wants to merge 1 commit into
sourcebot-dev:mainfrom
Harsh23Kashyap:fix/linked-accounts-n-plus-one-config-reload
Closed

Harsh23Kashyap wants to merge 1 commit into
sourcebot-dev:mainfrom
Harsh23Kashyap:fix/linked-accounts-n-plus-one-config-reload

Conversation

@Harsh23Kashyap

@Harsh23Kashyap Harsh23Kashyap commented Aug 17, 2026 •

Copy link
Copy Markdown

Summary

getLinkedAccounts called getIdentityProviderConfig(account.providerId) inside a for-loop over the user's linked accounts. Each call internally re-invokes getIdentityProviderConfigs (in packages/shared/src/env.server.ts), which re-reads the config file from disk (or re-fetches the remote config URL) and re-validates it with ajv on every iteration.

A user with N linked accounts triggered N full config reads on every call to getLinkedAccounts, plus one more read from the second loop in the same function. With a 50 KB config file and 5 linked accounts, that is 5 × 50 KB of disk reads + 5 × JSON.parse + 5 × ajv schema validation per settings-page load. The retry-on-ENOENT logic in loadConfig (5 attempts × 2 s delay) also amplified the worst-case latency when the config file was being mounted.

Hoist the getIdentityProviderConfigs() call to once before the first loop, mirror the pattern already used by the second loop, and use a synchronous object lookup per account. The second loop now reuses the same map.

Validation

  • yarn workspace @sourcebot/web test --run src/ee/features/sso/actions.test.ts → 6 passed (4 pre-existing + 2 new)
  • yarn workspace @sourcebot/web test --run → 1168 passed (same 7 pre-existing @opentelemetry/sdk-trace-base suite-load failures as upstream/main)
  • yarn workspace @sourcebot/web lint → clean
  • yarn workspace @sourcebot/web exec tsc --noEmit → 0 new errors introduced (the existing withAuth.ts SCOPED_ACCESS_TOKEN_PREFIX / scopedAccessToken errors are pre-existing on upstream/main@39b5953b and unrelated to this PR)

Test plan

  • yarn workspace @sourcebot/web test --run src/ee/features/sso/actions.test.ts (6 passed: 4 pre-existing + 2 new)
  • yarn workspace @sourcebot/web test --run (1168 passed; same 7 pre-existing suite-load failures as upstream/main)
  • yarn workspace @sourcebot/web lint (0 errors)
  • npx tsc --noEmit -p packages/web/tsconfig.json (0 new errors)

Fixes #1601


Note

Cursor Bugbot is generating a summary for commit c5cf7a2. Configure here.

Summary by CodeRabbit

  • Bug Fixes
    • Improved the display and handling of linked sign-in accounts.
    • Ensured available account-linking providers are included alongside existing linked accounts.
    • Preserved account ordering and provider details for a consistent experience.
    • Improved consistency when multiple linked accounts use identity-provider configurations.

`getLinkedAccounts` called `getIdentityProviderConfig(account.providerId)` inside a
for-loop over the user's linked accounts. Each call internally re-invokes
`getIdentityProviderConfigs` (in `packages/shared/src/env.server.ts`), which
re-reads the config file from disk (or re-fetches the remote config URL) and
re-validates it with ajv on every iteration.

A user with N linked accounts triggered N full config reads on every call to
`getLinkedAccounts`, plus one more read from the second loop in the same
function. With a 50 KB config file and 5 linked accounts, that is 5 x 50 KB
of disk reads + 5 x JSON.parse + 5 x ajv schema validation per settings-page
load. The retry-on-`ENOENT` logic in `loadConfig` (5 attempts x 2 s delay)
also amplified the worst-case latency when the config file was being mounted.

Hoist the `getIdentityProviderConfigs()` call to once before the first loop,
mirror the pattern already used by the second loop, and use a synchronous
object lookup per account. The second loop now reuses the same map.

Other call sites of `getIdentityProviderConfig` are single-call
(`backend/src/ee/accountPermissionSyncer.ts:292`,
`backend/src/ee/tokenRefresh.ts:213`,
`web/src/lib/encryptedPrismaAdapter.ts:31`) and are not in a loop, so the
N+1 does not apply to them. They are out of scope here.

Add two vitest cases to `actions.test.ts`:
- one that exercises the merge of linked and unlinked account_linking
  providers and pins the result shape, and
- one that asserts `getIdentityProviderConfigs` is called exactly once for
  five linked accounts (regression for the N+1).

Fixes #1601
@coderabbitai

coderabbitai Bot commented Aug 17, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: bf31a467-a710-496e-8b48-ef5a54297559

📥 Commits

Reviewing files that changed from the base of the PR and between 39b5953 and c5cf7a2.

📒 Files selected for processing (2)
  • packages/web/src/ee/features/sso/actions.test.ts
  • packages/web/src/ee/features/sso/actions.ts

Included review availability: Your plan includes up to 8 reviews per rolling hour; 7 remain after this review.


Walkthrough

getLinkedAccounts now loads identity-provider configurations once per invocation and reuses them while processing linked and unlinked providers. Tests cover merged account output, metadata, ordering, and a single configuration load for multiple linked accounts.

Changes

Linked account configuration reuse

Layer / File(s) Summary
Reuse provider configurations
packages/web/src/ee/features/sso/actions.ts
getLinkedAccounts loads the provider configuration map once, uses synchronous lookups for linked accounts, and reuses the map for unlinked providers.
Validate account behavior
packages/web/src/ee/features/sso/actions.test.ts
Tests verify merged account metadata, ordering, linked-provider state, and one configuration load for multiple accounts.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Merge Risk: ⚪ Minimal · up to c5cf7

This localized change reuses the identity-provider configuration during linked-account processing, reducing repeated config reads and validation without introducing an actionable merge-blocking risk; it is merge-ready after normal checks and review.

Suggested reviewers: brendan-kellam

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: loading identity provider configuration once in getLinkedAccounts.
Linked Issues check ✅ Passed The changes satisfy issue #1601 by loading configuration once, preserving account behavior, and adding regression tests.
Out of Scope Changes check ✅ Passed The changes are limited to the web/EE call site and related tests, with no unrelated or global configuration changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

perf(web/ee): getLinkedAccounts reloads the entire config file for each linked account

2 participants