feat: complete unified plugin admin v1.1.0
This commit is contained in:
@@ -2,14 +2,16 @@
|
||||
|
||||
状态:V1 只读试验实现已落库;余额购买、续费、撤销仍为 V1.1 Draft
|
||||
|
||||
本文定义基于 [`PLUGIN_FRAMEWORK_V1_RFC.md`](./PLUGIN_FRAMEWORK_V1_RFC.md) 的第一个业务插件试验,对应实现为 `plugins/subscription-admin`。插件是独立端口的管理员后台,复用 Sub2API Core 的管理员鉴权,不创建 Core 用户表,也不直接连接 Core 数据库。当前实现已完成框架、管理员会话、只读套餐/余额/订阅/审计联调;余额购买、续费和撤销写操作后置到 Core 原子接口冻结之后。
|
||||
本文定义基于 [`PLUGIN_FRAMEWORK_V1_RFC.md`](./PLUGIN_FRAMEWORK_V1_RFC.md) 的第一个业务模块试验,对应后端实现为 `plugins/subscription-admin`。订阅后端可以独立端口运行,但它不是第二个管理员后台:浏览器入口由 `plugins/plugin-admin` 统一控制面承载,复用同一套管理员会话、导航、CSRF 和权限,不创建 Core 用户表,也不直接连接 Core 数据库。当前实现已完成框架、管理员会话、只读套餐/余额/订阅/审计联调;余额购买、续费和撤销写操作后置到 Core 原子接口冻结之后。
|
||||
|
||||
> **前端架构修订(2026-08-30)**:本 RFC 中原有“订阅插件登录页/独立后台”描述由本条覆盖。订阅模块不得提供第二个 `/login`、独立 Cookie、独立管理员身份或重复的 Core 登录;安装并启用后才在 Plugin Admin 导航中出现。
|
||||
|
||||
## 1. 目标和范围
|
||||
|
||||
### 1.1 V1 目标
|
||||
|
||||
- 提供独立的管理员订阅后台,普通账号拒绝登录和访问;
|
||||
- 插件登录调用 Core 现有 `/api/v1/auth/login`、`/api/v1/auth/login/2fa` 和 `/api/v1/auth/me`,不维护第二套用户密码;
|
||||
- 提供挂载在统一 Plugin Admin 控制面内的管理员订阅模块,普通账号拒绝登录和访问;
|
||||
- 由 Plugin Admin 统一调用 Core 现有 `/api/v1/auth/login`、`/api/v1/auth/login/2fa` 和 `/api/v1/auth/me`;订阅模块不维护第二套用户密码或登录态;
|
||||
- 展示 Core 中的套餐、用户余额和订阅实例状态;
|
||||
- 通过现有 `custom_menu_items` 的 `visibility=admin` 入口嵌入 Core 页面,也支持新窗口打开;
|
||||
- 插件可独立升级、停用和回滚,不影响 Core 网关、余额账本和已有订阅;
|
||||
@@ -42,14 +44,15 @@
|
||||
Core 管理后台
|
||||
└─ custom_menu_items (visibility=admin)
|
||||
└─ sandbox iframe / 新窗口
|
||||
└─ 反向代理 -> Plugin `127.0.0.1:PLUGIN_PORT`
|
||||
├─ Plugin /login -> Core /api/v1/auth/login (+ /login/2fa)
|
||||
├─ Plugin /auth/me -> 只允许 role=admin
|
||||
├─ HttpOnly 插件会话(不建 Core 用户表)
|
||||
└─ 反向代理 -> Plugin Admin `127.0.0.1:PLUGIN_PORT`
|
||||
├─ Plugin Admin /login -> Core /api/v1/auth/login (+ /login/2fa)
|
||||
├─ Plugin Admin /auth/me -> 只允许 role=admin
|
||||
├─ 唯一 HttpOnly 控制面会话(不建 Core 用户表)
|
||||
├─ 挂载订阅模块 /modules/subscription/*(不重复登录)
|
||||
└─ 服务端 Bearer Core JWT -> 现有 Core Admin API(V1 只读)
|
||||
```
|
||||
|
||||
插件 UI 只访问自己的 BFF;Core JWT、refresh token 和 Admin API Key 只在插件服务端会话或 secret 中出现。iframe 不会自动继承 Core `localStorage` 登录态,因此 V1 首屏显示插件登录页属于预期行为。sandbox 或第三方 Cookie 策略可能导致嵌入会话刷新后失效,插件必须提供新窗口登录路径;登录密码只在一次转发请求中经过插件后端,不落库、不写日志。
|
||||
订阅模块 UI 只访问控制面的模块 BFF;Core JWT、refresh token 和 Admin API Key 只在控制面服务端会话或 secret 中出现。iframe 不会自动继承 Core `localStorage` 登录态,因此 V1 首屏显示一次 Plugin Admin 登录页属于预期行为;进入订阅模块时不再登录。sandbox 或第三方 Cookie 策略可能导致嵌入会话刷新后失效,控制面必须提供新窗口入口;登录密码只在一次转发请求中经过控制面后端,不落库、不写日志。
|
||||
|
||||
## 4. 权威边界
|
||||
|
||||
@@ -65,7 +68,7 @@ Core 管理后台
|
||||
|
||||
### 4.2 插件可以负责
|
||||
|
||||
- 管理员登录代理、插件会话和插件内角色;
|
||||
- 控制面负责管理员登录代理、统一插件会话和插件内角色;订阅模块只消费经过授权的模块会话;
|
||||
- 套餐、用户和订阅的分页筛选与展示;
|
||||
- 只读缓存、操作结果页和管理员审计视图;
|
||||
- 未来写操作的确认表单,但提交必须调用 Core 原子命令;
|
||||
@@ -210,7 +213,7 @@ accepted -> processing -> completed
|
||||
|
||||
### 11.3 浏览器和部署
|
||||
|
||||
- 管理员可在 iframe 和新窗口完成登录;普通用户菜单不可见且 API 拒绝;
|
||||
- 管理员在 Plugin Admin 的 iframe 或新窗口完成一次登录即可进入订阅模块;普通用户菜单不可见且 API 拒绝;
|
||||
- 425px、900px、1440px 下无横向溢出、遮挡或敏感字段泄露;
|
||||
- DevTools 请求、下载、页面源和日志中没有 secret;
|
||||
- 反向代理、HTTPS、低权限运行、停用、升级和回滚流程可恢复。
|
||||
@@ -247,7 +250,7 @@ accepted -> processing -> completed
|
||||
|
||||
- [ ] 插件只允许 Core `role=admin` 登录,且不创建用户表。
|
||||
- [ ] 独立端口、反向代理路径和 `visibility=admin` 菜单入口已确定。
|
||||
- [ ] iframe 登录页和新窗口登录页均可用,已知晓 V1 不提供无感 SSO。
|
||||
- [ ] Plugin Admin 统一登录入口在 iframe 和新窗口场景均可用;订阅模块不提供独立登录,V1 不提供无感 SSO。
|
||||
- [ ] 只读 Core API allowlist、分页、字段脱敏和缓存策略已冻结。
|
||||
- [ ] 同档位多实例、单独续费、用户不可取消和管理员撤销规则已确认。
|
||||
- [ ] 余额购买写操作明确等待 Core 原子接口,不使用现有多个接口拼接。
|
||||
|
||||
Reference in New Issue
Block a user