离线使用
NodeWarden 支持离线访问保险库,即使在网络不可用时也能查看和使用已缓存的密码。
工作原理
缓存机制
NodeWarden 使用多层缓存策略:
Service Worker 缓存
- 应用外壳(HTML、CSS、JS)
- 静态资源(图标、字体)
- 预缓存的 API 响应
IndexedDB 缓存
- 保险库数据(ciphers、folders、sends)
- 同步响应完整快照
- 附件元数据
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:应用内清除
- 打开 NodeWarden
- 进入
设置→安全 - 点击
清除离线解锁记录
方法 2:浏览器清除
Chrome / Edge:
设置→隐私和安全→清除浏览数据- 选择
缓存的图片和文件、Cookie 和其他网站数据 - 点击
清除数据
Safari:
Safari→设置→隐私- 点击
管理网站数据 - 搜索 NodeWarden 站点并删除
Firefox:
设置→隐私与安全Cookie 和网站数据→管理数据- 搜索 NodeWarden 站点并删除
Web Worker 后台解密
NodeWarden 使用 Web Worker 在后台线程处理保险库解密:
优势:
- 不阻塞 UI 渲染
- 大型保险库解密时界面仍可响应
- 充分利用多核 CPU
工作流程:
- 主线程将加密数据和密钥发送到 Worker
- Worker 执行密钥派生和解密
- Worker 返回解密后的保险库数据
- 主线程更新 UI
故障排除
离线解锁失败
可能原因:
- 从未在该设备上成功在线登录
- 主密码已修改,离线记录未更新
- 浏览器数据被清除
解决方法:
- 恢复网络连接并重新登录
- 登录成功后离线记录会自动更新
缓存数据不完整
可能原因:
- 上次同步时网络中断
- 浏览器存储配额不足
解决方法:
- 恢复网络连接
- 进入保险库,手动触发同步
- 清除浏览器缓存并重新登录
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 生成配置