fix(auth): 四家桥的读端点也带上会话收窄 + 转发同一条命(工作区隔离第 2 步)
第 1 步(1b8cd43)把工作区判据放在服务端、pi 桥接上了线。这一步补齐另外四家, 并把**转发**纳入:转发是"把原文引出去",能转发就等于能读到那条线索的全部内容, 与 read_mail 同一条命(服务端 ForwardMail 也加了同一道校验)。 四家各自的会话来源,与各自的 read_inbox 同一处(不引入第二个来源): - dsh:`mailSessionOf(exec)`(工具第二个参数)—— 五个读工具原本没接 exec,这次补上 - opencode:`reverseMap.get(context.sessionID)` - zcode:`process.env.AGENTMAIL_SESSION_ID`(一轮一个进程) - homeagent:`p.currentSessionID`(新增 `scopeQuery(sep)`,与 inboxURL 同构) 判据(每条两侧都钉:包住了 / 没包住的不存在): - dsh:静态对照,且额外钉 **dist** —— 那是真被 dsh 加载的那份(main: dist/index.js), src 改了忘了 build 就是"源码对、线上旧代码" - opencode / zcode:同上(opencode 还钉"会话来自 context 而不是模块级变量") - homeagent:起 httptest 当网关,**五个读工具 + 转发真调一遍**,断言请求 URL 带 session_id;对照侧:不在回合里(currentSessionID 为空)时不许带 - pi:把 post 的 URL 也纳入记录,forward 进用例表 ★ zcode 那条判据我第一版**对照组写错**了:对照组只写裸 URL,而它本来就是 `withScope(\`裸URL\`)` 的子串 ⇒ `!includes(bare)` 恒假。夹具形状不对时判据会以 "恒红/恒绿"的方式骗人(这次是恒红,一眼可见;恒绿就麻烦了)。 变异:homeagent 去掉 read_mail 的收窄 ⇒ 恰好那条断言红。 (工作区共享,只 add 了上面这 12 个文件;dsh 的 dist 是 gitignore 的,由 redeploy-plugin.sh 在 staging 里构建。)
This commit is contained in:
@ -1481,6 +1481,23 @@ func (p *Plugin) markRead(ids []string) {
|
||||
p.client.Do(req)
|
||||
}
|
||||
|
||||
// scopeQuery 拼读类端点的**会话收窄参数**(`?session_id=…` / `&session_id=…`,
|
||||
// 由调用方给分隔符)。
|
||||
//
|
||||
// 与 inboxURL 同一个理由(不收窄会把别会话的未读标掉 ⇒ 静默丢信),但服务端现在
|
||||
// 拿它多干一件事:**由这条会话反查工作区**,只有同工作区的会话才放行。为什么必须
|
||||
// 有一维:一个 Agent 同时服务所有工作区(注册时 workspaces 为空),不收窄时在
|
||||
// TrueAgent 里干活的 worker 能读到 agentmail 的整条线索(用户 2026-09-14 报的越界)。
|
||||
//
|
||||
// 不在回合里时 currentSessionID 为空,返回空串 —— 退回旧行为(服务端会记警告),
|
||||
// 而不是猜一个会话。
|
||||
func (p *Plugin) scopeQuery(sep string) string {
|
||||
if p.currentSessionID == "" {
|
||||
return ""
|
||||
}
|
||||
return sep + "session_id=" + url.QueryEscape(p.currentSessionID)
|
||||
}
|
||||
|
||||
// inboxURL 拼收件箱地址。单独抽出来是为了能被单测直接断言 ——
|
||||
// 会话收窄这种"少了个参数就静默丢信"的改动,必须有判据盯着 URL 本身。
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user