From 489ef567a32e0630dc696914c9a1701deb213d16 Mon Sep 17 00:00:00 2001 From: arc53-machine <232052973+arc53-machine@users.noreply.github.com> Date: Tue, 29 Sep 2026 10:31:17 +0100 Subject: [PATCH] Show GitHub's optional GitHub App setup in Admin > Connectors GitHub is Ready with tokens alone and marked Tokens only until its GitHub App settings are set. Its setup guide lists them, the callback URL to register, and the App permissions and install option to choose. --- frontend/src/admin/Connectors.test.tsx | 35 ++++++++ frontend/src/admin/Connectors.tsx | 111 ++++++++++++++++++++----- 2 files changed, 123 insertions(+), 23 deletions(-) diff --git a/frontend/src/admin/Connectors.test.tsx b/frontend/src/admin/Connectors.test.tsx index b8c9a0e9..cf190634 100644 --- a/frontend/src/admin/Connectors.test.tsx +++ b/frontend/src/admin/Connectors.test.tsx @@ -144,6 +144,41 @@ describe('Admin Connectors', () => { ); }); + it('shows GitHub as ready, with its optional GitHub App settings in the guide', async () => { + const GITHUB = connector({ + key: 'github', + name: 'GitHub', + icon: 'github', + auth_kind: 'api_key', + capabilities: ['sync', 'read'], + configured: true, + required_settings: [], + oauth_settings: [ + { name: 'GITHUB_CLIENT_ID', set: true }, + { name: 'GITHUB_CLIENT_SECRET', set: false }, + { name: 'GITHUB_APP_SLUG', set: false }, + ], + oauth_configured: false, + connection_count: 0, + }); + getAdmin.mockResolvedValue(payload({ connectors: [GITHUB] })); + await render(); + const row = container.querySelector('tbody tr')!; + expect(row.textContent).toContain('Ready'); + expect(row.textContent).toContain('Tokens only'); + const guide = Array.from(row.querySelectorAll('button')).find( + (b) => b.textContent === 'Setup guide', + )!; + await act(async () => guide.click()); + const text = document.body.textContent ?? ''; + expect(text).toContain('Sign in with GitHub'); + expect(text).toContain('GITHUB_APP_SLUG'); + expect(text).toContain( + 'Request user authorization (OAuth) during installation', + ); + expect(text).toContain('https://docs.example/api/connectors/callback'); + }); + it('warns when credentials use the default encryption key', async () => { getAdmin.mockResolvedValue(payload({ default_encryption_key: true })); await render(); diff --git a/frontend/src/admin/Connectors.tsx b/frontend/src/admin/Connectors.tsx index 3549fca9..36c27a52 100644 --- a/frontend/src/admin/Connectors.tsx +++ b/frontend/src/admin/Connectors.tsx @@ -65,6 +65,9 @@ type AdminConnector = { credential_mode: Policy; configured: boolean; required_settings: { name: string; set: boolean }[]; + /** Optional settings that add a second sign-in (GitHub's App). */ + oauth_settings?: { name: string; set: boolean }[]; + oauth_configured?: boolean; connection_count: number; docs_url: string | null; mcp_url: string | null; @@ -88,6 +91,35 @@ const POLICY_LABELS: Record = { const hasTools = (connector: AdminConnector) => connector.capabilities.some((capability) => capability !== 'sync'); +const hasSetupGuide = (connector: AdminConnector) => + connector.required_settings.length > 0 || + (connector.oauth_settings?.length ?? 0) > 0; + +/** Works with pasted tokens, but its optional OAuth sign-in is not set up yet. */ +const tokensOnly = (connector: AdminConnector) => + (connector.oauth_settings?.length ?? 0) > 0 && !connector.oauth_configured; + +function SettingsList({ + settings, +}: { + settings: { name: string; set: boolean }[]; +}) { + return ( + + {settings.map((setting) => ( + {setting.name}} + > + + {setting.set ? 'Set' : 'Missing'} + + + ))} + + ); +} + function CodeRow({ value }: { value: string }) { return ( @@ -108,12 +140,19 @@ function SetupGuide({ redirectUri: string; onClose: () => void; }) { + const oauthSettings = connector.oauth_settings ?? []; + const optionalOAuth = + connector.required_settings.length === 0 && oauthSettings.length > 0; return ( !open && onClose()} title={`Set up ${connector.name}`} - description="Register DocsGPT as an OAuth app with the provider, then set these server settings and restart the API and the worker." + description={ + optionalOAuth + ? `Members can already connect ${connector.name} with their own access tokens. To also offer Sign in with ${connector.name}, register a GitHub App, then set these server settings and restart the API and the worker.` + : 'Register DocsGPT as an OAuth app with the provider, then set these server settings and restart the API and the worker.' + } footer={