Skip to content

Conversation

@msukkari
Copy link
Contributor

@msukkari msukkari commented Nov 3, 2025

Adds a new identityProvider top 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: sso and integration. sso providers are used to auth, while integration providers 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 using Okta but still be able to connect to GitHub for 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 platforms

TODO:

  • docs
  • add oauth token refresh logic (probably in a different PR)
image image

Summary by CodeRabbit

Release Notes

  • New Features

    • Added identity provider management with support for multiple providers (GitHub, GitLab, Google, Okta, Keycloak, Microsoft Entra ID, GCP IAP)
    • Added permission syncing feature allowing users to link and manage integration accounts
    • New "Linked Accounts" settings page for managing connected provider accounts
    • Added OAuth token refresh capability for seamless account synchronization
  • Bug Fixes

    • Updated GitHub App configuration identifier for consistency
  • Configuration

    • Expanded root configuration schema to support identity providers collection
    • Configuration path parameter is now optional

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Important

Review skipped

Auto reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

This 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

Cohort / File(s) Summary
GitHub App Type Discriminator Rename
CHANGELOG.md, packages/schemas/src/v3/app.schema.ts, packages/schemas/src/v3/app.type.ts, packages/backend/src/ee/githubAppManager.ts, schemas/v3/app.json, docs/snippets/schemas/v3/app.schema.mdx
Updated GitHub App config type field from "githubApp" to "github" in schema definitions, TypeScript interfaces, backend filter logic, and JSON schema files.
Auto-Generated Identity Provider Schemas
docs/snippets/schemas/v3/authProvider.schema.mdx, docs/snippets/schemas/v3/identityProvider.schema.mdx, packages/schemas/src/v3/authProvider.schema.ts, packages/schemas/src/v3/identityProvider.schema.ts, schemas/v3/identityProvider.json
New auto-generated JSON Schema definitions for identity provider configurations supporting GitHub, GitLab, Google, Okta, Keycloak, Microsoft Entra ID, and GCP IAP providers with credential and optional field variants.
Auto-Generated Identity Provider Types
packages/schemas/src/v3/authProvider.type.ts, packages/schemas/src/v3/identityProvider.type.ts
New TypeScript type definitions for identity provider configurations, introducing discriminated union types and provider-specific interfaces.
Index Schema & Type Updates
docs/snippets/schemas/v3/index.schema.mdx, packages/schemas/src/v3/index.schema.ts, packages/schemas/src/v3/index.type.ts, schemas/v3/index.json
Updated root schema/type definitions to include new identityProviders collection and integrated GitHub App type discriminator changes.
Provider System Refactoring
packages/web/src/lib/authProviders.ts (deleted), packages/web/src/lib/identityProviders.ts, packages/web/src/lib/constants.ts
Replaced AuthProvider with IdentityProviderMetadata type, introduced getIdentityProviderMetadata() function, added OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAME constant.
SSO & Identity Provider Loading
packages/web/src/ee/features/sso/sso.ts, packages/web/src/auth.ts
Renamed getSSOProviders() to getEEIdentityProviders(), added support for config-driven provider initialization, integrated integration token tracking (accessToken, refreshToken, expiresAt) in NextAuth JWT/Session, and added permission-syncing purpose discrimination.
Integration Token Refresh
packages/web/src/ee/features/permissionSyncing/tokenRefresh.ts
New module providing refreshIntegrationTokens() and refreshOAuthToken() functions for OAuth token lifecycle management with support for GitHub and GitLab.
Permission Syncing Actions & Types
packages/web/src/ee/features/permissionSyncing/actions.ts, packages/web/src/ee/features/permissionSyncing/types.ts
New server actions getIntegrationProviderStates(), unlinkIntegrationProvider(), skipOptionalProvidersLink() and IntegrationIdentityProviderState type for managing linked accounts.
Permission Syncing UI Components
packages/web/src/ee/features/permissionSyncing/components/*.tsx
New client/server components: LinkedAccountsSettings, LinkAccounts, IntegrationProviderCard, LinkButton, UnlinkButton, ProviderIcon, ProviderInfo, ProviderBadge for account linking UI.
Authentication & Layout Integration
packages/web/src/app/[domain]/layout.tsx, packages/web/src/app/[domain]/settings/layout.tsx, packages/web/src/app/[domain]/settings/permission-syncing/page.tsx
Added permission-syncing entitlement checks, provider state fetching, conditional LinkAccounts prompt, and new settings page for managing linked accounts.
Provider Metadata Propagation
packages/web/src/app/components/authMethodSelector.tsx, packages/web/src/app/login/components/loginForm.tsx, packages/web/src/app/login/page.tsx, packages/web/src/app/invite/page.tsx, packages/web/src/app/onboard/page.tsx, packages/web/src/app/signup/page.tsx
Updated authentication flow pages to use IdentityProviderMetadata and getIdentityProviderMetadata() instead of AuthProvider/getAuthProviders().
Configuration & Initialization
packages/shared/src/utils.ts, packages/web/src/initialize.ts, packages/web/src/features/chat/actions.ts
Made loadConfig() parameter optional with validation, updated anonymous-access forcing logic to execute unconditionally, simplified language model config loading.

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
Loading
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
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Schema generation: Multiple new auto-generated TypeScript and JSON schema files require verification that schema generation logic correctly produces discriminated unions and provider-specific configurations.
  • Provider system refactoring: Extensive changes across authentication/login flow (6+ pages, auth.ts, sso.ts) with type changes from AuthProvider[] to IdentityProviderMetadata[] and new IdentityProvider wrapper type—requires tracing all call sites for correctness.
  • Permission syncing logic: New entitlement-gated feature with DB interactions, token refresh mechanics, and conditional rendering logic in layouts; token refresh implementation requires verification of OAuth refresh flows for GitHub/GitLab.
  • Type discriminator rename: GitHub App type field changed from "githubApp" to "github" across 6 files; requires verifying no runtime comparisons use hardcoded old value.
  • NextAuth extensions: JWT and Session augmentation with new integrationTokens and integrationProviderErrors fields; requires checking that token refresh integration happens at correct callback hook point.

Possibly related PRs

  • PR #311: Introduces/renames identity provider types and schemas with matching auth/SSO provider loading refactoring (packages/schemas/*, packages/web/src/auth.ts, packages/web/src/ee/features/sso/sso.ts).
  • PR #508: Implements the permission-syncing feature with DB migrations, schedulers, token refresh, and matching UI/schema changes across web and backend.
  • PR #284: Updates schema generator (packages/schemas/tools/generate.ts) that produces the new auto-generated MDX documentation snippets in this PR.

Suggested labels

sourcebot-team

Suggested reviewers

  • msukkari

Pre-merge checks and finishing touches

✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely describes the main feature introduced in the changeset: the ability to link external accounts for permission syncing and multi-provider OAuth support.

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 and usage tips.

@msukkari msukkari changed the title feat(account-linked): Add ability to linked external accounts feat(account-linked): Add ability to link external accounts Nov 4, 2025
@brendan-kellam
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 4, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a 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.

providers points directly at the module-level eeIdentityProviders; every invocation of getProviders() 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 in schemas/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 identityProviders from 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 same id, which breaks NextAuth’s provider map (last one wins, callbacks become unpredictable). Please gate the legacy path so it only runs when identityProviders is 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 div element. You can simplify the code by returning the div directly.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 26ec7af and 4f3369b.

📒 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.tsx
  • packages/web/src/ee/features/permissionSyncing/types.ts
  • packages/schemas/src/v3/app.type.ts
  • packages/web/src/ee/features/permissionSyncing/components/providerInfo.tsx
  • packages/schemas/src/v3/app.schema.ts
  • packages/web/src/lib/identityProviders.ts
  • packages/web/src/initialize.ts
  • packages/schemas/src/v3/authProvider.schema.ts
  • packages/web/src/ee/features/permissionSyncing/components/providerBadge.tsx
  • packages/web/src/ee/features/permissionSyncing/actions.ts
  • schemas/v3/index.json
  • packages/shared/src/utils.ts
  • packages/web/src/ee/features/permissionSyncing/components/providerIcon.tsx
  • docs/snippets/schemas/v3/app.schema.mdx
  • schemas/v3/app.json
  • packages/web/src/app/[domain]/settings/layout.tsx
  • docs/snippets/schemas/v3/authProvider.schema.mdx
  • packages/backend/src/ee/githubAppManager.ts
  • packages/web/src/app/signup/page.tsx
  • packages/web/src/app/[domain]/layout.tsx
  • packages/web/src/app/invite/page.tsx
  • packages/web/src/ee/features/permissionSyncing/components/integrationProviderCard.tsx
  • packages/schemas/src/v3/identityProvider.schema.ts
  • packages/web/src/ee/features/permissionSyncing/tokenRefresh.ts
  • CHANGELOG.md
  • packages/web/src/lib/constants.ts
  • packages/schemas/src/v3/identityProvider.type.ts
  • packages/web/src/app/login/page.tsx
  • packages/web/src/ee/features/permissionSyncing/components/linkedAccountsSettings.tsx
  • packages/web/src/auth.ts
  • packages/web/src/ee/features/permissionSyncing/components/linkAccounts.tsx
  • packages/schemas/src/v3/authProvider.type.ts
  • docs/snippets/schemas/v3/identityProvider.schema.mdx
  • packages/web/src/app/components/authMethodSelector.tsx
  • docs/snippets/schemas/v3/index.schema.mdx
  • packages/web/src/app/login/components/loginForm.tsx
  • schemas/v3/identityProvider.json
  • packages/web/src/ee/features/permissionSyncing/components/linkButton.tsx
  • packages/web/src/app/onboard/page.tsx
  • packages/web/src/ee/features/sso/sso.ts
  • packages/schemas/src/v3/index.schema.ts
  • packages/web/src/ee/features/permissionSyncing/components/unlinkButton.tsx
  • packages/web/src/features/chat/actions.ts
  • packages/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 org parameter 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_PATH was previously absent. Ensure this behavioral change is intentional and won't cause issues in deployments where CONFIG_PATH is 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[] to IdentityProviderMetadata[] is consistent with the broader refactoring in this PR.


18-26: LGTM - Backward compatible prop addition.

The new optional securityNoticeClosable prop with a default value of false maintains 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:

  1. IdentityProviderMetadata interface properly defines purpose: "sso" | "integration" in packages/web/src/lib/identityProviders.ts
  2. getIdentityProviderMetadata() consistently extracts and passes the purpose field from providers
  3. All providers from getProviders() are correctly assigned purpose: "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.json review.

packages/web/src/lib/constants.ts (1)

27-27: LGTM - Cookie constant follows naming conventions.

The new constant OPTIONAL_PROVIDERS_LINK_SKIPPED_COOKIE_NAME follows 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() to getIdentityProviderMetadata() 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 ProviderBadge component 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() to getIdentityProviderMetadata() 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 found
packages/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 identityProviders property 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 getAuthProviders to getIdentityProviderMetadata is 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 canSkip logic 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.json contains the updated discriminator value "const": "github" and no lingering "githubApp" references exist anywhere in the repository. The generated file packages/schemas/src/v3/app.schema.ts correctly 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—redirectTo is the correct property.

The redirectTo property is the newer Auth.js API and current preferred option name, replacing the older callbackUrl in client parameters. The code in linkButton.tsx is already using the correct, modern property name.

Likely an incorrect or invalid review comment.

@brendan-kellam
Copy link
Contributor

brendan-kellam commented Nov 5, 2025

**EDIT: #600 resolves this by moving the join table to be between Account and Repo

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 userPermissionSyncer.ts schedules new sync jobs when a new User object is created (and therefore will sync the primary sso account), but not when subsequent Account objects are added.

The hack fix is to reset the permissionSyncedAt field to null when a new account is linked. The scheduler will take care of scheduling a new user permission sync job. Caveat: This will only happen if the first job did not fail due to how the scheduler logic works.

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.

@msukkari msukkari changed the title feat(account-linked): Add ability to link external accounts feat(account-linking): Add ability to link external accounts Nov 5, 2025
@github-actions

This comment has been minimized.

@msukkari msukkari changed the title feat(account-linking): Add ability to link external accounts feat(ee): Add ability to link external accounts Nov 5, 2025
@msukkari msukkari merged commit 449c76f into main Nov 5, 2025
10 checks passed
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.

3 participants