aiclient-2-api / src /scripts /kiro-idc-token-refresh.js
Jaasomn
Initial deployment
ceb3821
/**
* Kiro IDC Token Refresh Tool
* 通过 refreshToken + clientId + clientSecret 获取 accessToken (基于 AWS OIDC/IDC)
*
* 使用方法:
* 1. 位置参数模式:
* node src/kiro-idc-token-refresh.js <refreshToken> <clientId> <clientSecret> [authMethod] [provider]
* 2. JSON 文件模式:
* node src/kiro-idc-token-refresh.js ./config.json
* 3. JSON 字符串模式:
* node src/kiro-idc-token-refresh.js '{"refreshToken": "...", "clientId": "...", "clientSecret": "..."}'
*
* 参数:
* refreshToken - Kiro 的 refresh token
* clientId - AWS OIDC client ID
* clientSecret - AWS OIDC client secret
* authMethod - 认证方法 (可选,默认: IdC)
* provider - 提供商 (可选,默认: BuilderId)
*
* 输出格式:
* {
* "accessToken": "aoaAAAA",
* "refreshToken": "aorAAAAAGnTpTMP_mR",
* "expiresAt": "2026-01-06T14:22:16.130Z",
* "authMethod": "IdC",
* "provider": "BuilderId",
* "clientId": "e8pqSrALVjvbqaW",
* "clientSecret": "eyJraWQiOiJrZXktMTU2NDAy",
* "region": "us-east-1"
* }
*/
import axios from 'axios';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// 获取当前脚本所在目录
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const KIRO_IDC_CONSTANTS = {
REFRESH_IDC_URL: 'https://oidc.{{region}}.amazonaws.com/token',
CONTENT_TYPE_JSON: 'application/json',
DEFAULT_AUTH_METHOD: 'IdC',
DEFAULT_PROVIDER: 'BuilderId',
DEFAULT_REGION: 'us-east-1',
AXIOS_TIMEOUT: 30000, // 30 seconds timeout
};
/**
* 通过 IDC (AWS OIDC) 刷新 token
* @param {string} refreshToken - Kiro 的 refresh token
* @param {string} clientId - AWS OIDC client ID
* @param {string} clientSecret - AWS OIDC client secret
* @param {Object} options - 可选参数
* @param {string} options.authMethod - 认证方法 (默认: IdC)
* @param {string} options.provider - 提供商 (默认: BuilderId)
* @param {string} options.region - AWS 区域 (默认: us-east-1)
* @returns {Promise<Object>} 包含 accessToken 等信息的对象
*/
async function refreshKiroIdcToken(refreshToken, clientId, clientSecret, options = {}) {
const authMethod = options.authMethod || KIRO_IDC_CONSTANTS.DEFAULT_AUTH_METHOD;
const provider = options.provider || KIRO_IDC_CONSTANTS.DEFAULT_PROVIDER;
const region = options.region || KIRO_IDC_CONSTANTS.DEFAULT_REGION;
const refreshUrl = KIRO_IDC_CONSTANTS.REFRESH_IDC_URL.replace('{{region}}', region);
// IDC/OIDC 使用 form-urlencoded 格式
const requestBody = {
grantType: 'refresh_token',
refreshToken: refreshToken,
clientId: clientId,
clientSecret: clientSecret,
};
const axiosConfig = {
timeout: KIRO_IDC_CONSTANTS.AXIOS_TIMEOUT,
headers: {
'Content-Type': KIRO_IDC_CONSTANTS.CONTENT_TYPE_JSON,
'User-Agent': 'KiroIDE'
},
};
try {
console.log(`[Kiro IDC Token Refresh] 正在请求: ${refreshUrl}`);
const response = await axios.post(refreshUrl, requestBody, axiosConfig);
// AWS OIDC 返回格式: { access_token, refresh_token, expires_in, token_type }
if (response.data && response.data.accessToken) {
const expiresIn = response.data.expiresIn;
const expiresAt = new Date(Date.now() + expiresIn * 1000).toISOString();
const result = {
accessToken: response.data.accessToken,
refreshToken: response.data.refreshToken || refreshToken,
expiresAt: expiresAt,
authMethod: authMethod,
provider: provider,
clientId: clientId,
clientSecret: clientSecret,
region: region,
};
return result;
} else {
throw new Error('Invalid refresh response: Missing access_token');
}
} catch (error) {
if (error.response) {
console.error(`[Kiro IDC Token Refresh] 请求失败: HTTP ${error.response.status}`);
console.error(`[Kiro IDC Token Refresh] 响应内容:`, error.response.data);
} else if (error.request) {
console.error(`[Kiro IDC Token Refresh] 请求失败: 无响应`);
} else {
console.error(`[Kiro IDC Token Refresh] 请求失败:`, error.message);
}
throw error;
}
}
/**
* 主函数 - 命令行入口
*/
async function main() {
const args = process.argv.slice(2);
let refreshToken, clientId, clientSecret, authMethod, provider;
// 1. 尝试解析第一个参数为 JSON 文件路径
if (args.length === 1 && args[0].toLowerCase().endsWith('.json')) {
try {
const jsonPath = path.isAbsolute(args[0]) ? args[0] : path.resolve(process.cwd(), args[0]);
if (fs.existsSync(jsonPath)) {
console.log(`[Kiro IDC Token Refresh] 正在从文件读取配置: ${jsonPath}`);
const fileContent = fs.readFileSync(jsonPath, 'utf-8');
const parsed = JSON.parse(fileContent);
refreshToken = parsed.refreshToken;
clientId = parsed.clientId;
clientSecret = parsed.clientSecret;
authMethod = parsed.authMethod;
provider = parsed.provider;
} else {
console.error(`错误: 找不到文件 ${jsonPath}`);
process.exit(1);
}
} catch (e) {
console.error(`错误: 读取或解析 JSON 文件失败: ${e.message}`);
process.exit(1);
}
}
// 2. 尝试解析第一个参数为 JSON 字符串
else if (args.length === 1 && args[0].trim().startsWith('{')) {
try {
const parsed = JSON.parse(args[0]);
refreshToken = parsed.refreshToken;
clientId = parsed.clientId;
clientSecret = parsed.clientSecret;
authMethod = parsed.authMethod;
provider = parsed.provider;
} catch (e) {
// JSON 解析失败,将回退到位置参数处理
}
}
// 如果没有通过 JSON 成功获取参数,则尝试位置参数
if (!refreshToken) {
if (args.length === 0 || args.length < 3) {
console.log('Kiro IDC Token Refresh Tool');
console.log('============================');
console.log('');
console.log('使用方法:');
console.log(' 1. 位置参数模式:');
console.log(' node src/kiro-idc-token-refresh.js <refreshToken> <clientId> <clientSecret> [authMethod] [provider]');
console.log(' 2. JSON 文件模式:');
console.log(' node src/kiro-idc-token-refresh.js ./config.json');
console.log(' 3. JSON 字符串模式:');
console.log(' node src/kiro-idc-token-refresh.js \'{"refreshToken": "...", "clientId": "...", "clientSecret": "...", "authMethod": "...", "provider": "..."}\'');
console.log('');
console.log('参数:');
console.log(' refreshToken - Kiro 的 refresh token (必需)');
console.log(' clientId - AWS OIDC client ID (必需)');
console.log(' clientSecret - AWS OIDC client secret (必需)');
console.log(' authMethod - 认证方法 (可选,默认: IdC)');
console.log(' provider - 提供商 (可选,默认: BuilderId)');
console.log('');
console.log('示例:');
console.log(' node src/kiro-idc-token-refresh.js aorAxxxxxxxx e8pqSrALVjvbqaW eyJraWQiOiJrZXktMTU2NDAy');
console.log(' node src/kiro-idc-token-refresh.js aorAxxxxxxxx e8pqSrALVjvbqaW eyJraWQiOiJrZXktMTU2NDAy IdC Enterprise');
console.log('');
console.log('输出格式:');
console.log(JSON.stringify({
accessToken: "aoaAAAA...",
refreshToken: "aorAAAAAGnTpTMP_mR...",
expiresAt: "2026-01-06T14:22:16.130Z",
authMethod: "IdC",
provider: "BuilderId",
clientId: "e8pqSrALVjvbqaW",
clientSecret: "eyJraWQiOiJrZXktMTU2NDAy",
region: "us-east-1"
}, null, 2));
process.exit(0);
}
refreshToken = args[0];
clientId = args[1];
clientSecret = args[2];
authMethod = args[3];
provider = args[4];
}
// 设置默认值
authMethod = authMethod || KIRO_IDC_CONSTANTS.DEFAULT_AUTH_METHOD;
provider = provider || KIRO_IDC_CONSTANTS.DEFAULT_PROVIDER;
if (!refreshToken) {
console.error('错误: 请提供 refreshToken');
process.exit(1);
}
if (!clientId) {
console.error('错误: 请提供 clientId');
process.exit(1);
}
if (!clientSecret) {
console.error('错误: 请提供 clientSecret');
process.exit(1);
}
try {
console.log(`[Kiro IDC Token Refresh] 开始刷新 token...`);
console.log(`[Kiro IDC Token Refresh] 认证方法: ${authMethod}`);
console.log(`[Kiro IDC Token Refresh] 提供商: ${provider}`);
console.log(`[Kiro IDC Token Refresh] Client ID: ${clientId.substring(0, 8)}...`);
const result = await refreshKiroIdcToken(refreshToken, clientId, clientSecret, {
authMethod,
provider,
region: KIRO_IDC_CONSTANTS.DEFAULT_REGION
});
console.log('');
console.log('=== Token 刷新成功 ===');
console.log('');
console.log(JSON.stringify(result, null, 2));
// 输出过期时间信息
const expiresDate = new Date(result.expiresAt);
const now = new Date();
const diffMs = expiresDate - now;
const diffMins = Math.floor(diffMs / 60000);
const diffHours = Math.floor(diffMins / 60);
console.log('');
console.log(`[Kiro IDC Token Refresh] Token 将在 ${diffHours} 小时 ${diffMins % 60} 分钟后过期`);
console.log(`[Kiro IDC Token Refresh] 过期时间: ${result.expiresAt}`);
// 写入 JSON 文件到脚本执行目录
const timestamp = Date.now();
const outputFileName = `kiro-idc-${timestamp}-auth-token.json`;
const outputFilePath = path.join(__dirname, outputFileName);
fs.writeFileSync(outputFilePath, JSON.stringify(result, null, 2), 'utf-8');
console.log('');
console.log(`[Kiro IDC Token Refresh] Token 已保存到文件: ${outputFilePath}`);
} catch (error) {
console.error('');
console.error('=== Token 刷新失败 ===');
console.error(`错误: ${error.message}`);
process.exit(1);
}
}
// 导出函数供其他模块使用
export { refreshKiroIdcToken };
// 如果直接运行此脚本,执行主函数
main();