feat(auth): 支持自定义 Builder ID Start URL 并添加相关国际化
为 Kiro OAuth 添加 Builder ID Start URL 的可配置选项,优先使用前端传入的值 添加相关国际化文本和 UI 控件,允许用户自定义或重新生成 Start URL 同时支持通过 options.authMethod 参数指定认证方法
This commit is contained in:
parent
817c25267b
commit
281d242466
3 changed files with 56 additions and 3 deletions
|
|
@ -665,7 +665,7 @@ export async function handleQwenOAuth(currentConfig, options = {}) {
|
||||||
* @returns {Promise<Object>} 返回授权URL和相关信息
|
* @returns {Promise<Object>} 返回授权URL和相关信息
|
||||||
*/
|
*/
|
||||||
export async function handleKiroOAuth(currentConfig, options = {}) {
|
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}`);
|
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 客户端
|
// 1. 注册 OIDC 客户端
|
||||||
const regResponse = await fetchWithProxy(`${KIRO_OAUTH_CONFIG.ssoOIDCEndpoint}/client/register`, {
|
const regResponse = await fetchWithProxy(`${KIRO_OAUTH_CONFIG.ssoOIDCEndpoint}/client/register`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
@ -771,7 +775,7 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) {
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
clientId: regData.clientId,
|
clientId: regData.clientId,
|
||||||
clientSecret: regData.clientSecret,
|
clientSecret: regData.clientSecret,
|
||||||
startUrl: KIRO_OAUTH_CONFIG.builderIDStartURL
|
startUrl: builderIDStartURL
|
||||||
})
|
})
|
||||||
}, 'claude-kiro-oauth');
|
}, 'claude-kiro-oauth');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -177,6 +177,8 @@ const translations = {
|
||||||
'oauth.kiro.importError': '导入出错',
|
'oauth.kiro.importError': '导入出错',
|
||||||
'oauth.kiro.duplicateToken': '重复凭据 - 此 refreshToken 已存在',
|
'oauth.kiro.duplicateToken': '重复凭据 - 此 refreshToken 已存在',
|
||||||
'oauth.kiro.duplicateCredentials': '该凭据已存在,请勿重复导入',
|
'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.step1': '点击下方按钮在浏览器中打开 iFlow 授权页面',
|
||||||
'oauth.iflow.step2': '使用您的 iFlow 账号登录并授权',
|
'oauth.iflow.step2': '使用您的 iFlow 账号登录并授权',
|
||||||
'oauth.iflow.step3': '授权完成后,系统会自动获取 API Key',
|
'oauth.iflow.step3': '授权完成后,系统会自动获取 API Key',
|
||||||
|
|
@ -527,6 +529,7 @@ const translations = {
|
||||||
'common.loading': '加载中...',
|
'common.loading': '加载中...',
|
||||||
'common.upload': '上传',
|
'common.upload': '上传',
|
||||||
'common.generate': '生成',
|
'common.generate': '生成',
|
||||||
|
'common.optional': '可选',
|
||||||
'common.found': '已找到',
|
'common.found': '已找到',
|
||||||
'common.missing': '缺失',
|
'common.missing': '缺失',
|
||||||
'common.search': '搜索',
|
'common.search': '搜索',
|
||||||
|
|
@ -732,6 +735,8 @@ const translations = {
|
||||||
'oauth.kiro.importError': 'Import error',
|
'oauth.kiro.importError': 'Import error',
|
||||||
'oauth.kiro.duplicateToken': 'Duplicate - this refreshToken already exists',
|
'oauth.kiro.duplicateToken': 'Duplicate - this refreshToken already exists',
|
||||||
'oauth.kiro.duplicateCredentials': 'This credential already exists, please do not import duplicates',
|
'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.step1': 'Click the button below to open the iFlow authorization page',
|
||||||
'oauth.iflow.step2': 'Log in with your iFlow account and authorize',
|
'oauth.iflow.step2': 'Log in with your iFlow account and authorize',
|
||||||
'oauth.iflow.step3': 'After authorization, the system will automatically fetch the API Key',
|
'oauth.iflow.step3': 'After authorization, the system will automatically fetch the API Key',
|
||||||
|
|
@ -1085,6 +1090,7 @@ const translations = {
|
||||||
'common.loading': 'Loading...',
|
'common.loading': 'Loading...',
|
||||||
'common.upload': 'Upload',
|
'common.upload': 'Upload',
|
||||||
'common.generate': 'Generate',
|
'common.generate': 'Generate',
|
||||||
|
'common.optional': 'Optional',
|
||||||
'common.found': 'Found',
|
'common.found': 'Found',
|
||||||
'common.missing': 'Missing',
|
'common.missing': 'Missing',
|
||||||
'common.search': 'Search',
|
'common.search': 'Search',
|
||||||
|
|
|
||||||
|
|
@ -680,7 +680,7 @@ function showKiroAuthMethodSelector(providerType) {
|
||||||
modal.style.display = 'flex';
|
modal.style.display = 'flex';
|
||||||
|
|
||||||
modal.innerHTML = `
|
modal.innerHTML = `
|
||||||
<div class="modal-content" style="max-width: 500px;">
|
<div class="modal-content" style="max-width: 550px;">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3><i class="fas fa-key"></i> <span data-i18n="oauth.kiro.selectMethod">${t('oauth.kiro.selectMethod')}</span></h3>
|
<h3><i class="fas fa-key"></i> <span data-i18n="oauth.kiro.selectMethod">${t('oauth.kiro.selectMethod')}</span></h3>
|
||||||
<button class="modal-close">×</button>
|
<button class="modal-close">×</button>
|
||||||
|
|
@ -1727,6 +1727,29 @@ function showAuthModal(authUrl, authInfo) {
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
<p style="margin: 8px 0 0 0; font-size: 0.85rem; color: #92400e;" data-i18n="oauth.modal.portNote">${t('oauth.modal.portNote')}</p>
|
<p style="margin: 8px 0 0 0; font-size: 0.85rem; color: #92400e;" data-i18n="oauth.modal.portNote">${t('oauth.modal.portNote')}</p>
|
||||||
|
${(authInfo.provider === 'claude-kiro-oauth' && authInfo.authMethod === 'builder-id') ? `
|
||||||
|
<div class="builder-id-url-section" style="margin-top: 12px; padding-top: 12px; border-top: 1px dashed #fcd34d;">
|
||||||
|
<label style="display: flex; align-items: center; gap: 6px; margin-bottom: 6px; font-size: 13px; font-weight: 600; color: #92400e;">
|
||||||
|
<i class="fas fa-link"></i>
|
||||||
|
<span data-i18n="oauth.kiro.builderIDStartURL">${t('oauth.kiro.builderIDStartURL') || 'Builder ID Start URL'}</span>
|
||||||
|
<span style="font-weight: normal; color: #b45309;">(${t('common.optional') || '可选'})</span>
|
||||||
|
</label>
|
||||||
|
<div style="display: flex; align-items: center; gap: 4px;">
|
||||||
|
<input type="text" class="builder-id-start-url-input"
|
||||||
|
value="${authInfo.builderIDStartURL || 'https://view.awsapps.com/start'}"
|
||||||
|
placeholder="https://view.awsapps.com/start"
|
||||||
|
style="flex: 1; padding: 6px 10px; border: 1px solid #fcd34d; border-radius: 4px; font-size: 13px; color: #92400e; background: white;"
|
||||||
|
/>
|
||||||
|
<button class="regenerate-builder-id-btn" title="${t('common.generate')}" style="background: none; border: 1px solid #d97706; border-radius: 4px; cursor: pointer; color: #d97706; padding: 4px 8px;">
|
||||||
|
<i class="fas fa-sync-alt"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<p style="margin: 6px 0 0 0; font-size: 0.75rem; color: #b45309;">
|
||||||
|
<i class="fas fa-info-circle"></i>
|
||||||
|
<span data-i18n="oauth.kiro.builderIDStartURLHint">${t('oauth.kiro.builderIDStartURLHint') || '如果您使用 AWS IAM Identity Center,请输入您的 Start URL'}</span>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
</div>
|
</div>
|
||||||
${instructionsHtml}
|
${instructionsHtml}
|
||||||
<div class="auth-url-section">
|
<div class="auth-url-section">
|
||||||
|
|
@ -1780,6 +1803,26 @@ function showAuthModal(authUrl, authInfo) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Builder ID Start URL 重新生成按钮事件
|
||||||
|
const regenerateBuilderIdBtn = modal.querySelector('.regenerate-builder-id-btn');
|
||||||
|
if (regenerateBuilderIdBtn) {
|
||||||
|
regenerateBuilderIdBtn.onclick = async () => {
|
||||||
|
const builderIdStartUrl = modal.querySelector('.builder-id-start-url-input').value.trim();
|
||||||
|
modal.remove();
|
||||||
|
// 构造重新请求的参数
|
||||||
|
const options = {
|
||||||
|
...authInfo,
|
||||||
|
builderIDStartURL: builderIdStartUrl || 'https://view.awsapps.com/start'
|
||||||
|
};
|
||||||
|
// 移除不需要传递回后端的字段
|
||||||
|
delete options.provider;
|
||||||
|
delete options.redirectUri;
|
||||||
|
delete options.callbackPort;
|
||||||
|
|
||||||
|
await executeGenerateAuthUrl(authInfo.provider, options);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// 复制链接按钮
|
// 复制链接按钮
|
||||||
const copyBtn = modal.querySelector('.copy-btn');
|
const copyBtn = modal.querySelector('.copy-btn');
|
||||||
copyBtn.addEventListener('click', () => {
|
copyBtn.addEventListener('click', () => {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue