feat(login): kg/tx 登录态自动续期(移植 lx-music-api-server 方案)

- kg: login_by_token 续期(AES-256-CBC + RSA 裸加密,参考其 refresh/kg.py),新 token 回写 data/auth.json
- tx: 新增 sdk/auth/tx.ts —— cookie 解析、VIP 检测(vip_login_base)、
  music.login.LoginServer 续期(走既有 musicu.fcg 未签名通道,最佳努力)
- 调度:启动 10s 后首刷 + 每 24h 一次(对齐参考项目 86400s + next_run_time=now)
- /login/tx 支持可选 App 抓包凭据(openId/accessToken/refreshToken/refreshKey)
- 新增 POST /login/refresh 手动续期;/login/status 增补 tx 字段与更新时间
- 补充 /login/tx 文档行与 smoke 测试
This commit is contained in:
snowy-yang committed 2026-09-29 20:16:33 +08:00
1 parent 9d7cb6f39a
commit aca7928019
8 files changed
+300 -9

No files matched your search

+14 -2
View File
@@ -377,8 +377,20 @@ await test('Swagger UI 规范端点 /docs/json(不可包信封)', async() =>
await test('登录状态 /login/status', async() => {
const r = await get('/login/status')
if (r.code != 0) throw new Error(r.msg)
if (typeof r.data.wy?.logged !== 'boolean' || typeof r.data.kg?.logged !== 'boolean') throw new Error('响应不完整')
return `wy:${r.data.wy.logged} kg:${r.data.kg.logged}`
if (typeof r.data.wy?.logged !== 'boolean' || typeof r.data.kg?.logged !== 'boolean' || typeof r.data.tx?.logged !== 'boolean') {
throw new Error('响应不完整')
}
return `wy:${r.data.wy.logged} kg:${r.data.kg.logged} tx:${r.data.tx.logged}`
})
await test('登录态续期 POST /login/refresh', async() => {
const r = await postJson('/login/refresh', {})
if (r.status !== 200 || r.body?.code !== 0) throw new Error(r.body?.msg ?? `HTTP ${r.status}`)
// 各平台结果为 skipped(未登录)/ refreshed(续期成功)/ error(网关拒绝)之一
const valid = (v: any) => v && (v.skipped || v.refreshed || v.error)
if (!valid(r.body.data?.kg) || !valid(r.body.data?.tx)) throw new Error(`响应结构异常: ${JSON.stringify(r.body.data)}`)
const brief = (v: any) => v.skipped ? 'skipped' : v.refreshed ? 'refreshed' : `error(${v.error})`
return `kg:${brief(r.body.data.kg)} tx:${brief(r.body.data.tx)}`
})
await test('扫码二维码创建 POST /login/wy/qr', async() => {