实现客户端登录七天滑动续期
需求:解决短效访问令牌到期后客户端一小时掉登录的问题。 实现:由 Electron Main 加密管理并轮换刷新凭据,按真实用户活动续期,七天闲置后清理会话,并补齐并发、迁移和终态回归测试。
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
# Task: 客户端登录滑动续期与七天闲置失效
|
||||
|
||||
## Identity
|
||||
|
||||
- Task ID: 20260807-client-login-sliding-7d2a
|
||||
- Mode: Feature
|
||||
- Branch: codex/login-sliding-7d2a
|
||||
- Worktree: D:\Datas\OthersProjects\makelore-login-sliding-7d2a
|
||||
- Base commit: 7b23cce67a1b9e61a48d89dedbd088d37b10ecd4
|
||||
- Owner: codex
|
||||
- Status: Done
|
||||
|
||||
## Scope
|
||||
|
||||
- 修复客户端启动时 access token 过期即清空整个会话的问题。
|
||||
- 由 Electron Main 统一执行 refresh token 换取、轮换保存与并发单飞。
|
||||
- 记录真实用户活跃时间;每天使用可持续续期,连续 7 天未使用则要求重新授权。
|
||||
- 后台保活不计入用户活跃,并补齐 Main、Host API、Renderer Store 聚焦测试。
|
||||
|
||||
## Intent And Constraints
|
||||
|
||||
- access token 保持短效,不把 7 天直接改成长效 Bearer token。
|
||||
- 真实前台使用才推进滑动窗口;后台定时刷新不能无限延长登录。
|
||||
- 先判断 7 天闲置,再允许刷新,过期后不得被一次迟到的活动复活。
|
||||
- 保留 OAuth 返回的旋转 refresh token,并在 Electron Main 中加密、原子持久化;Renderer 不保存新 refresh token。
|
||||
- 所有代码与 Git 操作仅限隔离工作区,不触碰原 Makelore 工作区未提交改动。
|
||||
|
||||
## Plan
|
||||
|
||||
1. 用失败测试固定每日活跃、7 天边界、后台刷新和并发单飞语义。
|
||||
2. 扩展 Main 会话模型与 Host API,使刷新和活跃状态由 Main 统一管理。
|
||||
3. 调整 Renderer 启动恢复、持久化和前台/定时维护逻辑。
|
||||
4. 运行聚焦测试、类型检查、Lint、构建与文档漂移检查。
|
||||
|
||||
## Outcome
|
||||
|
||||
- 新增 Main-owned 会话服务:使用系统安全存储加密 refresh token,启动恢复、刷新单飞、
|
||||
轮换凭据落盘屏障与恢复失败保护均在 Main 内完成。
|
||||
- 真实键盘、鼠标、触摸活动每分钟至多推进一次 `lastActiveAt`,并在 access token 临近过期时
|
||||
触发刷新;后台令牌消费者不推进用户活跃时间。
|
||||
- 连续 7 天无真实活动后终止会话,并由 Main 统一清理 AI gateway 凭据、Provider key、
|
||||
OpenCode 运行时和绘画事件会话;清理与新登录串行,避免跨账号代际竞态。
|
||||
- Renderer 只持久化公开会话;旧版本已存在的 refresh token 仅在 Main 安全落盘成功前保留在
|
||||
原 localStorage,接管成功后立即移除;新 refresh token 从不返回或写入 Renderer。Linux
|
||||
`basic_text` 等不受保护的存储后端不会落盘 refresh token。
|
||||
- 临时密钥库/磁盘故障返回 503 并保留可恢复状态,不再误判为授权失效;过期、退出和并发刷新
|
||||
的终态/跨代边界均有回归测试。
|
||||
- Electron Store 外层 JSON 损坏会安全重建;密文暂时不可读时先保留,用户显式重新授权可清除
|
||||
不可恢复记录后继续登录,不会因坏记录永久卡在启动或 503。
|
||||
- 登出及终态清理会先撤销本地派生凭据,并使用清理前捕获的 Main access token 尝试关闭远端绘画
|
||||
事件会话;无论远端结果都轮换本地幂等键,显式登出仍会对远端关闭失败返回错误。
|
||||
|
||||
## Verification
|
||||
|
||||
- `pnpm exec vitest run tests/unit/auth-routes.test.ts tests/unit/works-square-session-persistence.test.ts tests/unit/works-square-session.test.ts tests/unit/auth-store.test.ts tests/unit/login-page.test.tsx tests/unit/works-square-design-workspace.test.ts`
|
||||
- 通过:6 files,85 tests。
|
||||
- `pnpm run typecheck`
|
||||
- 通过。
|
||||
- 针对本次变更文件运行 ESLint
|
||||
- 通过。
|
||||
- `pnpm run build:vite`
|
||||
- 通过;仅保留既有 chunk size/dynamic import 警告。
|
||||
- 全量 `npm test -- --reporter=dot`
|
||||
- 未全绿:21 项失败集中在隔离工作树缺少外部 `zip`、未检出的 `.opencode/agent` 资源及既有
|
||||
project progress sync 用例;认证聚焦测试全部通过。
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- 服务端与客户端需协调上线;先发布支持旋转凭据原子落盘的兼容版本并确认共享 `app` 客户端的
|
||||
所有使用方,再应用 OAuth 数据迁移并刷新 RegisteredClient Redis 缓存。
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
- None recorded.
|
||||
Reference in New Issue
Block a user