-
Notifications
You must be signed in to change notification settings - Fork 169
feat(account-linked): Add ability to link external accounts #595
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
…th_provider_config
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR introduces comprehensive identity provider configuration support for multiple authentication types (GitHub, GitLab, Google, Okta, Keycloak, Microsoft Entra ID, GCP IAP), renames the GitHub App type discriminator from "githubApp" to "github" across schemas and code, implements permission-syncing features with UI components and server actions for linking/unlinking integration accounts, and refactors the provider metadata system with new types and schemas. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Layout as App Layout
participant Action as getIntegrationProviderStates()
participant DB as Prisma DB
participant LinkUI as LinkAccounts Component
User->>Layout: Access app (has permission-syncing entitlement)
Layout->>Action: Fetch provider states
Action->>DB: Query identity provider configs & linked accounts
DB-->>Action: Provider configs + user linked accounts
Action-->>Layout: IntegrationIdentityProviderState[]
alt Any provider unlinked
Layout->>LinkUI: Render LinkAccounts prompt
LinkUI->>User: Show required/optional providers to link
User->>LinkUI: Click "Connect" on provider
LinkUI->>User: Redirect to OAuth flow (signIn)
else All required providers linked
Layout->>User: Proceed to normal app flow
end
sequenceDiagram
participant JWT as JWT Callback
participant Token as tokenRefresh Module
participant OAuth as OAuth Provider
participant DB as Prisma DB
JWT->>JWT: Linking integration provider & permission-syncing enabled
JWT->>JWT: Store tokens in token.integrationTokens
JWT->>Token: refreshIntegrationTokens(currentTokens, userId)
loop For each provider
Token->>Token: Check if token close to expiry (5min buffer)
alt Token needs refresh
Token->>OAuth: POST refresh token request
OAuth-->>Token: New accessToken, refreshToken, expiresAt
Token->>DB: Persist refreshed tokens
Token->>Token: Update in-memory token map
else Token valid
Token->>Token: Keep existing token
end
end
Token-->>JWT: Updated IntegrationTokensMap
JWT->>JWT: Return token with refreshed integrationTokens
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes
Possibly related PRs
Suggested labels
Suggested reviewers
Pre-merge checks and finishing touches✅ Passed checks (2 passed)
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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
|
||
| if (hasEntitlement("permission-syncing")) { | ||
| const integrationProviderStates = await getIntegrationProviderStates(); | ||
| if (isServiceError(integrationProviderStates)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can probably just throw new ServiceErrorException
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's displayed in the UI if we just throw in the layout.tsx?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/web/src/auth.ts (1)
57-142: Fix provider list mutation before it duplicates entries.
providerspoints directly at the module-leveleeIdentityProviders; every invocation ofgetProviders()mutates that shared array, so the email/credentials providers are appended over and over. This quickly yields duplicate provider entries on the sign-in page and in downstream logic. Clone the array before pushing extras so the EE list stays immutable at module scope.- const providers: IdentityProvider[] = eeIdentityProviders; + const providers: IdentityProvider[] = [...eeIdentityProviders];
♻️ Duplicate comments (3)
CHANGELOG.md (1)
24-25: Remove duplicate "Removed" section.This duplicates the entry at lines 21–22. Keep only one instance.
Apply this diff to remove the duplicate lines:
- Removed built-in secret manager. [#592](https://github.com/sourcebot-dev/sourcebot/pull/592) - -## Removed -- Removed built-in secret manager. [#592](https://github.com/sourcebot-dev/sourcebot/pull/592) -Result (lines 21–23 should be):
## Removed - Removed built-in secret manager. [#592](https://github.com/sourcebot-dev/sourcebot/pull/592)docs/snippets/schemas/v3/app.schema.mdx (1)
11-11: Documentation update reflects schema discriminator change.This documentation snippet reflects the same discriminator change from
"githubApp"to"github"that was reviewed inschemas/v3/app.json. See the verification script in that review.Also applies to: 73-73
packages/web/src/ee/features/sso/sso.ts (1)
77-104: Prevent duplicate provider registration when configs exist.We still append the legacy env-based providers even after loading
identityProvidersfrom config. If an operator defines a provider in config but leaves the same env vars set (e.g.,AUTH_EE_GITHUB_CLIENT_ID), we register two providers with the sameid, which breaks NextAuth’s provider map (last one wins, callbacks become unpredictable). Please gate the legacy path so it only runs whenidentityProvidersis absent/empty.- // @deprecate - if (env.AUTH_EE_GITHUB_CLIENT_ID && env.AUTH_EE_GITHUB_CLIENT_SECRET) { + if (identityProviders.length === 0 && env.AUTH_EE_GITHUB_CLIENT_ID && env.AUTH_EE_GITHUB_CLIENT_SECRET) { providers.push({ provider: createGitHubProvider(env.AUTH_EE_GITHUB_CLIENT_ID, env.AUTH_EE_GITHUB_CLIENT_SECRET, env.AUTH_EE_GITHUB_BASE_URL), purpose: "sso" }); }Repeat the same guard for the other legacy blocks so we only fall back when config is unused.
🧹 Nitpick comments (2)
packages/web/src/ee/features/permissionSyncing/components/providerInfo.tsx (1)
13-22: Consider removing the unnecessary Fragment wrapper.The Fragment wrapper on Lines 14 and 21 is unnecessary since you're returning only a single
divelement. You can simplify the code by returning thedivdirectly.Apply this diff:
return ( - <> - <div className="flex items-center gap-2"> - <span className="text-sm font-medium text-foreground"> - {providerInfo.displayName} - </span> - {showBadge && <ProviderBadge required={required} />} - </div> - </> + <div className="flex items-center gap-2"> + <span className="text-sm font-medium text-foreground"> + {providerInfo.displayName} + </span> + {showBadge && <ProviderBadge required={required} />} + </div> );packages/web/src/ee/features/permissionSyncing/components/linkAccounts.tsx (1)
20-30: Consider providing user feedback on errors.When the skip action fails (Line 25), the error is only logged to the console. Users have no indication that the operation failed. Consider adding a toast notification or other UI feedback mechanism to inform users of errors.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (45)
CHANGELOG.md(1 hunks)docs/snippets/schemas/v3/app.schema.mdx(2 hunks)docs/snippets/schemas/v3/authProvider.schema.mdx(1 hunks)docs/snippets/schemas/v3/identityProvider.schema.mdx(1 hunks)docs/snippets/schemas/v3/index.schema.mdx(3 hunks)packages/backend/src/ee/githubAppManager.ts(1 hunks)packages/schemas/src/v3/app.schema.ts(2 hunks)packages/schemas/src/v3/app.type.ts(1 hunks)packages/schemas/src/v3/authProvider.schema.ts(1 hunks)packages/schemas/src/v3/authProvider.type.ts(1 hunks)packages/schemas/src/v3/identityProvider.schema.ts(1 hunks)packages/schemas/src/v3/identityProvider.type.ts(1 hunks)packages/schemas/src/v3/index.schema.ts(3 hunks)packages/schemas/src/v3/index.type.ts(4 hunks)packages/shared/src/utils.ts(1 hunks)packages/web/src/app/[domain]/layout.tsx(3 hunks)packages/web/src/app/[domain]/settings/layout.tsx(3 hunks)packages/web/src/app/[domain]/settings/permission-syncing/page.tsx(1 hunks)packages/web/src/app/components/authMethodSelector.tsx(2 hunks)packages/web/src/app/invite/page.tsx(3 hunks)packages/web/src/app/login/components/loginForm.tsx(1 hunks)packages/web/src/app/login/page.tsx(2 hunks)packages/web/src/app/onboard/page.tsx(2 hunks)packages/web/src/app/signup/page.tsx(2 hunks)packages/web/src/auth.ts(5 hunks)packages/web/src/ee/features/permissionSyncing/actions.ts(1 hunks)packages/web/src/ee/features/permissionSyncing/components/integrationProviderCard.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/linkAccounts.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/linkButton.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/linkedAccountsSettings.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/providerBadge.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/providerIcon.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/providerInfo.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/components/unlinkButton.tsx(1 hunks)packages/web/src/ee/features/permissionSyncing/tokenRefresh.ts(1 hunks)packages/web/src/ee/features/permissionSyncing/types.ts(1 hunks)packages/web/src/ee/features/sso/sso.ts(1 hunks)packages/web/src/features/chat/actions.ts(3 hunks)packages/web/src/initialize.ts(1 hunks)packages/web/src/lib/authProviders.ts(0 hunks)packages/web/src/lib/constants.ts(1 hunks)packages/web/src/lib/identityProviders.ts(1 hunks)schemas/v3/app.json(1 hunks)schemas/v3/identityProvider.json(1 hunks)schemas/v3/index.json(1 hunks)
💤 Files with no reviewable changes (1)
- packages/web/src/lib/authProviders.ts
🧰 Additional context used
📓 Path-based instructions (1)
**/*
📄 CodeRabbit inference engine (.cursor/rules/style.mdc)
Filenames should always be camelCase. Exception: if there are filenames in the same directory with a format other than camelCase, use that format to keep things consistent.
Files:
packages/web/src/app/[domain]/settings/permission-syncing/page.tsxpackages/web/src/ee/features/permissionSyncing/types.tspackages/schemas/src/v3/app.type.tspackages/web/src/ee/features/permissionSyncing/components/providerInfo.tsxpackages/schemas/src/v3/app.schema.tspackages/web/src/lib/identityProviders.tspackages/web/src/initialize.tspackages/schemas/src/v3/authProvider.schema.tspackages/web/src/ee/features/permissionSyncing/components/providerBadge.tsxpackages/web/src/ee/features/permissionSyncing/actions.tsschemas/v3/index.jsonpackages/shared/src/utils.tspackages/web/src/ee/features/permissionSyncing/components/providerIcon.tsxdocs/snippets/schemas/v3/app.schema.mdxschemas/v3/app.jsonpackages/web/src/app/[domain]/settings/layout.tsxdocs/snippets/schemas/v3/authProvider.schema.mdxpackages/backend/src/ee/githubAppManager.tspackages/web/src/app/signup/page.tsxpackages/web/src/app/[domain]/layout.tsxpackages/web/src/app/invite/page.tsxpackages/web/src/ee/features/permissionSyncing/components/integrationProviderCard.tsxpackages/schemas/src/v3/identityProvider.schema.tspackages/web/src/ee/features/permissionSyncing/tokenRefresh.tsCHANGELOG.mdpackages/web/src/lib/constants.tspackages/schemas/src/v3/identityProvider.type.tspackages/web/src/app/login/page.tsxpackages/web/src/ee/features/permissionSyncing/components/linkedAccountsSettings.tsxpackages/web/src/auth.tspackages/web/src/ee/features/permissionSyncing/components/linkAccounts.tsxpackages/schemas/src/v3/authProvider.type.tsdocs/snippets/schemas/v3/identityProvider.schema.mdxpackages/web/src/app/components/authMethodSelector.tsxdocs/snippets/schemas/v3/index.schema.mdxpackages/web/src/app/login/components/loginForm.tsxschemas/v3/identityProvider.jsonpackages/web/src/ee/features/permissionSyncing/components/linkButton.tsxpackages/web/src/app/onboard/page.tsxpackages/web/src/ee/features/sso/sso.tspackages/schemas/src/v3/index.schema.tspackages/web/src/ee/features/permissionSyncing/components/unlinkButton.tsxpackages/web/src/features/chat/actions.tspackages/schemas/src/v3/index.type.ts
🪛 markdownlint-cli2 (0.18.1)
CHANGELOG.md
24-24: Multiple headings with the same content
(MD024, no-duplicate-heading)
🔇 Additional comments (19)
packages/web/src/features/chat/actions.ts (1)
192-192: LGTM! Clean removal of unused parameter.The callback no longer needs the
orgparameter since it's not referenced in the function body.packages/web/src/initialize.ts (1)
71-92: Verify the behavioral change for anonymous access forcing.The anonymous access forcing logic now executes unconditionally, even when
CONFIG_PATHwas previously absent. Ensure this behavioral change is intentional and won't cause issues in deployments whereCONFIG_PATHis not configured.The logic itself is well-structured with appropriate entitlement checks and logging.
packages/web/src/app/components/authMethodSelector.tsx (3)
11-14: LGTM - Type refactor aligns with identity provider metadata system.The update from
AuthProvider[]toIdentityProviderMetadata[]is consistent with the broader refactoring in this PR.
18-26: LGTM - Backward compatible prop addition.The new optional
securityNoticeClosableprop with a default value offalsemaintains backward compatibility while enabling control over the security notice's closable state.
38-42: All verification checks passed.The codebase correctly implements the purpose field filtering:
IdentityProviderMetadatainterface properly definespurpose: "sso" | "integration"inpackages/web/src/lib/identityProviders.tsgetIdentityProviderMetadata()consistently extracts and passes thepurposefield from providers- All providers from
getProviders()are correctly assignedpurpose: "sso"The filtering logic at lines 38–42 is sound and will work as intended.
packages/schemas/src/v3/app.type.ts (1)
9-9: LGTM - Type definition consistent with schema update.This change mirrors the discriminator update in the JSON schema. See verification script in
schemas/v3/app.jsonreview.packages/web/src/lib/constants.ts (1)
27-27: LGTM - Cookie constant follows naming conventions.The new constant
OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAMEfollows the established pattern for cookie name constants in this file.packages/web/src/app/onboard/page.tsx (1)
9-9: LGTM - Consistent refactor to identity provider metadata.The update from
getAuthProviders()togetIdentityProviderMetadata()is consistent with the broader refactoring across the codebase.Also applies to: 44-44
packages/web/src/ee/features/permissionSyncing/components/providerBadge.tsx (1)
1-16: LGTM - Simple and effective badge component.The
ProviderBadgecomponent correctly implements a clean visual indicator for required vs. optional providers with appropriate variant selection.packages/web/src/app/login/page.tsx (1)
5-5: LGTM - Consistent refactor to identity provider metadata.The update from
getAuthProviders()togetIdentityProviderMetadata()aligns with the identity provider metadata system introduced in this PR.Also applies to: 28-28
schemas/v3/app.json (1)
9-9: All discriminator usages successfully updated.Verification confirms the breaking change has been fully applied:
- Schema definition (schemas/v3/app.json) updated:
"const": "github"- All configuration files (auth.json, basic.json, self-hosted.json, etc.) use
"type": "github"- Runtime code (githubAppManager.ts:53) filters by
app.type === 'github'- No remaining references to the old
"githubApp"discriminator foundpackages/web/src/app/[domain]/settings/layout.tsx (2)
14-14: LGTM!The entitlement check is properly integrated and follows the existing patterns in the file.
Also applies to: 72-72
120-125: LGTM!The conditional navigation item is correctly implemented, following the established patterns for other entitlement-gated items in the sidebar.
schemas/v3/index.json (1)
128-135: LGTM!The new
identityProvidersproperty is correctly structured and follows the established schema patterns for array properties in this configuration file.packages/web/src/app/invite/page.tsx (2)
10-10: LGTM!The migration from
getAuthProviderstogetIdentityProviderMetadatais correctly implemented and the import/usage are consistent.Also applies to: 33-33
60-60: LGTM!The type signature update correctly reflects the migration to the new identity provider system.
packages/web/src/ee/features/permissionSyncing/components/linkAccounts.tsx (1)
32-32: LGTM!The
canSkiplogic correctly verifies that all required providers are linked, and the sort function properly prioritizes required providers in the display order.Also applies to: 45-46
packages/schemas/src/v3/app.schema.ts (1)
1-1: Source schema has been correctly updated.The source schema file
schemas/v3/app.jsoncontains the updated discriminator value"const": "github"and no lingering"githubApp"references exist anywhere in the repository. The generated filepackages/schemas/src/v3/app.schema.tscorrectly reflects this change and will persist across regenerations since the source is the authoritative definition.packages/web/src/ee/features/permissionSyncing/components/linkButton.tsx (1)
13-17: No changes needed—redirectTois the correct property.The
redirectToproperty is the newer Auth.js API and current preferred option name, replacing the oldercallbackUrlin client parameters. The code in linkButton.tsx is already using the correct, modern property name.Likely an incorrect or invalid review comment.
| export interface GitHubIdentityProviderConfig { | ||
| provider: "github"; | ||
| purpose: "sso" | "identity"; | ||
| clientId: | ||
| | { | ||
| /** | ||
| * The name of the secret that contains the token. | ||
| */ | ||
| secret: string; | ||
| } | ||
| | { | ||
| /** | ||
| * The name of the environment variable that contains the token. Only supported in declarative connection configs. | ||
| */ | ||
| env: string; | ||
| }; | ||
| clientSecret: | ||
| | { | ||
| /** | ||
| * The name of the secret that contains the token. | ||
| */ | ||
| secret: string; | ||
| } | ||
| | { | ||
| /** | ||
| * The name of the environment variable that contains the token. Only supported in declarative connection configs. | ||
| */ | ||
| env: string; | ||
| }; | ||
| baseUrl?: | ||
| | { | ||
| /** | ||
| * The name of the secret that contains the token. | ||
| */ | ||
| secret: string; | ||
| } | ||
| | { | ||
| /** | ||
| * The name of the environment variable that contains the token. Only supported in declarative connection configs. | ||
| */ | ||
| env: string; | ||
| }; | ||
| [k: string]: unknown; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align IdentityProviderConfig literals with the new schema
purpose is still typed as "sso" | "identity", but the new schema (and consuming code) now uses "integration". Likewise, the credential refs are emitted as { secret: string }, while the schema expects { googleCloudSecret: string }. With the current typings a valid config (e.g. purpose: "integration" plus a googleCloudSecret ref) no longer type-checks, so this needs to be corrected before release. Please update the generator/output accordingly (and cascade the same fixes to clientSecret/baseUrl/etc.).
- purpose: "sso" | "identity";
+ purpose: "sso" | "integration";
@@
- secret: string;
+ googleCloudSecret: string;
@@
- secret: string;
+ googleCloudSecret: string;Committable suggestion skipped: line range outside the PR's diff.
packages/web/src/ee/features/permissionSyncing/components/providerIcon.tsx
Show resolved
Hide resolved
| const config = await loadConfig(env.CONFIG_PATH); | ||
| const forceEnableAnonymousAccess = config.settings?.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS === 'true'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
Add defensive checks for config loading.
The unconditional call to loadConfig(env.CONFIG_PATH) may cause a runtime error during application startup if:
env.CONFIG_PATHis undefined or invalid, andloadConfigdoesn't handle it gracefully.loadConfigreturnsnullorundefined, causing line 69 to throw (sinceconfig.settings?.enablePublicAccesslacks optional chaining onconfigitself).
Apply this diff to add defensive checks:
-const config = await loadConfig(env.CONFIG_PATH);
-const forceEnableAnonymousAccess = config.settings?.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS === 'true';
+const config = env.CONFIG_PATH ? await loadConfig(env.CONFIG_PATH) : null;
+const forceEnableAnonymousAccess = config?.settings?.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS === 'true';Alternatively, verify that loadConfig handles undefined/null paths gracefully and always returns a valid config object:
🏁 Script executed:
#!/bin/bash
# Description: Verify loadConfig's behavior with undefined/null paths
# Find the loadConfig implementation
ast-grep --pattern 'export function loadConfig($$$) { $$$ }'
# Also search for its type signature and error handling
rg -n -A 10 'export.*loadConfig' --type=tsLength of output: 824
🏁 Script executed:
#!/bin/bash
# Search for CONFIG_PATH usage and how it's set
rg -n 'CONFIG_PATH' --type=ts --type=js --type=env -B2 -A2
# Check for environment setup/initialization files
fd -e 'env*' -o -e '*config*' | head -20Length of output: 144
🏁 Script executed:
#!/bin/bash
# Check how initSingleTenancy is called and what context surrounds config loading
rg -n 'initSingleTenancy' --type=ts -B5 -A5
# Look for any error handling around config loading
rg -n 'loadConfig' --type=ts -B3 -A3 | head -40Length of output: 3826
---
🏁 Script executed:
```shell
#!/bin/bash
# Check the getConfigSettings function which wraps loadConfig
rg -n 'getConfigSettings' --type=ts -B5 -A15
Length of output: 12842
🏁 Script executed:
#!/bin/bash
# Search for CONFIG_PATH in entire codebase without regex issues
grep -r 'CONFIG_PATH' --include='*.ts' --include='*.js' --include='*.mts' -nLength of output: 1433
🏁 Script executed:
#!/bin/bash
# Look for environment initialization and .env handling
fd -name '.env*' -o -name 'env.mts' -o -name 'env.ts' -o -name 'environment*'
# Also check initialize.ts more broadly to understand the full flow
cat packages/web/src/initialize.ts | head -100Length of output: 4179
Use the getConfigSettings wrapper for safe config loading.
Line 68 unconditionally calls loadConfig(env.CONFIG_PATH), which will crash the application during startup if env.CONFIG_PATH is missing or falsy. The loadConfig function throws with "CONFIG_PATH is required but not provided" when the path is falsy.
For consistency with other parts of the codebase (e.g., packages/web/src/app/[domain]/repos/[id]/page.tsx line 37), use the getConfigSettings wrapper which handles missing CONFIG_PATH gracefully by returning default settings:
-const config = await loadConfig(env.CONFIG_PATH);
-const forceEnableAnonymousAccess = config.settings?.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS === 'true';
+const configSettings = await getConfigSettings(env.CONFIG_PATH);
+const forceEnableAnonymousAccess = configSettings.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS === 'true';Alternatively, import and use getConfigSettings from @sourcebot/shared instead of loadConfig.
Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In packages/web/src/initialize.ts around lines 68-69, the code calls
loadConfig(env.CONFIG_PATH) directly which throws if CONFIG_PATH is falsy;
replace this with the getConfigSettings wrapper (imported from
@sourcebot/shared) which safely handles missing CONFIG_PATH and returns
defaults, then derive forceEnableAnonymousAccess from the returned settings
(e.g., settings?.enablePublicAccess ?? env.FORCE_ENABLE_ANONYMOUS_ACCESS ===
'true'); update the imports to use getConfigSettings instead of loadConfig and
remove the direct loadConfig call.
| const config = await loadConfig(env.CONFIG_PATH); | ||
| const identityProviders = config?.identityProviders ?? []; | ||
|
|
||
| const providerConfig = identityProviders.find(idp => idp.provider === provider); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the situation where there are multiple identity providers of the same type, I think we will run into issues here right? We always get whatever identity provider appears first in the config?
Aside: does auth.js even support the situation where multiple accounts from the same auth provider are linked to the same User?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Discussed offline: we should uniquely identify providers based on the combination of the providers type and baseUrl. This is kind of similar to what we do for language models (getLanguageModelKey in features/chat/utils.ts)
| } | ||
|
|
||
| // When a user links a new account, store the tokens if it's an integration provider | ||
| if (account && hasEntitlement('permission-syncing')) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It doesn't really matter right now, but wouldn't we want integrations to live under the sso entitlement (or it's own entitlement)?
|
Discussed offline: there is a bug atm where if permission syncing is enabled and one or more integrations are configured, then private repositories that require signin via the integrations will not be accessible (until the next user driven permission sync job runs). This is because The hack fix is to reset the The longer term fix is to support on-demand job queuing s.t., the webapp could schedule a user permission sync job on account linking. |
Adds a new
identityProvidertop level object to the config file. This allows you to define one or more identity providers which will be used by Sourcebot.There are two different types of identity providers:
ssoandintegration.ssoproviders are used to auth, whileintegrationproviders are linked after authentication and are (currently) used for permission syncing. This allows users to login with a different identity provider than their code host platform (ex. login usingOktabut still be able to connect toGitHubfor permission syncing). It also sets the foundation to be able to oauth into multiple code host platforms to support permission syncing across multiple code host platformsTODO:
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Configuration