///
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;
});