| #!/usr/bin/env node |
|
|
| |
| |
| |
|
|
| const path = require('path') |
| const dotenv = require('dotenv') |
|
|
| |
| dotenv.config({ path: path.join(__dirname, '..', '.env') }) |
|
|
| const redis = require('../src/models/redis') |
| const geminiAccountService = require('../src/services/geminiAccountService') |
| const crypto = require('crypto') |
| const config = require('../config/config') |
|
|
| |
| const ALGORITHM = 'aes-256-cbc' |
| const ENCRYPTION_SALT = 'gemini-account-salt' |
|
|
| |
| function generateEncryptionKey() { |
| return crypto.scryptSync(config.security.encryptionKey, ENCRYPTION_SALT, 32) |
| } |
|
|
| |
| function debugDecrypt(text) { |
| if (!text) { |
| return { success: false, error: 'Empty text' } |
| } |
| try { |
| const key = generateEncryptionKey() |
| const ivHex = text.substring(0, 32) |
| const encryptedHex = text.substring(33) |
|
|
| const iv = Buffer.from(ivHex, 'hex') |
| const encryptedText = Buffer.from(encryptedHex, 'hex') |
| const decipher = crypto.createDecipheriv(ALGORITHM, key, iv) |
| let decrypted = decipher.update(encryptedText) |
| decrypted = Buffer.concat([decrypted, decipher.final()]) |
| return { success: true, value: decrypted.toString() } |
| } catch (error) { |
| return { success: false, error: error.message } |
| } |
| } |
|
|
| async function testGeminiTokenRefresh() { |
| try { |
| console.log('🚀 开始测试 Gemini token 刷新功能...\n') |
|
|
| |
| console.log('📋 配置信息:') |
| console.log(` 加密密钥: ${config.security.encryptionKey}`) |
| console.log(` 加密盐值: ${ENCRYPTION_SALT}`) |
| console.log() |
|
|
| |
| console.log('📡 连接 Redis...') |
| await redis.connect() |
| console.log('✅ Redis 连接成功\n') |
|
|
| |
| console.log('🔍 获取 Gemini 账户列表...') |
| const accounts = await geminiAccountService.getAllAccounts() |
| const geminiAccounts = accounts.filter((acc) => acc.platform === 'gemini') |
|
|
| if (geminiAccounts.length === 0) { |
| console.log('❌ 没有找到 Gemini 账户') |
| process.exit(1) |
| } |
|
|
| console.log(`✅ 找到 ${geminiAccounts.length} 个 Gemini 账户\n`) |
|
|
| |
| for (const account of geminiAccounts) { |
| console.log(`\n📋 测试账户: ${account.name} (${account.id})`) |
| console.log(` 状态: ${account.status}`) |
|
|
| try { |
| |
| const client = redis.getClient() |
| const rawData = await client.hgetall(`gemini_account:${account.id}`) |
|
|
| console.log(' 📊 原始数据检查:') |
| console.log(` refreshToken 存在: ${rawData.refreshToken ? '是' : '否'}`) |
| if (rawData.refreshToken) { |
| console.log(` refreshToken 长度: ${rawData.refreshToken.length}`) |
| console.log(` refreshToken 前50字符: ${rawData.refreshToken.substring(0, 50)}...`) |
|
|
| |
| const decryptResult = debugDecrypt(rawData.refreshToken) |
| if (decryptResult.success) { |
| console.log(' ✅ 手动解密成功') |
| console.log(` 解密后前20字符: ${decryptResult.value.substring(0, 20)}...`) |
| } else { |
| console.log(` ❌ 手动解密失败: ${decryptResult.error}`) |
| } |
| } |
|
|
| |
| const fullAccount = await geminiAccountService.getAccount(account.id) |
|
|
| if (!fullAccount.refreshToken) { |
| console.log(' ⚠️ 跳过:该账户无 refresh token\n') |
| continue |
| } |
|
|
| console.log(' ✅ 找到 refresh token') |
| console.log( |
| ` 📝 解密后的 refresh token 前20字符: ${fullAccount.refreshToken.substring(0, 20)}...` |
| ) |
|
|
| console.log(' 🔄 开始刷新 token...') |
| const startTime = Date.now() |
|
|
| |
| const newTokens = await geminiAccountService.refreshAccountToken(account.id) |
|
|
| const duration = Date.now() - startTime |
| console.log(` ✅ Token 刷新成功!耗时: ${duration}ms`) |
| console.log(` 📅 新的过期时间: ${new Date(newTokens.expiry_date).toLocaleString()}`) |
| console.log(` 🔑 Access Token: ${newTokens.access_token.substring(0, 20)}...`) |
|
|
| |
| const updatedAccount = await geminiAccountService.getAccount(account.id) |
| console.log(` 📊 账户状态: ${updatedAccount.status}`) |
| } catch (error) { |
| console.log(` ❌ Token 刷新失败: ${error.message}`) |
| console.log(' 🔍 错误详情:', error) |
| } |
| } |
|
|
| console.log('\n✅ 测试完成!') |
| } catch (error) { |
| console.error('❌ 测试失败:', error) |
| } finally { |
| |
| await redis.disconnect() |
| process.exit(0) |
| } |
| } |
|
|
| |
| testGeminiTokenRefresh() |
|
|