feat(claude-kiro): 支持AWS企业用户idcRegion字段并优化模型配置
- 在AWS凭据导入说明中增加idcRegion字段要求 - 移除不再使用的Amazon Q相关URL和旧模型映射 - 为Builder ID认证流程添加region选择和idcRegion支持 - 优化凭据加载逻辑,支持独立配置idcRegion - 在UI中添加region输入框和刷新按钮
This commit is contained in:
parent
37dab55d49
commit
785ac7890d
4 changed files with 56 additions and 32 deletions
|
|
@ -16,7 +16,7 @@ const KIRO_OAUTH_CONFIG = {
|
||||||
authServiceEndpoint: 'https://prod.us-east-1.auth.desktop.kiro.dev',
|
authServiceEndpoint: 'https://prod.us-east-1.auth.desktop.kiro.dev',
|
||||||
|
|
||||||
// AWS SSO OIDC 端点 (用于 Builder ID)
|
// AWS SSO OIDC 端点 (用于 Builder ID)
|
||||||
ssoOIDCEndpoint: 'https://oidc.us-east-1.amazonaws.com',
|
ssoOIDCEndpoint: 'https://oidc.{{region}}.amazonaws.com',
|
||||||
|
|
||||||
// AWS Builder ID 起始 URL
|
// AWS Builder ID 起始 URL
|
||||||
builderIDStartURL: 'https://view.awsapps.com/start',
|
builderIDStartURL: 'https://view.awsapps.com/start',
|
||||||
|
|
@ -34,8 +34,8 @@ const KIRO_OAUTH_CONFIG = {
|
||||||
'codewhisperer:completions',
|
'codewhisperer:completions',
|
||||||
'codewhisperer:analysis',
|
'codewhisperer:analysis',
|
||||||
'codewhisperer:conversations',
|
'codewhisperer:conversations',
|
||||||
'codewhisperer:transformations',
|
// 'codewhisperer:transformations',
|
||||||
'codewhisperer:taskassist'
|
// 'codewhisperer:taskassist'
|
||||||
],
|
],
|
||||||
|
|
||||||
// 凭据存储(符合现有规范)
|
// 凭据存储(符合现有规范)
|
||||||
|
|
@ -252,7 +252,10 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) {
|
||||||
console.log(`${KIRO_OAUTH_CONFIG.logPrefix} Using Builder ID Start URL: ${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 region = options.region || 'us-east-1';
|
||||||
|
const ssoOIDCEndpoint = KIRO_OAUTH_CONFIG.ssoOIDCEndpoint.replace('{{region}}', region);
|
||||||
|
|
||||||
|
const regResponse = await fetchWithProxy(`${ssoOIDCEndpoint}/client/register`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -262,7 +265,7 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) {
|
||||||
clientName: 'Kiro IDE',
|
clientName: 'Kiro IDE',
|
||||||
clientType: 'public',
|
clientType: 'public',
|
||||||
scopes: KIRO_OAUTH_CONFIG.scopes,
|
scopes: KIRO_OAUTH_CONFIG.scopes,
|
||||||
grantTypes: ['urn:ietf:params:oauth:grant-type:device_code', 'refresh_token']
|
// grantTypes: ['urn:ietf:params:oauth:grant-type:device_code', 'refresh_token']
|
||||||
})
|
})
|
||||||
}, 'claude-kiro-oauth');
|
}, 'claude-kiro-oauth');
|
||||||
|
|
||||||
|
|
@ -273,11 +276,10 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) {
|
||||||
const regData = await regResponse.json();
|
const regData = await regResponse.json();
|
||||||
|
|
||||||
// 2. 启动设备授权
|
// 2. 启动设备授权
|
||||||
const authResponse = await fetchWithProxy(`${KIRO_OAUTH_CONFIG.ssoOIDCEndpoint}/device_authorization`, {
|
const authResponse = await fetchWithProxy(`${ssoOIDCEndpoint}/device_authorization`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json'
|
||||||
'User-Agent': 'KiroIDE'
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
clientId: regData.clientId,
|
clientId: regData.clientId,
|
||||||
|
|
@ -304,7 +306,7 @@ async function handleKiroBuilderIDDeviceCode(currentConfig, options = {}) {
|
||||||
5,
|
5,
|
||||||
300,
|
300,
|
||||||
taskId,
|
taskId,
|
||||||
options
|
{ ...options, region }
|
||||||
).catch(error => {
|
).catch(error => {
|
||||||
console.error(`${KIRO_OAUTH_CONFIG.logPrefix} 轮询失败 [${taskId}]:`, error);
|
console.error(`${KIRO_OAUTH_CONFIG.logPrefix} 轮询失败 [${taskId}]:`, error);
|
||||||
broadcastEvent('oauth_error', {
|
broadcastEvent('oauth_error', {
|
||||||
|
|
@ -356,7 +358,9 @@ async function pollKiroBuilderIDToken(clientId, clientSecret, deviceCode, interv
|
||||||
attempts++;
|
attempts++;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await fetchWithProxy(`${KIRO_OAUTH_CONFIG.ssoOIDCEndpoint}/token`, {
|
const region = options.region || 'us-east-1';
|
||||||
|
const ssoOIDCEndpoint = KIRO_OAUTH_CONFIG.ssoOIDCEndpoint.replace('{{region}}', region);
|
||||||
|
const response = await fetchWithProxy(`${ssoOIDCEndpoint}/token`, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|
@ -391,7 +395,7 @@ async function pollKiroBuilderIDToken(clientId, clientSecret, deviceCode, interv
|
||||||
authMethod: 'builder-id',
|
authMethod: 'builder-id',
|
||||||
clientId,
|
clientId,
|
||||||
clientSecret,
|
clientSecret,
|
||||||
region: 'us-east-1'
|
idcRegion: options.region || 'us-east-1'
|
||||||
};
|
};
|
||||||
|
|
||||||
await fs.promises.mkdir(path.dirname(credPath), { recursive: true });
|
await fs.promises.mkdir(path.dirname(credPath), { recursive: true });
|
||||||
|
|
@ -634,7 +638,8 @@ const KIRO_REFRESH_CONSTANTS = {
|
||||||
AUTH_METHOD_SOCIAL: 'social',
|
AUTH_METHOD_SOCIAL: 'social',
|
||||||
DEFAULT_PROVIDER: 'Google',
|
DEFAULT_PROVIDER: 'Google',
|
||||||
REQUEST_TIMEOUT: 30000,
|
REQUEST_TIMEOUT: 30000,
|
||||||
DEFAULT_REGION: 'us-east-1'
|
DEFAULT_REGION: 'us-east-1',
|
||||||
|
IDC_REGION: 'us-east-1' // 用于 REFRESH_IDC_URL 的区域配置
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1024,7 +1029,8 @@ export async function importAwsCredentials(credentials, skipDuplicateCheck = fal
|
||||||
accessToken: credentials.accessToken,
|
accessToken: credentials.accessToken,
|
||||||
refreshToken: credentials.refreshToken,
|
refreshToken: credentials.refreshToken,
|
||||||
authMethod: credentials.authMethod || 'builder-id',
|
authMethod: credentials.authMethod || 'builder-id',
|
||||||
region: credentials.region || KIRO_REFRESH_CONSTANTS.DEFAULT_REGION
|
// region: credentials.region || KIRO_REFRESH_CONSTANTS.DEFAULT_REGION,
|
||||||
|
idcRegion: credentials.idcRegion || KIRO_REFRESH_CONSTANTS.IDC_REGION
|
||||||
};
|
};
|
||||||
|
|
||||||
// 可选字段
|
// 可选字段
|
||||||
|
|
@ -1042,8 +1048,8 @@ export async function importAwsCredentials(credentials, skipDuplicateCheck = fal
|
||||||
try {
|
try {
|
||||||
console.log(`${KIRO_OAUTH_CONFIG.logPrefix} Attempting to refresh token with provided credentials...`);
|
console.log(`${KIRO_OAUTH_CONFIG.logPrefix} Attempting to refresh token with provided credentials...`);
|
||||||
|
|
||||||
const region = credentials.region || KIRO_REFRESH_CONSTANTS.DEFAULT_REGION;
|
const refreshRegion = credentials.idcRegion || KIRO_REFRESH_CONSTANTS.IDC_REGION;
|
||||||
const refreshUrl = KIRO_REFRESH_CONSTANTS.REFRESH_IDC_URL.replace('{{region}}', region);
|
const refreshUrl = KIRO_REFRESH_CONSTANTS.REFRESH_IDC_URL.replace('{{region}}', refreshRegion);
|
||||||
|
|
||||||
const refreshResponse = await fetchWithProxy(refreshUrl, {
|
const refreshResponse = await fetchWithProxy(refreshUrl, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,7 @@ const KIRO_CONSTANTS = {
|
||||||
REFRESH_URL: 'https://prod.{{region}}.auth.desktop.kiro.dev/refreshToken',
|
REFRESH_URL: 'https://prod.{{region}}.auth.desktop.kiro.dev/refreshToken',
|
||||||
REFRESH_IDC_URL: 'https://oidc.{{region}}.amazonaws.com/token',
|
REFRESH_IDC_URL: 'https://oidc.{{region}}.amazonaws.com/token',
|
||||||
BASE_URL: 'https://q.{{region}}.amazonaws.com/generateAssistantResponse',
|
BASE_URL: 'https://q.{{region}}.amazonaws.com/generateAssistantResponse',
|
||||||
AMAZON_Q_URL: 'https://codewhisperer.{{region}}.amazonaws.com/SendMessageStreaming',
|
DEFAULT_MODEL_NAME: 'claude-sonnet-4-5',
|
||||||
USAGE_LIMITS_URL: 'https://q.{{region}}.amazonaws.com/getUsageLimits',
|
|
||||||
DEFAULT_MODEL_NAME: 'claude-opus-4-5',
|
|
||||||
AXIOS_TIMEOUT: 120000, // 2 minutes timeout for normal requests
|
AXIOS_TIMEOUT: 120000, // 2 minutes timeout for normal requests
|
||||||
TOKEN_REFRESH_TIMEOUT: 15000, // 15 seconds timeout for token refresh (shorter to avoid blocking)
|
TOKEN_REFRESH_TIMEOUT: 15000, // 15 seconds timeout for token refresh (shorter to avoid blocking)
|
||||||
USER_AGENT: 'KiroIDE',
|
USER_AGENT: 'KiroIDE',
|
||||||
|
|
@ -49,9 +47,7 @@ const FULL_MODEL_MAPPING = {
|
||||||
"claude-opus-4-5":"claude-opus-4.5",
|
"claude-opus-4-5":"claude-opus-4.5",
|
||||||
"claude-opus-4-5-20251101":"claude-opus-4.5",
|
"claude-opus-4-5-20251101":"claude-opus-4.5",
|
||||||
"claude-sonnet-4-5": "CLAUDE_SONNET_4_5_20250929_V1_0",
|
"claude-sonnet-4-5": "CLAUDE_SONNET_4_5_20250929_V1_0",
|
||||||
"claude-sonnet-4-5-20250929": "CLAUDE_SONNET_4_5_20250929_V1_0",
|
"claude-sonnet-4-5-20250929": "CLAUDE_SONNET_4_5_20250929_V1_0"
|
||||||
"claude-sonnet-4-20250514": "CLAUDE_SONNET_4_20250514_V1_0",
|
|
||||||
"claude-3-7-sonnet-20250219": "CLAUDE_3_7_SONNET_20250219_V1_0"
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 只保留 KIRO_MODELS 中存在的模型映射
|
// 只保留 KIRO_MODELS 中存在的模型映射
|
||||||
|
|
@ -362,7 +358,6 @@ export class KiroApiService {
|
||||||
// this.refreshUrl = KIRO_CONSTANTS.REFRESH_URL;
|
// this.refreshUrl = KIRO_CONSTANTS.REFRESH_URL;
|
||||||
// this.refreshIDCUrl = KIRO_CONSTANTS.REFRESH_IDC_URL;
|
// this.refreshIDCUrl = KIRO_CONSTANTS.REFRESH_IDC_URL;
|
||||||
// this.baseUrl = KIRO_CONSTANTS.BASE_URL;
|
// this.baseUrl = KIRO_CONSTANTS.BASE_URL;
|
||||||
// this.amazonQUrl = KIRO_CONSTANTS.AMAZON_Q_URL;
|
|
||||||
|
|
||||||
// Add kiro-oauth-creds-base64 and kiro-oauth-creds-file to config
|
// Add kiro-oauth-creds-base64 and kiro-oauth-creds-file to config
|
||||||
if (config.KIRO_OAUTH_CREDS_BASE64) {
|
if (config.KIRO_OAUTH_CREDS_BASE64) {
|
||||||
|
|
@ -536,16 +531,21 @@ async loadCredentials() {
|
||||||
this.expiresAt = this.expiresAt || mergedCredentials.expiresAt;
|
this.expiresAt = this.expiresAt || mergedCredentials.expiresAt;
|
||||||
this.profileArn = this.profileArn || mergedCredentials.profileArn;
|
this.profileArn = this.profileArn || mergedCredentials.profileArn;
|
||||||
this.region = this.region || mergedCredentials.region;
|
this.region = this.region || mergedCredentials.region;
|
||||||
|
this.idcRegion = this.idcRegion || mergedCredentials.idcRegion;
|
||||||
|
|
||||||
if (!this.region) {
|
if (!this.region) {
|
||||||
console.warn('[Kiro Auth] Region not found in credentials. Using default region us-east-1 for URLs.');
|
console.warn('[Kiro Auth] Region not found in credentials. Using default region us-east-1 for URLs.');
|
||||||
this.region = 'us-east-1';
|
this.region = 'us-east-1';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// idcRegion 用于 REFRESH_IDC_URL,如果未设置则使用 region
|
||||||
|
if (!this.idcRegion) {
|
||||||
|
this.idcRegion = this.region;
|
||||||
|
}
|
||||||
|
|
||||||
this.refreshUrl = (this.config.KIRO_REFRESH_URL || KIRO_CONSTANTS.REFRESH_URL).replace("{{region}}", this.region);
|
this.refreshUrl = (this.config.KIRO_REFRESH_URL || KIRO_CONSTANTS.REFRESH_URL).replace("{{region}}", this.region);
|
||||||
this.refreshIDCUrl = (this.config.KIRO_REFRESH_IDC_URL || KIRO_CONSTANTS.REFRESH_IDC_URL).replace("{{region}}", this.region);
|
this.refreshIDCUrl = (this.config.KIRO_REFRESH_IDC_URL || KIRO_CONSTANTS.REFRESH_IDC_URL).replace("{{region}}", this.idcRegion);
|
||||||
this.baseUrl = (this.config.KIRO_BASE_URL || KIRO_CONSTANTS.BASE_URL).replace("{{region}}", this.region);
|
this.baseUrl = (this.config.KIRO_BASE_URL || KIRO_CONSTANTS.BASE_URL).replace("{{region}}", this.region);
|
||||||
this.amazonQUrl = (KIRO_CONSTANTS.AMAZON_Q_URL).replace("{{region}}", this.region);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`[Kiro Auth] Error during credential loading: ${error.message}`);
|
console.warn(`[Kiro Auth] Error during credential loading: ${error.message}`);
|
||||||
}
|
}
|
||||||
|
|
@ -2724,7 +2724,8 @@ async saveCredentialsToFile(filePath, newData) {
|
||||||
const resourceType = 'AGENTIC_REQUEST';
|
const resourceType = 'AGENTIC_REQUEST';
|
||||||
|
|
||||||
// 构建请求 URL
|
// 构建请求 URL
|
||||||
const usageLimitsUrl = KIRO_CONSTANTS.USAGE_LIMITS_URL.replace('{{region}}', this.region);
|
let usageLimitsUrl = this.baseUrl;
|
||||||
|
usageLimitsUrl = usageLimitsUrl.replace('generateAssistantResponse', 'getUsageLimits');
|
||||||
const params = new URLSearchParams({
|
const params = new URLSearchParams({
|
||||||
isEmailRequired: 'true',
|
isEmailRequired: 'true',
|
||||||
origin: KIRO_CONSTANTS.ORIGIN_AI_EDITOR,
|
origin: KIRO_CONSTANTS.ORIGIN_AI_EDITOR,
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ const translations = {
|
||||||
'oauth.kiro.batchImportInstructions': '请输入 refreshToken,每行一个。系统将自动刷新并生成凭据文件。',
|
'oauth.kiro.batchImportInstructions': '请输入 refreshToken,每行一个。系统将自动刷新并生成凭据文件。',
|
||||||
'oauth.kiro.awsImport': '导入 AWS 账号',
|
'oauth.kiro.awsImport': '导入 AWS 账号',
|
||||||
'oauth.kiro.awsImportDesc': '从 AWS SSO cache 目录导入凭据文件,适用于 AWS Builder ID 模式。',
|
'oauth.kiro.awsImportDesc': '从 AWS SSO cache 目录导入凭据文件,适用于 AWS Builder ID 模式。',
|
||||||
'oauth.kiro.awsImportInstructions': '请上传 AWS SSO cache 目录中的 JSON 文件,需包含 clientId、clientSecret、accessToken、refreshToken 四个字段。',
|
'oauth.kiro.awsImportInstructions': '请上传 AWS SSO cache 目录中的 JSON 文件,需包含 clientId、clientSecret、accessToken、refreshToken 四个字段。如果是AWS企业用户,需增加 idcRegion 字段。',
|
||||||
'oauth.kiro.awsModeFile': '文件上传',
|
'oauth.kiro.awsModeFile': '文件上传',
|
||||||
'oauth.kiro.awsModeJson': 'JSON 粘贴',
|
'oauth.kiro.awsModeJson': 'JSON 粘贴',
|
||||||
'oauth.kiro.awsUploadFiles': '上传凭据文件',
|
'oauth.kiro.awsUploadFiles': '上传凭据文件',
|
||||||
|
|
@ -856,7 +856,7 @@ const translations = {
|
||||||
'oauth.kiro.batchImportInstructions': 'Enter refreshTokens, one per line. The system will automatically refresh and generate credential files.',
|
'oauth.kiro.batchImportInstructions': 'Enter refreshTokens, one per line. The system will automatically refresh and generate credential files.',
|
||||||
'oauth.kiro.awsImport': 'Import AWS Account',
|
'oauth.kiro.awsImport': 'Import AWS Account',
|
||||||
'oauth.kiro.awsImportDesc': 'Import credential files from AWS SSO cache directory. For AWS Builder ID mode.',
|
'oauth.kiro.awsImportDesc': 'Import credential files from AWS SSO cache directory. For AWS Builder ID mode.',
|
||||||
'oauth.kiro.awsImportInstructions': 'Upload JSON files from AWS SSO cache directory. Must contain clientId, clientSecret, accessToken, and refreshToken.',
|
'oauth.kiro.awsImportInstructions': 'Upload JSON files from AWS SSO cache directory. Must contain clientId, clientSecret, accessToken, and refreshToken. For AWS enterprise users, add the idcRegion field.',
|
||||||
'oauth.kiro.awsModeFile': 'File Upload',
|
'oauth.kiro.awsModeFile': 'File Upload',
|
||||||
'oauth.kiro.awsModeJson': 'Paste JSON',
|
'oauth.kiro.awsModeJson': 'Paste JSON',
|
||||||
'oauth.kiro.awsUploadFiles': 'Upload Credential Files',
|
'oauth.kiro.awsUploadFiles': 'Upload Credential Files',
|
||||||
|
|
|
||||||
|
|
@ -1723,7 +1723,12 @@ function showAuthModal(authUrl, authInfo) {
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="auth-info">
|
<div class="auth-info">
|
||||||
<p><strong data-i18n="oauth.modal.provider">${t('oauth.modal.provider')}</strong> ${authInfo.provider}</p>
|
<p><strong data-i18n="oauth.modal.provider">${t('oauth.modal.provider')}</strong> ${authInfo.provider}</p>
|
||||||
<div class="port-info-section" style="margin: 12px 0; padding: 12px; background: #fef3c7; border: 1px solid #fcd34d; border-radius: 8px;">
|
<div class="port-info-section" style="margin: 12px 0; padding: 12px; background: #fef3c7; border: 1px solid #fcd34d; border-radius: 8px; position: relative;">
|
||||||
|
${(authInfo.provider === 'claude-kiro-oauth' && authInfo.authMethod === 'builder-id') ? `
|
||||||
|
<button class="regenerate-builder-id-btn" title="${t('common.generate')}" style="position: absolute; top: 12px; right: 12px; 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 style="margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
|
<div style="margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap;">
|
||||||
<i class="fas fa-network-wired" style="color: #d97706;"></i>
|
<i class="fas fa-network-wired" style="color: #d97706;"></i>
|
||||||
<strong data-i18n="oauth.modal.requiredPort">${t('oauth.modal.requiredPort')}</strong>
|
<strong data-i18n="oauth.modal.requiredPort">${t('oauth.modal.requiredPort')}</strong>
|
||||||
|
|
@ -1751,15 +1756,25 @@ function showAuthModal(authUrl, authInfo) {
|
||||||
placeholder="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;"
|
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>
|
</div>
|
||||||
<p style="margin: 6px 0 0 0; font-size: 0.75rem; color: #b45309;">
|
<p style="margin: 6px 0 0 0; font-size: 0.75rem; color: #b45309;">
|
||||||
<i class="fas fa-info-circle"></i>
|
<i class="fas fa-info-circle"></i>
|
||||||
<span data-i18n="oauth.kiro.builderIDStartURLHint">${t('oauth.kiro.builderIDStartURLHint') || '如果您使用 AWS IAM Identity Center,请输入您的 Start URL'}</span>
|
<span data-i18n="oauth.kiro.builderIDStartURLHint">${t('oauth.kiro.builderIDStartURLHint') || '如果您使用 AWS IAM Identity Center,请输入您的 Start URL'}</span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="builder-id-region-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-globe"></i>
|
||||||
|
<span>AWS Region</span>
|
||||||
|
</label>
|
||||||
|
<div style="display: flex; align-items: center; gap: 4px;">
|
||||||
|
<input type="text" class="builder-id-region-input"
|
||||||
|
value="${authInfo.region || 'us-east-1'}"
|
||||||
|
placeholder="us-east-1"
|
||||||
|
style="flex: 1; padding: 6px 10px; border: 1px solid #fcd34d; border-radius: 4px; font-size: 13px; color: #92400e; background: white;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
` : ''}
|
` : ''}
|
||||||
</div>
|
</div>
|
||||||
${instructionsHtml}
|
${instructionsHtml}
|
||||||
|
|
@ -1819,11 +1834,13 @@ function showAuthModal(authUrl, authInfo) {
|
||||||
if (regenerateBuilderIdBtn) {
|
if (regenerateBuilderIdBtn) {
|
||||||
regenerateBuilderIdBtn.onclick = async () => {
|
regenerateBuilderIdBtn.onclick = async () => {
|
||||||
const builderIdStartUrl = modal.querySelector('.builder-id-start-url-input').value.trim();
|
const builderIdStartUrl = modal.querySelector('.builder-id-start-url-input').value.trim();
|
||||||
|
const region = modal.querySelector('.builder-id-region-input').value.trim();
|
||||||
modal.remove();
|
modal.remove();
|
||||||
// 构造重新请求的参数
|
// 构造重新请求的参数
|
||||||
const options = {
|
const options = {
|
||||||
...authInfo,
|
...authInfo,
|
||||||
builderIDStartURL: builderIdStartUrl || 'https://view.awsapps.com/start'
|
builderIDStartURL: builderIdStartUrl || 'https://view.awsapps.com/start',
|
||||||
|
region: region || 'us-east-1'
|
||||||
};
|
};
|
||||||
// 移除不需要传递回后端的字段
|
// 移除不需要传递回后端的字段
|
||||||
delete options.provider;
|
delete options.provider;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue