Skip to content

Feat: 添加应用锁屏功能#1609

Open
Ryanisgood wants to merge 49 commits into
binaricat:mainfrom
Ryanisgood:feature/app-lock-screen
Open

Feat: 添加应用锁屏功能#1609
Ryanisgood wants to merge 49 commits into
binaricat:mainfrom
Ryanisgood:feature/app-lock-screen

Conversation

@Ryanisgood

@Ryanisgood Ryanisgood commented Jun 24, 2026

Copy link
Copy Markdown
Contributor

变更内容

新增 Netcatty 应用锁屏能力:应用可以在主界面渲染前锁定,也可以从顶部标签栏手动锁定,并支持空闲超时、隐藏到后台、重新打开等场景下的锁定/恢复。

本 PR 目前覆盖的是完整 App Lock 链路:

  • 新增锁屏密码 verifier 创建、密码修改、禁用/重置 App Lock、锁屏设置持久化。
  • 新增 AppLockGate 启动 gate,避免启动锁定时主界面先渲染到锁屏背后。
  • 新增锁屏 Overlay,支持密码解锁、系统认证解锁、错误提示、自动聚焦和重开后的状态刷新。
  • 顶部标签栏新增手动锁定入口;设置页新增 App Lock 配置区。
  • 新增空闲活动记录和空闲超时锁定,支持禁用空闲自动锁定。
  • 主进程新增 App Lock 生命周期处理:隐藏到后台、退出前处理、激活/重开、主窗口崩溃后的恢复、终端弹窗 route ownership。
  • 新增 renderer/main IPC bridge:设置读取/更新、runtime state、reset、lock/unlock、activity report、系统解锁状态等。
  • 新增系统解锁能力:
    • macOS 通过 Electron systemPreferences 使用 Touch ID。
    • Windows 通过打包的 native helper 使用 Windows Hello。
  • 新增 Windows Hello helper 构建与打包:
    • per-arch helper 输出。
    • PE machine 架构校验。
    • MSVC 开发环境初始化。
    • Windows 打包架构处理,避免 x64 打包误触发 arm64 helper。
  • 补充 App Lock 相关多语言文案。
  • 补充功能所需的开发/构建适配:dev CSP、jsdom runtime 测试、CI Windows MSVC setup。

给 Reviewer 的说明

这个 PR 的 diff 比“添加锁屏”听起来大,因为它不是单个 UI Overlay,而是跨 renderer gate、Electron 生命周期、持久化设置、IPC、安全认证、Windows native helper 打包和回归测试的一整套功能。

当前 PR 统计:

  • 69 个文件,+8888/-220。
  • 测试和 test support 约 +4554 行。
  • Renderer/UI/state 约 +1813 行。
  • Electron main/bridge/packaging 约 +1424 行。
  • Windows Hello helper/build script 约 +324 行。
  • package.json / package-lock.json 约 +505 行。

Windows Hello/helper 打包相关内容包含在这个 PR 里,是因为 UI 已经暴露了系统解锁入口,而 Windows 需要 native helper 才能完成该路径。如果希望降低 review 面积,可以把本 PR 收敛为“密码锁屏核心”,再把系统解锁/Windows Hello 拆成后续 PR。

行为细节

  • 只有在 App Lock 已启用且存在 password verifier 时才真正锁定。
  • 启动锁定会 gate 主 renderer,防止解锁前看到主界面内容。
  • 空闲锁定支持关闭;timeout 为 disabled/0 时不会自动空闲锁定。
  • 禁用 App Lock 会删除当前 password verifier;后续重新启用必须创建新密码。
  • reset 需要当前密码,成功后会关闭 App Lock、清空 verifier 并解锁当前 runtime。
  • Overlay 保留隐藏重置入口,避免忘记密码后完全锁死。
  • 系统解锁的“支持/可用”和“设置中启用”分开判断。
  • reset/unlock bridge 缺失或失败时不会乐观解锁,避免假解锁。
  • 重开/聚焦时会重新同步 runtime lock state,避免窗口恢复后显示旧状态。

安全与锁死风险处理

  • 正确密码解锁后,主进程更新 runtime state 并广播到相关窗口。
  • App Lock 已关闭或 verifier 已清空时,解锁请求会直接放行,避免设置状态与 UI 状态不一致导致锁死。
  • reset IPC 缺失或失败时保持锁屏并提示错误,不会直接放行。
  • 系统解锁失败、取消、不可用会返回明确状态,不会影响密码解锁路径。
  • Windows Hello helper 构建产物会校验目标架构,避免打包错误架构的 exe。
  • 退出前 dirty editor 检查和后台锁定保持兼容,避免退出流程被锁屏状态打断。

验证

合并最新 upstream/main 后已在本地验证:

  • git diff --name-only --diff-filter=U:无未解决冲突。
  • git diff --cached --check:提交 merge 前通过。
  • npm run lint:通过,0 errors,2 个已有 warnings。
  • npm run generate:capability-tools + generated JSON diff check:无 drift。
  • npm test:4007 tests,4004 passed,0 failed,3 skipped。
  • npm run build:通过。

冲突解决后已推送当前 head commit,并重新触发 CI。

关联 Issue

关联 #672
关联 #955

@Ryanisgood Ryanisgood changed the title 添加应用锁屏与应急重置机制 添加应用锁屏功能 Jun 24, 2026

@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: 5be97aa5e0

ℹ️ 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".

notifyRendererReady: boolean;
renderChildren: boolean;
}): boolean {
return input.notifyRendererReady && input.renderChildren;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Keep startup deep links queued while locked

When Netcatty is launched from an ssh:// link with App Lock enabled, renderChildren stays false on the startup lock screen, so this suppresses rendererReady until the user unlocks. deliverSshDeepLink waits on sendWhenRendererReady with a 15s timeout after the URL has already been shifted from the pending queue, so taking longer than that to enter the password drops the deep link instead of connecting after unlock. Consider keeping the deep link queued/buffered while locked or separating renderer readiness from app-content mounting.

Useful? React with 👍 / 👎.

@Ryanisgood Ryanisgood changed the title 添加应用锁屏功能 Feat: 添加应用锁屏功能 Jun 24, 2026
@Ryanisgood Ryanisgood marked this pull request as draft June 24, 2026 08:27
@Ryanisgood Ryanisgood force-pushed the feature/app-lock-screen branch from f1f1586 to 90db33c Compare June 29, 2026 09:10
@Ryanisgood Ryanisgood marked this pull request as ready for review June 30, 2026 01:11

@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: 17b6130014

ℹ️ 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 on lines +38 to +41
return !(
input.locked &&
input.lockReason === 'startup' &&
!input.hasRenderedChildren

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Defer deep links until background locks are cleared

When a new renderer opens while the shared runtime is already locked for background or idle (for example, Netcatty was hidden to tray and then an ssh:// link is opened), this predicate still renders the app children because it only suppresses startup locks. That lets the renderer report ready and register App.tsx's onSshDeepLink handler, which immediately calls handleConnectToHost when main delivers the URL, so a saved-credential connection can start behind the lock screen before the user unlocks. Consider gating first-render/readiness for all locked reasons, or queueing external actions until unlock.

Useful? React with 👍 / 👎.

@binaricat binaricat mentioned this pull request Jul 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant