Skip to content

fix(desktop): recover auth after credential backend failure - #3960

Open
dashhuang wants to merge 2 commits into
mainfrom
fix/auth-startup-recovery
Open

fix(desktop): recover auth after credential backend failure#3960
dashhuang wants to merge 2 commits into
mainfrom
fix/auth-startup-recovery

Conversation

@dashhuang

Copy link
Copy Markdown
Member

这次改了什么

摘要

修复 macOS 上 safeStorage 首次读取失败后登录状态显示异常的问题。Electron 会在进程内缓存该失败,Cindy 现在会在解锁且没有运行中任务时自动正常重启一次,重启后恢复已保存登录;同时为浏览器启动增加独立超时和明确错误。

变更类型

  • fix 缺陷修复

范围

  • 关联 Issue / 需求:用户反馈登录恢复失败
  • 本 PR 包含:凭证库失败诊断、自动恢复状态机、浏览器启动超时、登录错误提示及测试
  • 明确不包含:服务端改动、更新器实现改动
  • 用户可见变化:符合条件时自动恢复登录;无法恢复时保留凭证并给出可操作提示
  • 是否存在 breaking change:无

UI 变化

  • 引用的设计规范:docs/design-rules/DESIGN.md 双模式交付门槛;复用现有登录错误面板和语义主题 token,新增文案已覆盖五种 locale。

怎么验证的

自动验证

pnpm test:unit:related
pnpm --filter desktop run --if-present typecheck
定向认证、恢复、登录 UI、重启忙碌探针测试:148 tests passed
结果:通过

手工验证

不涉及:当前 worktree 未安装到正在运行的 Cindy.app,未执行真实锁屏重启。

未执行的验证

真实 macOS 锁屏 / 钥匙串拒绝场景未执行,原因是需要在用户运行客户端上复现;系统日志对历史故障没有保留原始 Keychain OSStatus。

风险

风险分类

  • 权限 / 安全 / 用户数据
  • 跨平台差异

影响与回滚

  • 影响范围:仅 macOS packaged Desktop 的已确认凭证后端故障;Windows/Linux 不启用自动重启。
  • 回滚 / 降级方式:回滚本 PR 即恢复原登录流程;自动恢复最多尝试一次,失败不删除凭证。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s
  • UI 改动已在「UI 变化」注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

Signed-off-by: Cindy <cindy@Cindys-Mac-mini.local>
@dashhuang
dashhuang requested a review from a team as a code owner September 5, 2026 07:30
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 5, 2026

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review Completed 2026-09-05T08:50:38.634771Z 5746376 New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 为 macOS 凭证后端首次读取失败增加一次性自动重启恢复,并为系统浏览器启动增加独立超时与明确错误提示。

  • 新增凭证故障健康信号和解锁后、空闲时的恢复状态机
  • 在 Desktop bootstrap 中接入屏幕事件、任务忙碌探针及正常重启流程
  • 统一 hosted/loopback 浏览器启动与授权超时错误
  • 为五种 locale 增加凭证恢复和浏览器错误文案,并补充相关测试
  • 当前自动重启可能与用户刚开始的认证流程竞争,需要补充认证活动阻断

Confidence Score: 4/5

当前不宜合并,因为自动恢复可能在用户正在重新登录或后台认证尚未完成时退出并重启应用。

恢复定时器会在重启前检查任务活动,但没有检查登录 action、浏览器授权或后台冷启动认证;这些流程提交前仍满足恢复条件,因此存在可达的中途重启路径。

Files Needing Attention: apps/desktop/src/main/bootstrap-electron.ts

Important Files Changed

