Skip to content

离线使用

NodeWarden 支持离线访问保险库,即使在网络不可用时也能查看和使用已缓存的密码。

工作原理

缓存机制

NodeWarden 使用多层缓存策略:

  1. Service Worker 缓存

    • 应用外壳(HTML、CSS、JS)
    • 静态资源(图标、字体)
    • 预缓存的 API 响应
  2. IndexedDB 缓存

    • 保险库数据(ciphers、folders、sends)
    • 同步响应完整快照
    • 附件元数据
  3. localStorage 缓存

    • 离线解锁记录
    • 用户配置偏好

离线解锁

当成功在线登录后,NodeWarden 会自动保存离线解锁记录,包含:

  • 用户邮箱
  • 加密的 Profile Key
  • KDF 迭代次数
  • Profile 快照(用户名、是否启用高级功能等)

下次离线时,输入主密码即可解锁本地缓存的保险库。

支持的离线解锁方式:

  • ✅ 主密码解锁
  • ✅ Passkey PRF 密钥解锁(如果已启用)
  • ❌ 生物识别解锁(需要在线验证)

网络状态检测

NodeWarden 主动检测网络连接状态:

  • 检测超时 - 3.5 秒
  • 结果缓存 - 5 秒
  • 检测方式 - 向服务器发送轻量级请求

UI 会实时显示当前连接状态(在线/离线)。

功能可用性

离线可用功能

功能离线可用说明
查看密码已缓存的条目
搜索条目本地搜索
复制密码
TOTP 生成本地生成
查看附件列表仅元数据
查看 Sends已缓存的
查看文件夹
离线解锁主密码或 Passkey PRF

离线不可用功能

功能离线可用说明
创建新条目需要服务器分配 ID
编辑条目需要同步到服务器
删除条目需要服务器确认
上传附件需要网络传输
下载附件未缓存的附件
创建 Send需要服务器生成 URL
修改主密码需要服务器验证
同步保险库需要网络连接
注册新账户需要服务器处理

限制

数据新鲜度

离线缓存的数据是最后一次成功同步的快照。如果:

  • 在其他设备上修改了保险库
  • 其他用户共享了新条目
  • 服务器上删除了条目

这些变更在离线时不会反映到本地。下次联网同步后才会更新。

存储空间

浏览器对 PWA 本地存储有配额限制:

  • Chrome / Edge - 通常可用空间的 60%
  • Safari - 约 1GB
  • Firefox - 约 10% 可用空间,最多 2GB

如果缓存数据超过配额,浏览器可能:

  • 拒绝缓存新数据
  • 清除旧缓存
  • 提示用户授予更多空间

大型保险库(数千条目 + 大量附件元数据)可能接近限制。

附件预览

离线模式下:

  • 附件元数据(文件名、大小)可查看
  • 附件内容无法下载(除非已预缓存)

未来版本可能支持附件预缓存功能。

安全考虑

离线解锁记录存储在浏览器本地:

  • ✅ Profile Key 使用主密码派生密钥加密
  • ✅ 不包含明文主密码
  • ⚠️ 如果设备被物理访问,有暴力破解风险
  • ⚠️ 清除浏览器数据会删除离线解锁能力

建议:

  • 在共享设备上使用完毕后清除浏览器数据
  • 为主密码使用强密码
  • 启用设备加密(BitLocker / FileVault)

清除离线数据

方法 1:应用内清除

  1. 打开 NodeWarden
  2. 进入 设置安全
  3. 点击 清除离线解锁记录

方法 2:浏览器清除

Chrome / Edge:

  1. 设置隐私和安全清除浏览数据
  2. 选择 缓存的图片和文件Cookie 和其他网站数据
  3. 点击 清除数据

Safari:

  1. Safari设置隐私
  2. 点击 管理网站数据
  3. 搜索 NodeWarden 站点并删除

Firefox:

  1. 设置隐私与安全
  2. Cookie 和网站数据管理数据
  3. 搜索 NodeWarden 站点并删除

Web Worker 后台解密

NodeWarden 使用 Web Worker 在后台线程处理保险库解密:

优势:

  • 不阻塞 UI 渲染
  • 大型保险库解密时界面仍可响应
  • 充分利用多核 CPU

工作流程:

  1. 主线程将加密数据和密钥发送到 Worker
  2. Worker 执行密钥派生和解密
  3. Worker 返回解密后的保险库数据
  4. 主线程更新 UI

详见 前端架构 - Web Worker

故障排除

离线解锁失败

可能原因:

  • 从未在该设备上成功在线登录
  • 主密码已修改,离线记录未更新
  • 浏览器数据被清除

解决方法:

  • 恢复网络连接并重新登录
  • 登录成功后离线记录会自动更新

缓存数据不完整

可能原因:

  • 上次同步时网络中断
  • 浏览器存储配额不足

解决方法:

  • 恢复网络连接
  • 进入保险库,手动触发同步
  • 清除浏览器缓存并重新登录

Service Worker 未注册

症状:

  • 离线时应用完全无法加载
  • 没有离线提示页面

解决方法:

  • 检查浏览器是否支持 Service Worker
  • 确认访问的是 HTTPS 站点(localhost 除外)
  • 清除浏览器缓存并刷新页面

IndexedDB 操作失败

可能原因:

  • 浏览器隐私模式(Private/Incognito)
  • 浏览器设置禁止本地存储

解决方法:

  • 使用普通浏览模式访问
  • 检查浏览器设置,允许网站存储数据

技术细节

缓存更新策略

静态资源:

  • 策略:Cache First
  • 后台检查更新,下次启动时生效

API 响应:

  • 策略:Network First
  • 网络失败时返回缓存
  • 成功响应自动更新缓存

保险库数据:

  • 每次成功同步后完整更新
  • 使用事务保证原子性

离线检测逻辑

1. 检查 navigator.onLine(粗略判断)
2. 发送 HEAD 请求到 /alive endpoint
3. 3.5 秒超时视为离线
4. 结果缓存 5 秒避免频繁请求

相关文件

  • webapp/src/lib/offline-auth.ts - 离线解锁记录管理
  • webapp/src/lib/network-status.ts - 网络状态探测
  • webapp/src/lib/vault-cache.ts - IndexedDB 保险库缓存
  • webapp/src/workers/vault-decrypt.worker.ts - Web Worker 解密
  • webapp/vite.config.ts - Service Worker 生成配置