From 713c9e4e3003088e29aafcf1fdd3bd87078ec394 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Sun, 16 Aug 2026 19:40:29 +0800 Subject: [PATCH 1/3] =?UTF-8?q?fix:=20=E6=81=A2=E5=A4=8D=E7=99=BB=E5=BD=95?= =?UTF-8?q?=E9=A1=B5=E5=89=8D=E7=AB=AF=E9=85=8D=E7=BD=AE=E6=8E=A5=E5=8F=A3?= =?UTF-8?q?=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sense/server/app/admin/router/sys_router.go | 5 +++ .../app/admin/router/sys_router_test.go | 37 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 Sense/server/app/admin/router/sys_router_test.go diff --git a/Sense/server/app/admin/router/sys_router.go b/Sense/server/app/admin/router/sys_router.go index ffab703..71ae8b7 100644 --- a/Sense/server/app/admin/router/sys_router.go +++ b/Sense/server/app/admin/router/sys_router.go @@ -80,6 +80,11 @@ func sysCheckRoleRouterInit(r *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddle func registerBaseRouter(v1 *gin.RouterGroup, authMiddleware *jwt.GinJWTMiddleware) { api := apis.SysMenu{} api2 := apis.SysDept{} + configAPI := apis.SysConfig{} + // The GoAdmin login shell reads frontend-only branding before a user is + // authenticated. Keep this single read route public without registering the + // disabled system-configuration CRUD and write routes. + v1.GET("/app-config", configAPI.Get2SysApp) v1auth := v1.Group("").Use(authMiddleware.MiddlewareFunc()).Use(middleware.AuthCheckRole()) { v1auth.GET("/roleMenuTreeselect/:roleId", api.GetMenuTreeSelect) diff --git a/Sense/server/app/admin/router/sys_router_test.go b/Sense/server/app/admin/router/sys_router_test.go new file mode 100644 index 0000000..d882d47 --- /dev/null +++ b/Sense/server/app/admin/router/sys_router_test.go @@ -0,0 +1,37 @@ +package router + +import ( + "testing" + + "github.com/gin-gonic/gin" + jwt "github.com/go-admin-team/go-admin-core/sdk/pkg/jwtauth" +) + +func TestRegisterBaseRouterExposesOnlyFrontendAppConfig(t *testing.T) { + gin.SetMode(gin.TestMode) + engine := gin.New() + registerBaseRouter(engine.Group("/api/v1"), &jwt.GinJWTMiddleware{}) + + routes := make(map[string]struct{}) + for _, route := range engine.Routes() { + routes[route.Method+" "+route.Path] = struct{}{} + } + + if _, ok := routes["GET /api/v1/app-config"]; !ok { + t.Fatal("anonymous frontend app-config route is not registered") + } + for _, disabled := range []string{ + "GET /api/v1/config", + "POST /api/v1/config", + "GET /api/v1/config/:id", + "PUT /api/v1/config/:id", + "DELETE /api/v1/config", + "GET /api/v1/configKey/:configKey", + "GET /api/v1/set-config", + "PUT /api/v1/set-config", + } { + if _, ok := routes[disabled]; ok { + t.Fatalf("disabled system-configuration route was registered: %s", disabled) + } + } +} From 08b4b61f9020968aefc8e73a3c1715619da5214d Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Sun, 16 Aug 2026 19:46:07 +0800 Subject: [PATCH 2/3] =?UTF-8?q?docs:=20=E8=AE=B0=E5=BD=95=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=A4=96=E5=A3=B3=E5=8F=AA=E8=AF=BB=E9=85=8D=E7=BD=AE?= =?UTF-8?q?=E8=BE=B9=E7=95=8C=20(#99)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/02-architecture-and-code-map.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/02-architecture-and-code-map.md b/docs/02-architecture-and-code-map.md index 5013571..0c95592 100644 --- a/docs/02-architecture-and-code-map.md +++ b/docs/02-architecture-and-code-map.md @@ -2,8 +2,8 @@ generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) wiki_page: Architecture-and-Code-Map wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Architecture-and-Code-Map.- -wiki_revision: a95b7692bc0c6bf4d05f8c57088a83379e15a08f -synchronized_at: 2026-08-15T03:01:57Z +wiki_revision: 5cbaa178193811083519c5125febf8cc962c94ee +synchronized_at: 2026-08-16T11:45:49Z # 架构与代码地图 @@ -87,7 +87,7 @@ Sense 已由工单 #61 从冻结 go-admin/go-admin-ui 源码建立:后端入 工单 #64 在该基线上重建 Sense 独立身份能力:`Sense/server/app/admin/apis/identity_bootstrap.go` 提供受外部高熵令牌保护的一次性首位管理员初始化,数据库迁移固定建立 `admin`、`implementation_operator`、`site_admin`、`viewer` 四个角色及最小 Casbin 权限;前端继续复用 go-admin-ui 动态菜单、权限按钮、请求封装与 Layout。仓库仍不提供默认账号、默认密码或可用 JWT 密钥。 -Sense JWT realm 固定为 `Sense`;浏览器令牌 Cookie 为 `Sense-Admin-Token`,后端仅接受标准 Authorization Bearer 或独立的 `sense_session` Cookie,不接受查询参数令牌,也不得与 Bell 共享 JWT 密钥、Cookie 或账户库。登录成功/失败、登出、密码变更和鉴权拒绝写入身份审计;审计内容必须剔除密码、令牌、Cookie、验证码和其他秘密。配置、接口管理等非产品必要路由不注册,即使管理员直接调用也返回 404。 +Sense JWT realm 固定为 `Sense`;浏览器令牌 Cookie 为 `Sense-Admin-Token`,后端仅接受标准 Authorization Bearer 或独立的 `sense_session` Cookie,不接受查询参数令牌,也不得与 Bell 共享 JWT 密钥、Cookie 或账户库。登录成功/失败、登出、密码变更和鉴权拒绝写入身份审计;审计内容必须剔除密码、令牌、Cookie、验证码和其他秘密。配置管理 CRUD、configKey、set-config、接口管理等非产品必要路由不注册,即使管理员直接调用也返回 404。登录外壳必需的匿名只读 `GET /api/v1/app-config` 是唯一例外:它复用 GoAdmin `SysConfig.Get2SysApp`,只投影标记为前端可见的配置,不提供写入或管理能力。 工单 #65 新增设备台账入口:后端按 `models → dto → service → api → router` 分层位于 `Sense/server/app/sense/device/`,管理路由在 `Sense/server/app/admin/router/sense_device.go`,前端页面位于 `Sense/ui/src/views/sense/device/index.vue`。设备凭据由 `Sense/server/app/sense/credential/` 独立存储和 AES-256-GCM 加密,HTTP 只返回是否已配置,不提供凭据读取接口。 From d067f0b98930801b95e6c5aacbe7ec34a8e0c2a3 Mon Sep 17 00:00:00 2001 From: QiuSW <105186638@qq.com> Date: Sun, 16 Aug 2026 19:49:19 +0800 Subject: [PATCH 3/3] =?UTF-8?q?docs:=20=E5=AE=8C=E6=88=90=E4=BB=BB?= =?UTF-8?q?=E5=8A=A1=20#99=20=E5=BE=85=E9=AA=8C=E6=94=B6=E5=BD=92=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../99-Sense登录页只读配置接口.md | 73 +++++++++++++++++++ wiki-docs.json | 4 + 2 files changed, 77 insertions(+) create mode 100644 docs/task/99-Sense登录页只读配置接口.md diff --git a/docs/task/99-Sense登录页只读配置接口.md b/docs/task/99-Sense登录页只读配置接口.md new file mode 100644 index 0000000..ae1af1a --- /dev/null +++ b/docs/task/99-Sense登录页只读配置接口.md @@ -0,0 +1,73 @@ + +generated: true (请先修改 Gitea Wiki,禁止直接编辑本文件) +wiki_page: Task-99-Sense登录页只读配置接口 +wiki_url: https://git.ilapage.cn/ila/yovision/wiki/Task-99-Sense%E7%99%BB%E5%BD%95%E9%A1%B5%E5%8F%AA%E8%AF%BB%E9%85%8D%E7%BD%AE%E6%8E%A5%E5%8F%A3.- +wiki_revision: 26d3762828f6e4273a2002fca49336bebf7566fe +synchronized_at: 2026-08-16T11:48:58Z + + +# 99 Sense登录页只读配置接口 + +- 类型:缺陷修复 / GoAdmin 路由精简回归 +- 所属 Epic:#7 +- 所属 MVP / 版本:#8 +- 状态:待验收 +- 日期:2026-08-16 +- Gitea 工单:https://git.ilapage.cn/ila/yovision/issues/99 +- Wiki 页面:Task-99-Sense登录页只读配置接口 +- Wiki revision:见本地镜像头 + +## 背景与目标 + +用户启动 #70 Windows 发布包后,登录页弹出 `Request failed with status code 404`。只读诊断确认首页、runtime JS 和兼容 captcha 端点均为 200,唯一失败请求是登录页在 created 阶段发出的 `GET /api/v1/app-config`。 + +冻结 go-admin-ui 使用该匿名接口取得系统名称等登录外壳展示配置;Sense 后端保留了 `SysConfig.Get2SysApp` handler,但在最小化默认模块时没有注册此路由。目标是恢复这一个只读端点,同时继续禁用系统配置管理和写接口。 + +## 最终方案 + +- 在现有 `registerBaseRouter` 中单独注册匿名 `GET /api/v1/app-config`,直接复用 GoAdmin `SysConfig.Get2SysApp`。 +- 不调用上游完整 `registerSysConfigRouter`,因此 `/api/v1/config`、`/api/v1/configKey` 和 `/api/v1/set-config` 不会随之开放。 +- handler 继续只查询 `is_frontend=1` 的配置并返回标准响应;没有前端配置时返回空对象和业务码 200。 +- 保持 #97 的免验证码登录、JWT、RBAC、Cookie、密码策略和 captcha 兼容端点不变。 +- 基于实现提交重新生成 Windows 包,恢复仓库外备份的现场配置,并重新启动 Sense/MediaMTX。 + +## 修改文件 + +- `Sense/server/app/admin/router/sys_router.go`:恢复登录外壳必需的匿名只读 app-config 路由。 +- `Sense/server/app/admin/router/sys_router_test.go`:锁定公开端点和八个仍禁用的配置管理路由。 +- Wiki `Architecture-and-Code-Map` 及镜像:记录匿名只读例外与配置管理禁用边界。 +- `wiki-docs.json` 与本任务镜像:登记任务归档。 + +## 验收结果 + +| 验收标准 | 结果 | +|---|---| +| 匿名 app-config 返回 HTTP 200 和标准结构 | 通过:HTTP 200、业务码 200 | +| 登录页不再出现该 404 | 通过:真实 Edge 页面 app-config 200,错误消息数 0 | +| 配置 CRUD/configKey/set-config 未启用 | 通过:GET/PUT 定向 smoke 均为 404 | +| 免验证码登录与认证边界不变 | 通过:登录页仅账号和密码,无验证码文本;后端全量测试通过 | +| Go 与 Windows 包测试 | 通过 | +| ZIP 无秘密、node_modules 或客户数据 | 通过:构建内置包审计通过,ZIP 使用模板配置 | +| Wiki、归档与证据完整 | 通过 | + +## 测试 + +- `go test ./app/admin/router -run TestRegisterBaseRouterExposesOnlyFrontendAppConfig -count=1`:通过。 +- `go test ./...`、`go vet ./...`、`go build ./...`:通过。 +- Windows PowerShell 包测试:21 项断言通过。 +- 固定 Go 1.26.5、Node 22.22.1、pnpm 9.15.1 production build 与 11 个 HTML 本地资源审计通过;存在既有 4 条非阻塞构建 warning。 +- 真实运行:`GET /api/v1/app-config` 为 HTTP 200/业务码 200;配置 CRUD、configKey、set-config GET/PUT 均为 404。 +- Headless Edge:进入 `/#/login?redirect=/dashboard`;app-config 200;错误消息 0;仅账号、密码两个输入;无验证码文本、失败请求或页面异常。 +- 新 ZIP:56,457,323 字节;SHA-256 `A98EB70B709BBA546F4968723E4F89CE44DAF412FCC426869820FB7454CB3CC7`;包内 `source_commit=713c9e4e3003088e29aafcf1fdd3bd87078ec394`。 +- 测试后 Sense 与 MediaMTX 已使用恢复的现场配置重新启动,监听 18080/9997。 +- `git diff --check` 与 Wiki 定向同步检查:通过。 +- **未验证部分**:尚未在客户全新 Windows 主机、客户生产 PostgreSQL 账号和客户目标浏览器中验收;本轮使用当前机器 PostgreSQL、Microsoft Edge 和现有脱敏配置验证。 + +## 遗留问题 + +- 无本工单阻塞项。 + +## 相关提交 + +- `713c9e4e3003088e29aafcf1fdd3bd87078ec394` 恢复登录页只读配置接口并增加负向路由测试。 +- `08b4b61` 记录登录外壳只读配置边界。 diff --git a/wiki-docs.json b/wiki-docs.json index 3fb80b4..a14222e 100644 --- a/wiki-docs.json +++ b/wiki-docs.json @@ -143,6 +143,10 @@ { "page": "Task-97-Sense免验证码登录与管理员密码重置", "path": "docs/task/97-Sense免验证码登录与管理员密码重置.md" + }, + { + "page": "Task-99-Sense登录页只读配置接口", + "path": "docs/task/99-Sense登录页只读配置接口.md" } ] }