Repository navigation
Issue 107 Validation
- Issue:设置页管理命名令牌,仓库 PR/MR 按名称选择
- PR:#110
- 设计:Issue-107
- 代码提交:ab58fb7fa578fcc557369a9377f3f2773b3a5879
- 基线:
development/50cce92b691496457d0a912d068cad3ded874fa2 - 验证日期:2026-09-28
- 环境:macOS 15.5 arm64、Node.js 25.5.0、Electron 44.2.0
- 状态:功能已实现;本地验证通过,真实私有平台与 Windows/Linux 原生桌面待验收。
此前 PR/MR 认证值只存在于视图内存中,离开视图后需要重新输入。现在可在“设置 → 应用 → 访问令牌”保存名称和值,再到仓库搜索名称并“应用到此仓库”。仓库和远端独立保存选择,返回视图、重新加载和重启后可以恢复。保存一个命名令牌不会自动应用到其他仓库。
列表只展示名称、固定遮罩、作用域及关联。改名保留关联,更换值用于后续请求,删除前展示受影响的仓库远端,删除后要求重新选择。从仓库进入管理页可保存并返回原仓库/远端,但仍需明确应用。匿名读取和原有临时输入继续可用。
| 部分 | 最终实现 |
|---|---|
| 令牌管理 |
AccessTokensService 使用稳定 ID;名称去除首尾空格、忽略大小写唯一,新增/更换时校验令牌格式。普通响应不包含明文或密文。 |
| 数据持久化 | SQLite 分别保存元数据、密文及仓库远端关联;事务与 revision 检查保护并发修改、首次主机绑定、删除影响预览后的保存。 |
| 作用域 | 首次明确应用绑定 provider 与规范化 HTTPS origin(含端口);项目、主机或平台变化后旧关联失效,恢复旧地址也不会自动启用。 |
| 凭据使用 | 后端重新读取实际 Git 远端后才解密;认证头只用于校验后的目标,拒绝重定向;令牌或关联变更后的在途响应不能覆盖新状态。 |
| 存储实现 | 从 AI 模块抽取共享 secrets 模块,保留兼容导出和原 ai-master-key。独立服务使用 AES-GCM;桌面由主进程提供 safeStorage,拒绝不受保护的 Linux 存储后端。 |
| 桌面导入 | 首次导入独立数据库时,事务性地把访问令牌重加密为系统存储格式,保留 ID/作用域/关联。不可用时不覆盖原密文,保留标记供下次启动重试。 |
| 同步与失败恢复 | WebSocket 通知刷新元数据;过时读取不能恢复已删除记录。加密不可用或密文损坏时拒绝使用凭据,仍可改名、删除、匿名读取或临时输入。 |
主要代码:访问令牌服务、共享加密存储、导入迁移、设置界面、PR/MR 界面。
命令默认在代码仓库根目录执行;桌面 smoke 的工作目录单独注明。托管平台 HTTP 响应由测试模拟,Nest、SQLite、本地 Git、SSH fixture 和 macOS Electron 为实际执行。
| 命令 / 场景 | 实际结果 | 覆盖与边界 |
|---|---|---|
npm run test -w server -- --runInBand |
16 个套件,178 项通过 | 包含令牌生命周期、并发冲突、主机/端口/平台隔离、独立存储重启、加解密失败、删除清理、迁移事务和原有服务回归。 |
npm run test -w web |
151 项通过 | 包含元数据请求竞态与已有工作区、PR/MR 行为回归。 |
npm run test:e2e -w server -- --runInBand |
1 项通过 | 使用隔离数据目录启动完整 Nest 模块,验证基础 HTTP 路径。 |
node --test apps/web/tests/pull-requests.integration.cjs |
2 项通过 | 实际 Nest/SQLite/Git/SSH 链路;验证真实远端发现、目标约束、命名令牌 HTTP 生命周期及响应不含凭据,平台响应模拟。 |
npm run desktop:test:unit |
42 项通过 | 桌面安全存储、IPC、偏好设置及更新行为回归。 |
npm run desktop:build |
通过 | 共享包、服务端、前端与桌面暂存构建通过,包含原生 SQLite 重建。 |
node scripts/smoke.mjs,工作目录 apps/desktop
|
write / restore 两个独立进程通过 | 实际 macOS safeStorage 密文、Git 远端关联、重启恢复、删除后清理密文和引用;AI、外观、侧栏恢复回归通过。 |
| 浏览器:新增、必填/重名校验、搜索、保存并返回仓库、明确应用、改名、删除、重载与视图切换 | 通过 | 使用正式应用和虚构项目/令牌,不连接真实私有账号。 |
| 浏览器:匿名读取、PR/MR 列表分页与搜索、浅色/深色、1280px/390px、键盘切换令牌可见性 | 通过 | 窄窗口无横向溢出;显示切换保留键盘焦点。 |
git diff --check |
通过 | 提交前差异检查。 |
上述单元、端到端和集成测试共 374 项通过;桌面构建、跨进程 smoke 和浏览器检查另计。
本轮桌面 smoke 首次执行时暴露测试仓库残留影响后续检查、DELETE 空响应被测试助手当作 JSON 解析的问题;已修正 fixture 清理和空响应处理,重新执行 write/restore 两个进程均通过。输入框可见性切换的键盘焦点问题也已修正并复验。
最终桌面日志包含侧栏 smoke 刻意写入损坏偏好 JSON 后产生的预期错误;该用例验证失败写入不会覆盖原有偏好,整体测试退出码为 0。原型阶段“尚未实施”的记录仍保留在设计页,不回写为当时已经验证。
以下截图均为虚构项目与测试数据,令牌值保持遮罩。原型截图继续留在设计页,本节“实现后”来自正式应用。
复用 Issue #98 的历史实际应用截图作为行为基线,展示原临时令牌入口;这不是本次原型截图,也不是本次重新拍摄的基线。






- 未连接真实 GitHub 私有仓库、GitLab.com 私有项目或自建 GitLab 实例;真实个人/项目/群组令牌权限、组织 SSO、证书和网络差异待验收。模拟测试不能替代这些结果。
- Windows/Linux 原生 Electron、安全存储与应用重启未执行。macOS safeStorage 结果只代表本次 macOS arm64 环境。
- 独立数据库导入的成功、失败与回滚由自动化验证;真实用户资料的首次桌面启动导入尚未人工验收。
- 沿用原 PR/MR 支持范围:自建 GitLab 需本机可达、可信 HTTPS、根路径部署;不新增 HTTP 实例、路径前缀、SSH 主机别名或 GitHub Enterprise 支持。
- 更换值保留已有平台/主机作用域;同一凭据用于另一主机需新建命名记录。删除只移除 Alune 保存的数据,不在托管平台撤销令牌。
- SQLite 新增表按需创建,保留原 AI 密钥文件和兼容导出。代码回退不会自动移除新增表或撤销 Wiki 更新;迁移后的系统密文不能假定可由独立服务的本机密钥读取,导入源数据库和密钥保持保留。
PR 使用 Refs #107,不自动关闭 Issue。真实平台与跨平台验收补齐后再确认最终验收状态。
设计文档首页 · Alune 品牌说明 · 维护约定 · 代码仓库