feat(trigger-user-auth): lark-cli 设备码按人鉴权 + 统一自动授权(收敛 #1382) - #1384
Conversation
|
本地测试反馈后补一版(commit 0c29a0c):
|
|
自动评审的初步意见,供参考;最终以维护者审阅为准。基线已同步到 整体方向认同:把 lark-cli 从「注入 user_access_token」改成与 bytedcli 一致的「一人一个 HOME 目录」, 1. lark-cli 的「点完链接直接重试」在当前实现下无法完成lark-cli 的设备码是两段式: 而 结果是:用户点完链接、按提示让 bot 重试 → bytedcli 没有这个问题: 用真实契约建模(只有 建议: 2. 一次网络抖动会把已授权的 bytedcli 用户锁在门外
本 PR 新增的 验证:turn1 让取 JWT 超时一次后落下 challenge;turn2 网络已恢复,仍返回 建议二选一:① 把硬闸改成尽力而为——收尾失败时不要 3. 建议同 PR 一并处理(不阻断)
以上验证用的临时探针均已删除,未对本仓库留下任何改动。 |
9148611 to
a6cea38
Compare
在 #1382(bytedcli 自动登录 + /login 放权)基础上,把 lark-cli 拉齐到同一套 按触发人鉴权/设备码体验,并把授权链接做成统一、保证有效、一次授权的形态: - 新增 services/lark-cli-auth.ts:per-person HOME(~/.botmux/data/ lark-cli-home/<openId>)、设备码 begin/complete、机器级 app 凭证 bootstrap、 未过期 challenge 复用;签发 app 来源支持 BOTMUX_LARK_CLI_ISSUER_HOME 与 托管 ~/.botmux/data/lark-cli-app-bootstrap,避免隐式取操作员首个 app。 - cli-identity:新增 user-home 身份模式,wrapper 以 per-person HOME 执行 lark-cli(不注入 user token),保留 turn 绑定/缺失目录即拒。 - turn-cli-identity:lark-cli 优先用 per-person HOME(回退旧 bot-app token); lark-cli 缺凭证时也自动 begin 设备码并把链接嵌入拒绝信息(与 bytedcli 同款)。 - 授权文案统一为「只需授权一次、自动续期、点完直接重试」,lark/byted 都带 provider,不出现「无权限错误路由」式生硬提示;新增 agent 转述规则 on_auth_link。 - /login 增加 lark 设备码入口(/login lark、/login done 同时收尾两种设备码), /login status 按 per-person HOME 报 lark/byted 各自状态。 - 修 dashboard「按触发人鉴权」工具勾选框在 bd-row grid 下错位(css specificity)。 注:飞书没有「全员通用 CLI app」,设备码必须绑自建 app 且用户在其可用范围; 正解是每人/统一使用自己有权限(创建者天然在内)的签发 app,per-person HOME 已为此隔离。飞书后台「扩大可用范围」审批是外部前提,代码不绕过。 Co-Authored-By: Claude Code <noreply@anthropic.com>
…me 用例 Co-Authored-By: Claude Code <noreply@anthropic.com>
对齐 bytedcli:lark-cli 开启按触发人鉴权后,发起人没有 per-person HOME 身份时不再静默降级 bot(bot 身份对 docs/drive/wiki/search 等 user-only 命令本就不可用,静默降级只会失败且不给链接),而是直接拒绝并内嵌该用户 可授权的设备码链接——「用到、没授权 → 直接给链接」,无需手敲 /login。 签发 app 按发起人解析,杜绝「点开标『你没有该 app 使用权限』」的错误链接: issuerMachineHome(openId) 优先级 test > env > **per-person ~/.botmux/data/lark-cli-issuer-<openId>**(每人各自 config init --new 建的、 自己天然有权限的 app)> 共享 bootstrap > 操作员 HOME。openId 做路径字符白名单 防穿越。真机验证孙晓雪/董思琪各自 begin 出的链接绑定的是她俩自己的 app。 - turn-cli-identity:lark 与 byted 同款 deny+link,移除 lark 静默 bot 分支 及随之无用的 unauthorizedOutcomeFor import;对应测试改为 needs-authorization。 - 无人类发起人(定时/hook)仍 deny 但不取链接、不发消息。 Co-Authored-By: Claude Code <noreply@anthropic.com>
修两个会把人锁在授权循环外的阻断问题: - lark-cli 设备码是两段式:浏览器点完本地零写入,必须再用 --device-code 轮询一次,token 才会落进按人 HOME。此前轮询只在 /login done 里发生, turn 路径只查目录,导致拒绝文案承诺的「点完直接重试」必然再次被拒、 循环到用户自己猜到 /login done。新增 resolveLarkCliHomeForTurn,在 判定前对未完成的 challenge 轮询至多一次,与 bytedcli 的 mintBytedcliJwts 逐字对称;未授权者轮询后仍无 HOME,继续被拒。 - bytedcli 的 challenge 收尾此前是硬闸:轮询非 authorized 就直接 return null,根本不读这个人本来有效的登录态;叠加被拒时自动 begin, 一次网络抖动就能把已授权者锁到 50 分钟 TTL。改为尽力而为:无论轮询 结果如何都落回 HOME/JWT 读取,由后者作权威判定;终态 failed(含 lark-cli)同时清掉死 challenge,下一次 begin 换新链接,pending 保留以便继续扫码。 - 顺手修掉 #1382 的目录误判:runAsUser 每次调用都会 mkdir HOME, hasBytedcliHome 只判目录存在会把「发起过但没授权」报成已授权; 改为要求 bytedcli 数据目录下存在真正的凭证文件(token[.<env>].json 或 sso_session[.<env>].json,已对照本机 bytedcli 安装核实布局)。 - ToolIdentityOutcome.state 移除已不可达的 'bot-identity'(lark-cli 的 bot 降级路径已在本 PR 删除,没有任何产出方)。 Co-Authored-By: Claude Code <noreply@anthropic.com>
- /status 的 trigger-user auth 行此前把「未授权」描述成「当前以 bot 身份调用」,但 lark-cli 的 bot 降级已移除,实际命令会被直接拒;且 授权判定只读旧的 user-token 库,走设备码按人 HOME 授权过的人会被 显示成未授权。改为 HOME 或旧 token 任一存在即「以你自己的身份」, 未授权一律描述为拒绝并附自动链接;bytedcli 行同样只看真实 HOME。 - /login done 此前用 replied 互斥:lark 有 challenge 或已授权时, pending 的 bytedcli 收尾永远够不着,已授权 lark 的人只会收到 「没有进行中的登录」。改为两个身份提供方各自独立判定、一次回复, 无 challenge 但已授权时直接报已授权。 - /login lark 与裸 /login 的授权引导补上 lark_step2(此前该文案键 - 定义后零使用):点完链接直接重试即可,/login done 仅作确认路径; lark_no_challenge 换成两个提供方通用的 no_challenge。 Co-Authored-By: Claude Code <noreply@anthropic.com>
fallback 字段当前对两个被治理工具都不再产生降级行为(bytedcli 从来 没有 bot 身份,lark-cli 的 bot 降级随按人 HOME 模型移除),但设置页 仍提供「降级到 bot 自己的身份」选项、配置 hint 也这么描述。设置页改 为只读的实际行为说明;解析器与类型保留该字段以兼容存量配置,注释改 为「仅兼容保留」。 Co-Authored-By: Claude Code <noreply@anthropic.com>
a6cea38 to
c422362
Compare
|
🚀 Released in v3.27.0 |
背景
按触发人(飞书消息发送者)让 lark-cli / bytedcli 以其本人身份执行。本 PR 在 #1382(bytedcli 缺凭证自动发起设备码 +
/login对 canTalk 放权)之上,把 lark-cli 拉齐到同一套设备码/按人 HOME/自动授权体验,收敛成一个完整方案。改动(相对 #1382 的增量,11 文件)
services/lark-cli-auth.ts:per-person HOME~/.botmux/data/lark-cli-home/<openId>/;设备码auth login --no-wait/--device-code;从机器级 issuer HOME bootstrap app 凭证(master.key+appsecret);未过期 challenge 复用(同轮不重复弹)。签发 app 来源:BOTMUX_LARK_CLI_ISSUER_HOME> 托管~/.botmux/data/lark-cli-app-bootstrap> 操作员 lark-cli HOME。cli-identity.ts:新增user-home身份模式,wrapper 以 per-person HOME 执行 lark-cli(不注入 user token);保留 turn 绑定、缺失目录即拒(exit 77)。turn-cli-identity.ts:lark-cli 优先 per-person HOME(回退旧 bot-app user token);lark-cli 缺凭证时也自动 begin 设备码、把有效链接嵌入拒绝 stderr(与 bytedcli 同款)。/login:新增/login lark设备码入口、/login done同时收尾两种设备码;/login status按 per-person HOME 分报 lark/byted 状态。on_auth_link:拒绝 stderr 含链接时用botmux send逐字原样转发、停下等授权、禁止换身份/假装成功。.bd-rowgrid 下被压成两行(checkbox 居中在文字上方)的错位(css specificity 1:1 覆盖)。关键事实(飞书身份层,代码绕不过,写入说明)
影响面
验证
tsc --noEmit0;bun run build通过