|
|
495e4ee20e
|
fix(admin): 壁纸注入补测试;测试夹具真实备案号换占位值;后台历史条数展示
|
2026-10-02 11:24:55 +08:00 |
|
|
|
bb41b61ad6
|
fix(gateway): 路由表接口只替换路由,不再整份配置重置(agent 友好)
真实验证(干净环境练兵)抓到:POST /admin/api/gateway/routes 会把整个
GatewayConfig 反序列化为零值后保存,因此
- 只提交单个路由对象 → {"routes":0,"status":"saved"}:**静默清空整张路由表**
- 提交 {"routes":[…] } → 其余字段被重置为默认(实测入口端口 13080 → 8081,
TLS/认证地址一并丢失),随后 apply 生成的配置与预期完全不符
对 agent 尤其危险:照文档提交一条路由就会改掉入口端口与所有其它路由。
修复:
- 只补路由表:以现有配置为基准,仅替换 Routes,其它字段原样保留
- 请求体必须是 {"routes":[...]};缺该键 → 400 并说明正确形状(不再静默变空表)
- 非空表要清空必须显式传 force:true,否则 400 拒绝
- 测试:单个对象被拒;数组提交后 listenPort/TLS/认证地址/证书路径全部保留;
清空被拒、force 允许
- README:修正路由示例为完整数组形状,补"替换整张表"与 /admin/api 前缀说明
|
2026-09-12 10:28:03 +08:00 |
|
|
|
158217103d
|
fix(deploy): 首装路由表路径写错(静默零路由)+ apply 空表安全阀
真实练兵(干净数据目录跑 install-host.sh)抓到:
1. 路由表源文件被写到 <数据卷>/gateway/gateway.yml,容器实际读取 <数据卷>/gateway.yml
→ apply 报 routes: 0,用户自备/生成的初始路由被静默忽略
2. 自检在 apply 后立即探测,nginx 还没 reload 完 → 误判连接失败;
code_of 失败时重复输出 000
3. 缺安全阀:路由表为空时 apply 会照常生成零路由配置并覆盖,
等于静默清空入口路由表
修复:
- install-host.sh 改写 <数据卷>/gateway.yml(并注释说明两个目录的区别)
- 自检前轮询等待入口监听就绪(最多 10s),code_of 只在成功时输出状态码
- handleGatewayApply 增加安全阀:路由表为空但现有配置含 server_name → 400 拒绝覆盖
- 新增测试 TestApplyRefusesEmptyRoutesOverExisting
|
2026-09-12 09:40:36 +08:00 |
|
|
|
064f986a7f
|
fix(theme): 深色遮罩交给服务端,避免双重压暗
实测发现深色下 body 的 background-image 仍是亮色的 70% 白遮罩(壁纸被洗白)。
遮罩由服务端 applyWallpaperBlock 写进 conf.yml,因此在那里补一条深色规则
(同一张壁纸 + rgba(6,12,24,dim+0.15) 遮罩),并移除 navi.css 里那层
body::before 遮罩,避免壁纸被双重压暗。加单测断言深浅两条规则共存、
且移除壁纸时一并清除。
|
2026-09-12 07:49:34 +08:00 |
|
|
|
0d9619e446
|
feat(admin): 导航分组可增 / 可改名 / 可删;初始状态无分组
后台此前只能往已有分组里加服务,分组本身是写死在 conf.yml 里的,
用户无法增删。现在新增「导航分组」卡片:
- POST /admin/api/section 新增(重名 409、空名 400)
- POST /admin/api/section/update 改名/换图标
- DELETE /admin/api/section 删除;非空分组必须 force=1(二次确认),
避免误点一下连带删掉一组服务
「历史访问」分组由 history-server 依据浏览记录重建,改名/删除/手工新建
都会被它覆写回来,所以一律 409 并说明原因 —— 否则用户以为删掉了,
下次同步又"长"回来。
初始状态无分组:conf.example.yml 的 sections 改为空数组,后台在两个位置
给空态提示(「还没有任何分组」/「先创建分组」,并把"添加服务"置灰)。
补上原本缺失的一环:rebuildDashySections() 原先只更新已存在的
「历史访问」分组、从不创建它,新装用户永远看不到历史分组;现在缺了就补建
(完全空配置时不补,保持"初始无分组")。
测试覆盖:新增/重名/改历史分组/删历史分组/删非空(无 force 拒绝)/force 删除,
以及删除后的分组名列表断言。
|
2026-09-11 19:52:19 +08:00 |
|
|
|
22c405d2a0
|
feat(admin): 新增可内嵌性三态探测 /admin/api/frameable
Dashy 的「工作空间」用 iframe 打开应用,被 X-Frame-Options /
CSP frame-ancestors 拒绝时浏览器只给一片空白,而且 JS 无法区分
「被拒绝」与「加载中」(onload 一样触发)。所以由服务端读响应头。
实测 24 个应用:19 个可内嵌;Gitea(含内网 IP) 与 docker.com 是
SAMEORIGIN,Dify 是 DENY。
三态而非布尔,因为探测本身会失真:
- conclusive=true frameable=false → 有明确拒绝证据(XFO / frame-ancestors)
- conclusive=true frameable=true → 2xx 且无拒绝头
- conclusive=false → 探测被 WAF 拦成 403、或跳到了别的主机
这类不给结论,前端照常尝试内嵌,但在工具条里说明原因并留出新标签页退路。
两个关键细节:
1) 转发浏览器自己的 Cookie。门户后面的应用对未登录请求会 302 到登录页
(登录页没有 X-Frame-Options),不转发会话就会把「重定向到登录页」
误判成「可内嵌」——这是线上真实发生过的误判。
2) 用普通浏览器 UA。自造的 "HomeDash embed check" UA 会被 WAF 当机器人拦成 403。
测试覆盖:无头/有 XFO/有 CSP frame-ancestors/WAF 403/带与不带 Cookie。
|
2026-09-11 19:04:38 +08:00 |
|
|
|
e4967b99ee
|
feat(admin): 备案号可编辑,页脚模板由服务端生成
备案号原来只能写死在 pageInfo.footer 的 HTML 里。现在 /admin/ 站点信息
拆出「ICP 备案号」「公安备案号」两个输入框,页脚 HTML 由服务端
beianFooter() 统一按模板生成(含 html.EscapeString 转义),
自定义页脚 HTML 降级为「高级」折叠项;旧 footer 会被解析回填到字段。
conf.example.yml 里重复的 .navi-search-bar 规则已由 web/navi.css 接管,删除。
|
2026-09-11 16:25:26 +08:00 |
|