Filename Overview
apps/desktop/src/main/authCredentialRecovery.ts 新增一次性、解锁感知且等待任务空闲的凭证故障重启状态机。
apps/desktop/src/main/bootstrap-electron.ts 接入恢复状态机及统一重启忙碌来源,但探针未阻止正在进行的认证流程。
apps/desktop/src/main/authManager.ts 诊断 safeStorage 后端故障、保留启动失败状态,并向登录流程提供可恢复错误。
apps/desktop/src/main/authBrowserLaunch.ts 为不可取消的系统浏览器启动增加取消、失败和 15 秒超时边界。
apps/desktop/src/main/authHostedCallback.ts 将 hosted 授权总超时从静默取消调整为明确的 REQUEST_TIMEOUT。
apps/desktop/src/renderer/components/login/LoginPage.tsx 复用现有错误面板展示保存登录仍被保留的凭证故障提示。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[启动读取保存凭证] --> B{凭证后端可用?}
  B -->|是| C[恢复登录]
  B -->|否| D[记录 CREDENTIAL_STORE_UNAVAILABLE]
  D --> E[等待屏幕可用并延迟 3 秒]
  E --> F{任务忙碌?}
  F -->|是| G[30 秒后重试]
  G --> F
  F -->|否| H[携带一次性标记重启]
  H --> I{新进程读取成功?}
  I -->|是| C
  I -->|否| J[停止自动重启并显示恢复提示]
Loading
Prompt To Fix All With AI
### Issue 1
apps/desktop/src/main/bootstrap-electron.ts:3063-3071
**认证期间可能自动重启**

凭证故障后,如果用户在 3 秒延迟内点击重试并开始登录,`needsCredentialProcessRecovery()` 在登录提交前仍为 true。这里的忙碌探针没有检查登录 action、浏览器授权或后台冷启动认证,因此可能误判为空闲并执行 `app.relaunch()`/`app.quit()`,中断正在进行的认证。请将这些认证活动纳入重启阻断条件。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "fix(desktop): recover auth after credent..." | Re-trigger Greptile

Comment thread apps/desktop/src/main/bootstrap-electron.ts

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 47b8dce481

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread apps/desktop/src/main/authManager.ts
@MagicLizi

Copy link
Copy Markdown
Contributor

@dashhuang 👋 这个 PR 还有 2 条 review conversation 没 resolve(apps/desktop/src/main/bootstrap-electron.ts / apps/desktop/src/main/authManager.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示) labels Sep 5, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/components/login/LoginPage.tsx)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@MagicLizi MagicLizi added status:ci-failed CI 失败(review-pr 自动维护,仅展示) and removed status:awaiting-bot-review 等外部审查机器人表态(review-pr 自动维护,仅展示) labels Sep 5, 2026
Signed-off-by: Cindy <cindy@Cindys-Mac-mini.local>

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5746376024

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

return finishColdStartSignedOut('cold-start-credential-reconcile-unavailable');
return finishColdStartSignedOut(
'cold-start-credential-reconcile-unavailable',
error instanceof AuthApiError && error.code === 'CREDENTIAL_STORE_UNAVAILABLE',

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Distinguish corrupt vaults from restartable backend failures

When the encrypted account vault contains invalid JSON/schema, readAuthAccountVault() also throws CREDENTIAL_STORE_UNAVAILABLE, so this marks the credential-store health unavailable even though safeStorage.isEncryptionAvailable() succeeded. In that case automatic process recovery is ineligible, getLoginState() keeps returning the recovery error, and runLoginAction() blocks every action except reset; reset reruns the same strict parse indefinitely. This removes the previous explicit-login path that used recoverInvalidForExplicitLogin: true to repair an invalid vault, leaving affected users unable to sign in or enter local mode. Only classify an observed encryption-backend failure as restartable, or preserve a route to the explicit-login recovery path for malformed records.

Useful? React with 👍 / 👎.

@MagicLizi

Copy link
Copy Markdown
Contributor

@dashhuang 👋 这个 PR 还有 1 条 review conversation 没 resolve(apps/desktop/src/main/authManager.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi

Copy link
Copy Markdown
Contributor

@dashhuang 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi MagicLizi added status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) status:ci-failed CI 失败(review-pr 自动维护,仅展示) and removed status:ci-failed CI 失败(review-pr 自动维护,仅展示) status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) labels Sep 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:security 改动碰到安全边界(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants