// 调试脚本:cloud 重启后鉴权链路 + 解密数据完整性回归 // 用法:node dev_test_scripts/debug/debug_cloud_regression.js const BASE = 'http://localhost:8976' const main = async () => { const r1 = await fetch(BASE + '/go?systemId=Tools-cloud', { redirect: 'manual' }) console.log('entry:', r1.status, r1.headers.get('location') ? '(redirect ok)' : '(NO LOCATION)') const r2 = await fetch(new URL(r1.headers.get('location'), BASE), { redirect: 'manual' }) const setc = String(r2.headers.get('set-cookie') || '') console.log('index hop:', r2.status, /cloud_gate=1/.test(setc) ? '(cookie ok)' : '(NO COOKIE)') const r3 = await fetch(BASE + '/tools/cloud/index.html', { headers: { Cookie: 'cloud_gate=1' } }) console.log('index.html:', r3.status) const r4 = await fetch(BASE + '/tools/cloud/cloud.js', { headers: { Cookie: 'cloud_gate=1' } }) console.log('cloud.js:', r4.status) const H = { Cookie: 'cloud_gate=1' } const j = async u => (await fetch(BASE + u, { headers: H })).json() const ops = await j('/api/cloud/operators') const opsEnc = (ops.rows || []).filter(r => r.login_password_enc) const opsDecOk = opsEnc.filter(r => String(r.login_password || '') !== '').length console.log(`operators: ok=${ops.ok} rows=${(ops.rows || []).length} enc=${opsEnc.length} decrypted_non_empty=${opsDecOk}`) const ecs = await j('/api/cloud/ecs') const ecsEnc = (ecs.rows || []).filter(r => r.rdp_password_enc) const ecsDecOk = ecsEnc.filter(r => String(r.rdp_password || '') !== '').length console.log(`ecs: ok=${ecs.ok} rows=${(ecs.rows || []).length} enc=${ecsEnc.length} decrypted_non_empty=${ecsDecOk}`) const vas = await j('/api/cloud/vas') const vasEnc = (vas.rows || []).filter(r => r.access_text_enc) const vasDecOk = vasEnc.filter(r => String(r.access_text || '') !== '').length console.log(`vas: ok=${vas.ok} rows=${(vas.rows || []).length} enc=${vasEnc.length} decrypted_non_empty=${vasDecOk}`) const rn = await j('/api/cloud/renew') console.log(`renew: ok=${rn.ok} rows=${(rn.rows || []).length}`) const nt = await j('/api/cloud/notes') console.log(`notes: ok=${nt.ok} rows=${(nt.rows || []).length}`) const bs = await j('/api/cloud/balance_alerts/status') console.log(`balance status: ok=${bs.ok} proxied=${!!bs.proxied_to_automation} listener=${bs.data && bs.data.listener ? 'present' : 'n/a'}`) const bad = (opsEnc.length !== opsDecOk) || (ecsEnc.length !== ecsDecOk) || (vasEnc.length !== vasDecOk) console.log(bad ? 'REGRESSION FAIL: 存在解密为空的行' : 'REGRESSION PASS') process.exit(bad ? 1 : 0) } main().catch(e => { console.error('ERR', e.message); process.exit(1) })