From d0091901dc83de984e97577c7ad725f846fb8507 Mon Sep 17 00:00:00 2001 From: LiJian Date: Fri, 1 May 2026 13:00:55 +0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=90=9B=20fix(skill):=20skip=20OAuth=20red?= =?UTF-8?q?irectUri=20on=20desktop=20to=20prevent=20broken=20app=20(#14345?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 🐛 fix(skill): skip OAuth redirectUri on desktop to prevent broken app:// navigation On desktop (Electron), window.location.origin is app://renderer which the system browser cannot navigate to. Skip passing redirectUri so market shows a default success page instead, relying on existing window-close monitoring and fallback polling to detect OAuth completion. Co-authored-by: Claude Opus 4.6 (1M context) --- .../agent-manager-runtime/src/AgentManagerRuntime.ts | 3 ++- packages/builtin-tool-creds/src/executor/index.ts | 6 +++++- .../ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx | 9 +++++++-- .../SkillStore/SkillList/LobeHub/useSkillConnect.ts | 5 ++++- .../(main)/settings/skill/features/LobehubSkillItem.tsx | 5 ++++- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/packages/agent-manager-runtime/src/AgentManagerRuntime.ts b/packages/agent-manager-runtime/src/AgentManagerRuntime.ts index dfeb34c075..3cac0bdc66 100644 --- a/packages/agent-manager-runtime/src/AgentManagerRuntime.ts +++ b/packages/agent-manager-runtime/src/AgentManagerRuntime.ts @@ -872,8 +872,9 @@ export class AgentManagerRuntime { } // Need OAuth authorization + // Skip redirectUri on desktop (app:// protocol) since the system browser can't navigate to it const redirectUri = - typeof window !== 'undefined' + typeof window !== 'undefined' && window.location.protocol.startsWith('http') ? `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(identifier)}` : undefined; const authInfo = await getToolStoreState().getLobehubSkillAuthorizeUrl(identifier, { diff --git a/packages/builtin-tool-creds/src/executor/index.ts b/packages/builtin-tool-creds/src/executor/index.ts index 0868317db0..184accbe93 100644 --- a/packages/builtin-tool-creds/src/executor/index.ts +++ b/packages/builtin-tool-creds/src/executor/index.ts @@ -191,7 +191,11 @@ class CredsExecutor extends BaseExecutor { } // Get the authorization URL from the market API - const redirectUri = `${typeof window !== 'undefined' ? window.location.origin : ''}/oauth/callback/success?provider=${provider}`; + // Skip redirectUri on desktop (app:// protocol) since the system browser can't navigate to it + const redirectUri = + typeof window !== 'undefined' && window.location.protocol.startsWith('http') + ? `${window.location.origin}/oauth/callback/success?provider=${provider}` + : undefined; const response = await toolsClient.market.connectGetAuthorizeUrl.query({ provider, redirectUri, diff --git a/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx b/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx index 6aa9b8292f..be1ccf6cf2 100644 --- a/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx +++ b/src/features/ChatInput/ActionBar/Tools/LobehubSkillServerItem.tsx @@ -201,7 +201,10 @@ const LobehubSkillServerItem = memo(({ provider, la setIsConnecting(true); try { // Use /oauth/callback/success as redirect URI with provider param for auto-enable - const redirectUri = `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider)}`; + // Skip redirectUri on desktop (app:// protocol) since the system browser can't navigate to it + const redirectUri = window.location.protocol.startsWith('http') + ? `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider)}` + : undefined; const { authorizeUrl } = await getAuthorizeUrl(provider, { redirectUri }); openOAuthWindow(authorizeUrl); } catch (error) { @@ -277,7 +280,9 @@ const LobehubSkillServerItem = memo(({ provider, la onClick={async (e) => { e.stopPropagation(); try { - const redirectUri = `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider)}`; + const redirectUri = window.location.protocol.startsWith('http') + ? `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider)}` + : undefined; const { authorizeUrl } = await getAuthorizeUrl(provider, { redirectUri }); openOAuthWindow(authorizeUrl); } catch (error) { diff --git a/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts b/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts index 6e379b490a..2541b8506e 100644 --- a/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts +++ b/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts @@ -178,7 +178,10 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec const provider = getLobehubSkillProviderById(identifier); if (!provider) return; - const redirectUri = `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(identifier)}`; + // Skip redirectUri on desktop (app:// protocol) since the system browser can't navigate to it + const redirectUri = window.location.protocol.startsWith('http') + ? `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(identifier)}` + : undefined; const { authorizeUrl } = await getAuthorizeUrl(identifier, { redirectUri }); openOAuthWindow(authorizeUrl, identifier); } catch (error) { diff --git a/src/routes/(main)/settings/skill/features/LobehubSkillItem.tsx b/src/routes/(main)/settings/skill/features/LobehubSkillItem.tsx index 8a832f31dc..6b1f279517 100644 --- a/src/routes/(main)/settings/skill/features/LobehubSkillItem.tsx +++ b/src/routes/(main)/settings/skill/features/LobehubSkillItem.tsx @@ -152,7 +152,10 @@ const LobehubSkillItem = memo(({ provider, server }) => { setIsConnecting(true); try { - const redirectUri = `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider.id)}`; + // Skip redirectUri on desktop (app:// protocol) since the system browser can't navigate to it + const redirectUri = window.location.protocol.startsWith('http') + ? `${window.location.origin}/oauth/callback/success?provider=${encodeURIComponent(provider.id)}` + : undefined; const { authorizeUrl } = await getAuthorizeUrl(provider.id, { redirectUri }); openOAuthWindow(authorizeUrl); } catch (error) {