feat: StarLight 第三方登录 + 安全加固 + 循环池 + 热配置

功能:
- StarLight Yggdrasil 第三方登录(后端中转,accessToken 不落地)
- 管理员可视化权限管理(用户列表 + 一键授予/移出)
- 设置页热配置(11 项可编辑,立即生效)
- 循环池(每流独立手动歌单,队列空时随机不重复抽取)
- 登录页统一主站浅色风格
- 全站改名「Starlight专属电台」
- 删除关于页

安全:
- 全局 CSRF 防护(双提交 Cookie)
- 登录限流防 XFF 伪造、错误信息脱敏
- 权限中间件 requireAdminForWrites(读放行/写 admin)
- 密码哈希存储(scrypt/sha256)
- SSRF 防护(封面下载域名白名单)
- 空 catch 加日志、SSE 连接上限

修复:
- 多角色账号 selectedProfile 缺失
- 普通用户越权删歌(V4)
- streams 写操作越权(V9)
- 设置页布局溢出

测试:38 项全绿(api16 / e2e17 / write5)
This commit is contained in:
Xiao-no-love committed 2026-10-06 16:37:03 +08:00
1 parent 5066f32fa4
commit f0fe50e484
29 files changed
+1703 -315

No files matched your search

+18 -2
View File
@@ -1,4 +1,20 @@
@echo off
set "ADMIN_PASSWORD=test123"
set "USER_PASSWORD=user123"
REM ===== 应急管理员密码(后门,StarLight 挂掉时用)=====
REM 支持三种格式:
REM 明文:set "ADMIN_PASSWORD=你的密码"
REM sha256:set "ADMIN_PASSWORD=sha256:<hex>"
REM scrypt:set "ADMIN_PASSWORD=scrypt:<salt_hex>:<hash_hex>" ← 推荐(加盐慢哈希)
REM 生成 scrypt 哈希(把 YourPassword 换成你的密码):
REM node -e "const c=require('crypto');const s=c.randomBytes(16).toString('hex');console.log('scrypt:'+s+':'+c.scryptSync('YourPassword',Buffer.from(s,'hex'),64).toString('hex'))"
set "ADMIN_PASSWORD=scrypt:5893f9e5e5933cffcd0a66886efefd3d:ad455e8b9e973c71d47eff8d1c5e24e0354857a0f413d8fb96b6a2550945c02935321493dc2513609642af24bb2052e856204dd2ccbdf788631b40b9b874cc19"
REM ===== StarLight 第三方登录配置 =====
set "STARLIGHT_API=https://skin.starlight.cool/yggdrasil"
REM 管理员白名单:填 StarLight 角色的【UUID】,逗号分隔(命中=admin,其余=user)
set "STARLIGHT_ADMINS=a347e21fbea14ef79a5236ff526a6b67"
REM 登录锁定豁免 IP(防管理员被锁死 DoS),逗号分隔
set "TRUSTED_IPS=127.0.0.1,::1"
node index.js