refactor: session-based external auth, dynamic sources, drop netease UID

Auth (external API):
- ID: 16-digit random (non-sequential); Secret: SeaReport- + 32 hex
- POST /auth/session: ID+Secret -> Bearer SESSION (24h, single-session,
  old session invalidated on re-issue, disabled client invalidates)
- clientAuth now validates Bearer SESSION via api_sessions JOIN api_clients

Sources (dynamic, no default, open-source friendly):
- sources table + CRUD route (/api/sources, owner; delete guarded by usage)
- users/user_identities.source ENUM -> VARCHAR, seeded netease/skin
- register/admin create/identity bind: validate against enabled sources
- UI: 来源管理 page; source dropdowns loaded dynamically everywhere
  (register, dashboard identity, users admin, bans), labels dynamic

UID removal:
- game_uid/reporter_game_uid no longer required (db default '', validations
  dropped, frontend fields optional)

Docs: EXTERNAL-API.md session flow + new credential format; API.md updated
Verified: 37 checks (syntax, session logic, source CRUD, UID removal, docs)
This commit is contained in:
2026-08-19 20:08:06 +08:00
parent 6056153f57
commit 65edbaf157
19 changed files with 497 additions and 103 deletions

View File

@@ -25,10 +25,12 @@ const ExternalApiPage = {
<button class="btn btn-d btn-sm" onclick="ExternalApiPage.del(${c.id})"><i class="fas fa-trash"></i></button>
</td>
</tr>`).join('')}</tbody></table></div>`}
<div class="alert alert-i" style="margin-top:12px"><b>鉴权方式(唯一):</b> 请求头 <code>x-api-client-id</code> + <code>x-api-secret</code>。无凭据或凭据错误一律返回 401;secret 仅创建时显示一次,请立即保存。支持多个客户端,可单独停用/删除。</div>
<div class="alert alert-i" style="margin-top:12px"><b>鉴权流程:</b> 先调 <code>POST /api/external/auth/session</code> 用 <code>x-api-client-id</code> + <code>x-api-secret</code> 换取 SESSION(24小时有效), 之后所有接口请求头用 <code>Authorization: Bearer &lt;SESSION&gt;</code>。secret 仅创建时显示一次,请立即保存。</div>
</div></div>
<div class="card"><div class="card-h"><i class="fas fa-book"></i> 接口速览(免用户登录, 需上述鉴权头)</div><div class="card-b"><div class="table-wrap"><table><thead><tr><th>方法</th><th>路径</th><th>说明</th></tr></thead><tbody>
<div class="card"><div class="card-h"><i class="fas fa-book"></i> 接口速览(除换取SESSION外, 均需 Bearer SESSION)</div><div class="card-b"><div class="table-wrap"><table><thead><tr><th>方法</th><th>路径</th><th>说明</th></tr></thead><tbody>
<tr><td>POST</td><td><code>/api/external/auth/session</code></td><td>ID+Secret 换取 SESSION(唯一使用 ID+Secret 的接口)</td></tr>
<tr><td>POST</td><td><code>/api/external/auth/register</code></td><td>插件注册账号(需 SESSION)</td></tr>
<tr><td>POST</td><td><code>/api/external/tickets</code></td><td>提交工单(举报/建议/申诉),返回 id + tracking_token;可带 <code>server</code>(别名或「分组/子服」)</td></tr>
<tr><td>GET</td><td><code>/api/external/tickets/track?token=xxx</code></td><td>按追踪码查工单状态 + 回复,从提交到结束全程可查</td></tr>
<tr><td>GET</td><td><code>/api/external/all-tickets?server=&status=&type=&page=&limit=</code></td><td>工单列表(可按子服过滤)</td></tr>