Skip to content

Latest commit

 

History

History
131 lines (97 loc) · 5.74 KB

File metadata and controls

131 lines (97 loc) · 5.74 KB

核心概念

新版(v0.2)把概念缩减到 两个Sync SecretAdmin Key。本文解释它们的区别、组合行为、以及典型使用场景。


一、两个核心密钥

🔑 Admin Key(服务端 ADMIN_KEY 环境变量)

作用:身份证明。承担三件事:

  • 同步写入鉴权(PUT /api/sync)
  • 云端浏览鉴权(POST /api/admin/list-all)
  • 分享写入鉴权(PUT /api/share,PUT /api/sharekey)

特性:

  • 由你(管理员)部署时设置;客户端登录时输入
  • 客户端仅保存在当前标签页会话的 sessionStorage;关闭浏览器会话后需要重新输入
  • 解锁后整个会话内有效(管理员模式 sessionStorage 标志)
  • 忘记可以改服务端环境变量重新设置

分享链接恢复材料默认不保存。生成分享时可显式选择保存到 /api/sharekey,供其他管理员设备重新复制链接;无口令分享开启该选项后,服务端管理员也具备解密能力。口令保护的分享只保存被口令包裹后的恢复材料。

兼容字段:旧版 SYNC_TOKENKV_ADMIN_KEY 仍然有效,与 ADMIN_KEY 等价。所有 endpoint 的鉴权统一在 functions/_lib/auth.js 处理,使用恒时比较以降低时序攻击面。

🔐 Sync Secret(每个同步项目独立)

作用:端到端加密密钥。客户端用 PBKDF2(secret, "sync:" + syncId) 派生 AES-GCM 256 位密钥,加密整个 items 列表后才上传到云端。

特性:

  • 由你为每个项目独立设置
  • 跨设备必须一致(否则解不开同一份云端密文)
  • 服务端永远看不到,也无法重置
  • 忘记后云端数据无法恢复(除非启用了 RSA 密钥托管)

二、SYNC_MODE:strict 与 open

模式 GET /api/sync PUT /api/sync 适用场景
strict(默认) 需要 Admin Key 需要 Admin Key 个人 / 小团队私用,最大隐私
open 公开(任何人可下载密文) 需要 Admin Key 公开实例,密文靠 Sync Secret 保护即可

若服务端没有配置任何密钥(既没 ADMIN_KEY 也没 SYNC_TOKEN),则等价于 open 模式且写入也不鉴权——仅适合内网或测试。


三、典型场景

场景 1:访客即点即用

不配置任何环境变量也可以。访客:

  • 打开页面 → 加 2FA → 看验证码 → 关闭浏览器后数据仍在
  • 数据只在浏览器 localStorage,不会上传任何服务端
  • 完全离线可用,PWA 装到主屏

注:如果服务端配置了 ACCESS_GATE,访客需要先通过站点访问口令才能进入页面,但数据本身仍只在本地。

场景 2:你自己多设备同步(推荐配置)

  1. 部署时配 ADMIN_KEY = "强随机字符串-自己记住"
  2. SYNC_MODE 不设 → 默认 strict(最严)
  3. 设备 A:
    • 关于 → 输入 Admin Key 登录
    • 项目 → 新建项目(项目名 / Sync ID / Sync Secret)
    • 自动推送,或手动点"⬆ 推送"
  4. 设备 B:
    • 同样登录 Admin Key
    • 新建项目,填完全相同的 Sync ID + Secret(项目名可不同)
    • 点"⬇ 拉取"

期间任何普通访客的 GET 请求都返回 401,看不到任何云端数据。

场景 3:公开实例,社区共享

  1. 配置 ADMIN_KEYSYNC_MODE = "open"
  2. 任何人可以下载密文,但没 Sync Secret 解不开
  3. 只有你能写入

场景 4:管理员保管密钥(Vault)

担心忘记 Sync Secret 后数据无法恢复?启用密钥托管:

  1. 生成一对 RSA 密钥(推荐 4096 位)
  2. 在客户端"管理员 → 密钥托管"启用,填公钥
  3. 选中云端项目 → 点"托管选中项目密钥"
  4. 后端 vault:<syncId> 存储用 RSA-OAEP+AES-GCM 加密的 Sync Secret
  5. 私钥离线保存(U 盘 / 密码管理器)
  6. 任何时候,用私钥从"找回选中项目密钥"取回 Secret

四、本地数据与主密码

无论是否同步,本地数据可选用主密码加密:

  • 设置后:localStorage 中是 {v:2, iv, ct} 格式的 AES-GCM 密文
  • 重启浏览器需要先输入主密码才能解锁
  • 与 Sync Secret 完全独立(一个保护本地,一个保护云端)

五、权限矩阵

操作 无项目 有项目(无 Admin Key) 有项目(有 Admin Key)
添加 / 复制 / 删除(本地)
推送到云端 ❌ (401)
从云端拉取(strict) ❌ (401)
从云端拉取(open) ✅ 但密文
分享验证码 ❌ (写入需要 Admin Key)
撤销分享
云端浏览 / Vault / 迁移

六、调试清单

现象 检查
401 推送失败 抽屉「关于」是否登录 Admin Key?key 是否与服务端 ADMIN_KEY 一致?
拉取后数据空 Sync ID 是否与对端一致?
拉取后解密失败 Sync Secret 是否与对端一致?
摄像头扫描不工作 必须 HTTPS(npm run dev:https);不支持的浏览器请用图片识别或链接粘贴
改了代码刷新没生效 Service Worker 缓存。Application → Service Workers → Unregister 后刷新
升级后看到空白 主密码加密的数据需要先在抽屉"数据"里解锁

七、"全部汇总视图"是什么?

抽屉「项目」里有「📊 全部项目(汇总视图)」入口。它是纯本地的虚拟视图

  • ✅ 显示你已创建的所有项目的验证码合并结果
  • ❌ 不会主动拉取你不知道的云端项目
  • ❌ 不会显示其他用户的数据
  • 工作原理:遍历 state.syncProjects 数组,把每个项目的 itemsData 合并

要看到一个云端项目,必须主动在「项目 → 新建」中填它的 Sync ID + Secret。