From 281d242466021cd25e63a895c5798c3effb70dd2 Mon Sep 17 00:00:00 2001 From: hex2077 Date: Tue, 13 Jan 2026 19:09:17 +0800 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=E6=94=AF=E6=8C=81=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=20Builder=20ID=20Start=20URL=20=E5=B9=B6?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9B=B8=E5=85=B3=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 为 Kiro OAuth 添加 Builder ID Start URL 的可配置选项,优先使用前端传入的值 添加相关国际化文本和 UI 控件,允许用户自定义或重新生成 Start URL 同时支持通过 options.authMethod 参数指定认证方法 --- src/auth/oauth-handlers.js | 8 ++++-- static/app/i18n.js | 6 +++++ static/app/provider-manager.js | 45 +++++++++++++++++++++++++++++++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/src/auth/oauth-handlers.js b/src/auth/oauth-handlers.js index c4a241f..c2e578a 100644 --- a/src/auth/oauth-handlers.js +++ b/src/auth/oauth-handlers.js @@ -665,7 +665,7 @@ export async function handleQwenOAuth(currentConfig, options = {}) { * @returns {Promise} 返回授权URL和相关信息 */ export async function handleKiroOAuth(currentConfig, options = {}) { - const method = options.method || 'google'; // 默认使用 Google + const method = options.method || options.authMethod || 'google'; // 默认使用 Google,同时支持 authMethod 参数 console.log(`${KIRO_OAUTH_CONFIG.logPrefix} Starting OAuth with method: ${method}`); @@ -740,6 +740,10 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) { } } + // 获取 Builder ID Start URL(优先使用前端传入的值,否则使用默认值) + const builderIDStartURL = options.builderIDStartURL || KIRO_OAUTH_CONFIG.builderIDStartURL; + console.log(`${KIRO_OAUTH_CONFIG.logPrefix} Using Builder ID Start URL: ${builderIDStartURL}`); + // 1. 注册 OIDC 客户端 const regResponse = await fetchWithProxy(`${KIRO_OAUTH_CONFIG.ssoOIDCEndpoint}/client/register`, { method: 'POST', @@ -771,7 +775,7 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) { body: JSON.stringify({ clientId: regData.clientId, clientSecret: regData.clientSecret, - startUrl: KIRO_OAUTH_CONFIG.builderIDStartURL + startUrl: builderIDStartURL }) }, 'claude-kiro-oauth'); diff --git a/static/app/i18n.js b/static/app/i18n.js index 063134c..c19517d 100644 --- a/static/app/i18n.js +++ b/static/app/i18n.js @@ -177,6 +177,8 @@ const translations = { 'oauth.kiro.importError': '导入出错', 'oauth.kiro.duplicateToken': '重复凭据 - 此 refreshToken 已存在', 'oauth.kiro.duplicateCredentials': '该凭据已存在,请勿重复导入', + 'oauth.kiro.builderIDStartURL': 'Builder ID Start URL', + 'oauth.kiro.builderIDStartURLHint': '如果您使用 AWS IAM Identity Center,请输入您的 Start URL', 'oauth.iflow.step1': '点击下方按钮在浏览器中打开 iFlow 授权页面', 'oauth.iflow.step2': '使用您的 iFlow 账号登录并授权', 'oauth.iflow.step3': '授权完成后,系统会自动获取 API Key', @@ -527,6 +529,7 @@ const translations = { 'common.loading': '加载中...', 'common.upload': '上传', 'common.generate': '生成', + 'common.optional': '可选', 'common.found': '已找到', 'common.missing': '缺失', 'common.search': '搜索', @@ -732,6 +735,8 @@ const translations = { 'oauth.kiro.importError': 'Import error', 'oauth.kiro.duplicateToken': 'Duplicate - this refreshToken already exists', 'oauth.kiro.duplicateCredentials': 'This credential already exists, please do not import duplicates', + 'oauth.kiro.builderIDStartURL': 'Builder ID Start URL', + 'oauth.kiro.builderIDStartURLHint': 'If you use AWS IAM Identity Center, enter your Start URL', 'oauth.iflow.step1': 'Click the button below to open the iFlow authorization page', 'oauth.iflow.step2': 'Log in with your iFlow account and authorize', 'oauth.iflow.step3': 'After authorization, the system will automatically fetch the API Key', @@ -1085,6 +1090,7 @@ const translations = { 'common.loading': 'Loading...', 'common.upload': 'Upload', 'common.generate': 'Generate', + 'common.optional': 'Optional', 'common.found': 'Found', 'common.missing': 'Missing', 'common.search': 'Search', diff --git a/static/app/provider-manager.js b/static/app/provider-manager.js index f27662e..779d56e 100644 --- a/static/app/provider-manager.js +++ b/static/app/provider-manager.js @@ -680,7 +680,7 @@ function showKiroAuthMethodSelector(providerType) { modal.style.display = 'flex'; modal.innerHTML = ` -