fix(ui): 把已算好但没发出去的数据接到界面上 - #5
Merged
Merged
Conversation
三批。共同点是后端早就算好了,只差最后一段接线 —— 用户看不到的功能等于没有。 ## 1. csrf 错误码没人接(上个 PR 我自己留下的) api() 只处理 401 和 2fa_required,而我上轮加的 code:'csrf' 没有分支,很多调用点 又不判 ok —— 表现是"点了没反应"。正常同源访问走不到这里,走到了基本只有一种 情况:面板在反代后面而 Host 头没透传对,而那恰恰是最需要把原因说清楚的时候。 顺带把 MCSP_TRUSTED_ORIGINS 这个逃生阀写进 README 和 docker-compose —— 之前它只存在于源码里,遇到问题的人不可能知道有这个东西。 ## 2. 权限分档在 UI 上等于不存在 后端一直算着 req.perm(viewer/operator/manager/owner),但从没发给前端: snapshot() 里没有,前端对 .perm 的引用数是 0。于是 viewer 看到的界面和主人 一模一样,启动、保存配置、清空统计按钮全在,点下去才 403。 "能看见但一按就报错"比"看不见"更糟 —— 用户分不清是自己没权限还是面板坏了。 - perm 加在**路由层**(实例列表 + /status),不进 snapshot():同一份 snapshot 还会经 SSE 广播给权限不同的多个用户,塞进去就会发错人。 - 前端用独立的 permMap 存,不放 instMap —— 否则会被 SSE 的 state 事件覆盖掉。 - 做法是声明式的:HTML 标 data-need="operator|manager|owner",一个函数统一 禁用并给出"需要 X 档,你是 Y 档"的 title。以后加按钮只需加个属性。 - 总览卡片的启停按钮按**卡片所属实例**判权限(不是当前选中实例),只读档直接 不渲染 —— 列表里摆一排点了就报错的按钮比没有按钮更让人困惑。 - .perm-denied 的透明度对齐已有的 .btn:disabled(0.35)。那条规则特指度 (0,2,0) 本来就压过 (0,1,0),按钮走的一直是它;这里主要给非 .btn 控件兜底,数值写一样 免得输入框和按钮灰得深浅不同,也不加 filter(否则只在输入框上生效,更不一致)。 ## 3. 五处"数据已在手边,差一行渲染" - **计划任务执行历史**:后端存最近 5 次并落盘、API 原样下发,前端只画了 lastResult。而"偶尔抽风"和"一直坏"是两种处置,一次结果分不出来。 画成结果点,失败用方块+琥珀色(形状+颜色双编码,不只靠颜色)。 - **实例 createdAt**:三处写入、一直落盘,却从没进过 snapshot。用户/邀请/备份 都有"创建于",唯独实例没有。 - **playtime firstSeen**:后端三层都传到前端了,渲染时跳过了。 - **审计按用户精确筛选**:read() 早就支持 user 参数,还为它写了条免 JSON.parse 的快路径(直接在原始行里找 "user":"xxx"),但前端只发 q —— 那条优化没有调用方 能触发。改成点用户名即筛他一个人;全文搜索会把路径里含同名子串的行也带进来, 精确匹配不会。 - **导入探测置信度**:detect.js 算了 high/low/none 三级(三条线索都对上才 high), 前端只用了 d.type,于是"三样都对上"和"只猜出个类型"反馈一模一样,而后者 需要用户去核对。notes 也从只显示第一条改成全部显示 —— 里面有"未找到已同意的 eula.txt"这类直接影响能否启动的提示,漏掉后面几条等于让用户自己去撞。 ## 测试 85 → 111 项。新增 perm 下发的 7 条(三档 + 管理员,列表与 /status 各一)。 **并修好了一个测试覆盖缺口**:collabRoleSuite 原先只在"面板上恰好已有实例"时才跑, 空面板(CI 就是空的)会整段跳过 —— 也就是说这套权限用例在 CI 里从来没执行过, 而它覆盖的正是最容易写错的部分。现在没有现成实例就自建一个空壳走完 finalize, 跑完删掉。上个 PR 里靠手工验证的那批权限断言,现在 CI 每次都会跑。 前端部分另在真实浏览器里核对:viewer 身份下 9 个控件全部 disabled 且 title 正确、 协作者卡片隐藏、createdAt 正常渲染、三类控件透明度一致(0.35)。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
三批改动,共同点是后端早就算好了,只差最后一段接线 —— 用户看不到的功能等于没有。
1.
csrf错误码没人接(上个 PR 我自己留下的)api()只处理401和2fa_required,我上轮加的code:'csrf'没有分支,而很多调用点又不判ok—— 表现是**「点了没反应」**。正常同源访问走不到这里;走到了基本只有一种情况:面板在反代后面而
Host头没透传对。而那恰恰是最需要把原因说清楚的时候。顺带把
MCSP_TRUSTED_ORIGINS写进 README 和 docker-compose —— 之前这个逃生阀只存在于源码里,遇到问题的人不可能知道有它。2. 权限分档在 UI 上等于不存在
后端一直算着
req.perm,但从没发给前端:snapshot()里没有,前端对.perm的引用数是 0。于是 viewer 看到的界面和主人一模一样,按钮全在,点下去才 403。「能看见但一按就报错」比「看不见」更糟 —— 用户分不清是自己没权限还是面板坏了,而 403 的文案是通用的。
几个设计决定:
perm加在路由层(列表 +/status),不进snapshot()—— 同一份 snapshot 还会经 SSE 广播给权限不同的多个人,塞进去就会发错人permMap,不放instMap—— 否则会被 SSE 的 state 事件覆盖data-need="operator|manager|owner",一个函数统一禁用并给出「需要 X 档,你是 Y 档」的 title。以后加按钮只需加个属性3. 五处「数据已在手边,差一行渲染」
lastResultcreatedAtsnapshot()playtime.firstSeenread()支持user且为它写了条免 JSON.parse 的快路径,前端只发q—— 那条优化没有调用方能触发detect.js算了 high/low/none,前端只用d.typenotes从只显示第一条改成全部notes里有「未找到已同意的 eula.txt」这类直接影响能否启动的提示,漏掉后面几条等于让用户自己去撞。测试:85 → 111
新增 perm 下发的 7 条(三档 + 管理员,列表与
/status各一)。并修好了一个测试覆盖缺口:
collabRoleSuite原先只在「面板上恰好已有实例」时才跑,空面板(CI 就是空的)会整段跳过 —— 也就是说这套权限用例在 CI 里从来没执行过,而它覆盖的正是最容易写错的部分。现在没有现成实例就自建一个走完 finalize,跑完删掉。上个 PR 里我靠手工验证的那批权限断言,现在 CI 每次都会跑。前端另在真实浏览器里核对(测试覆盖不到这层):viewer 身份下 9 个控件全部
disabled且 title 正确、协作者卡片隐藏、createdAt正常渲染。顺带发现并对齐了一处样式冲突:代码库已有
.btn:disabled { opacity: 0.35; filter: none },特指度 (0,2,0) 压过我新加的.perm-denied(0,1,0) —— 我原本写的grayscale在按钮上从不生效、在输入框上却生效,两者会灰得不一样。改成对齐既有约定。我更正的一处说法
上一轮我说「
detect.notes前端不读」。实际上notes[0]是渲染了的,没渲染的是confidence和第 2 条之后的 notes。🤖 Generated with Claude Code