/// import datasource from '../datasource'; import { encryptSecret, isEncryptedSecret } from '../src/integration/config/secret-crypto'; import { IntegrationConfigDetail } from '../src/integration/entities/integration-config.entity'; /** integration_config_detail.content JSON 中与本次回填相关的结构。 */ interface StoredConfigContent { type?: unknown; verify?: unknown; config?: Record; } async function main(): Promise { // 主动检查加密密钥:缺失时 getEncryptionKey() 会静默使用开发回退密钥, // 绝不能用回退密钥加密生产数据,因此未配置时直接报错退出。 if (!process.env.AI_CONFIG_ENCRYPTION_KEY) { throw new Error( 'AI_CONFIG_ENCRYPTION_KEY 未设置:为避免使用开发回退密钥加密数据,请先配置 AI_CONFIG_ENCRYPTION_KEY 再运行回填脚本', ); } await datasource.initialize(); console.log('已连接数据库,开始回填第三方集成配置 appSecret 加密...'); try { const repo = datasource.getRepository(IntegrationConfigDetail); const rows = await repo.find(); let processed = 0; for (const row of rows) { if (!row.content) continue; let parsed: StoredConfigContent; try { parsed = JSON.parse(row.content) as StoredConfigContent; } catch { continue; } const config = parsed.config; if (!config || typeof config !== 'object' || Array.isArray(config)) continue; const appSecret = config.appSecret; if (typeof appSecret !== 'string' || !appSecret || isEncryptedSecret(appSecret)) continue; config.appSecret = encryptSecret(appSecret); row.content = JSON.stringify(parsed); await repo.save(row); processed += 1; } console.log(`回填完成:共处理 ${processed} 行(加密 appSecret)`); } finally { // 无论成功还是失败都关闭连接池,避免泄漏 try { await datasource.destroy(); } catch { // 销毁失败不影响主流程结果 } } } main().catch((error) => { console.error('回填失败:', error); process.exitCode = 1; });