Skip to content

feat(webdav): WebDAV 私有备份与跨设备账号同步 - #186

Open
t3nc wants to merge 1 commit into
changexbc:mainfrom
t3nc:feat/webdav-sync
Open

t3nc wants to merge 1 commit into
changexbc:mainfrom
t3nc:feat/webdav-sync

Conversation

@t3nc

@t3nc t3nc commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

背景

账号库 ~/.wb-switch/accounts.json 含全部授权信息(access/refresh token、auth_raw 等),跨设备迁移只能手动导出 JSON 文件再导入。本 PR 接入私有 WebDAV 服务器做端到端加密备份,并支持不同设备之间同步软件信息与账号授权信息(issue 需求:#webdav 私有备份)。

方案(两个关键取舍,均已确认)

  • 客户端加密(口令派生密钥):PBKDF2-HMAC-SHA256(60 万轮)→ AES-256-GCM。备份文件自描述明文头(格式版本 / 更新时间 / 设备名 / 账号数)+ 密文体,云端备份元信息无需密码可读,解密失败即密码错误。WebDAV 服务器与中间人接触不到凭据明文。
  • 备份范围 = 账号库 + 各功能配置(签到 / 旅行 / 限额 / 自动轮换 / 更新源 / WebDAV 自身),不含日志 / 缓存 / 会话库。恢复可按白名单逐项写回,版本漂移安全。

改动

  • wb-switch-core 新增 webdav_sync 模块:
    • 信封:魔数 WBSWITCH-SYNC-V1 + u32 头长 + 明文头 JSON + 16B 盐 + 12B nonce + GCM 密文;派生 / 加解密走 spawn_blocking(KDF 是 CPU 密集)。
    • 备份载荷:account::load_accounts() 全量 + 固定 6 项配置(config::load_checkin_config / load_travel_config / load_rate_limit_config / load_auto_rotate_config / update::load_github_config / 本模块配置,含服务器口令以便新设备一次恢复即连上同一服务器,随整包加密保护)。
    • WebDAV 客户端:复用 config::http_request_raw,新增二进制变体 http_request_bytes(任意方法 / Content-Type / 请求体,PUT/GET 独立 300s 超时),PROPFIND→缺失 MKCOL(405=已存在视为成功)→PUT(If-Match 条件写,412 即报冲突不覆盖)→GET(带 ETag 回读)。
    • 同步语义:GET → export_import::merge_import_records 按 uid 全量合并(同 uid 覆盖、缺 token 跳过)→ 整库 + 本机配置快照 PUT;note/displayField 沿用既有「本地缺失才回填」规则。
    • 口令存储:webdav_config.json 脱敏视图不回显明文,save 空提交保留旧值;新增单测覆盖该行为。
  • Tauri 命令 + axum 路由双宿主对等(8 个),src-tauri/src/commands.rs、lib.rs、wb-switch-server/src/api.rs。
  • 前端:SettingsPage 新增 WebdavSyncCard(服务器 / 用户名 / 口令 / 目录 + 测试连接 + 备份 / 同步 / 恢复),恢复弹框 WebdavRestoreDialog 支持勾选账号 + 可选「同时恢复功能配置」;types.ts / api.ts 补齐类型与 ROUTES。
  • 测试:14 条单测(信封往返 / 错密 / 魔数校验 / URL 归一化 / 口令保留 / 配置快照跨设备)+ 1 条进程内双设备全链路 e2e(crates/wb-switch-core/tests/webdav_e2e.rs,内置最小 WebDAV 服务器:PROPFIND / MKCOL / PUT(ETag+If-Match) / GET,覆盖 测试连接 → 备份 → 跨设备同步 → 新设备恢复 + 写回配置 → 412 冲突路径)。

验证

  • cargo test -p wb-switch-core:796 全过;cargo check 三 crate 通过;vitest 全过;tsc 无错误。
  • 实测本地最小 WebDAV stub(Basic auth)+ webui 服务:8 个路由全链路跑通;备份文件 grep 无明文 token / 无服务器口令;过期 If-Match 得 412;恢复后新设备 accounts.json 与 auto_checkin_config.json / webdav_config.json 均正确写回。

兼容性

  • 新增 webdav_config.json 与备份文件,不动既有文件;旧版客户端对 ~/.wb-switch 无感知,可安全回退。
  • 未新增第三方依赖:全部基于既有 aes-gcm / pbkdf2 / sha2 / base64 / reqwest。

🤖 Generated with Claude Code

- 新增 wb-switch-core webdav_sync 模块:账号库 + 6 项功能配置
  (checkin/travel/rateLimit/autoRotate/github/webdav)打包,
  经 PBKDF2-SHA256(60万轮) → AES-256-GCM 端到端加密后上传私有
  WebDAV 服务器;明文自描述头支持无密码读取云端备份元信息。
- WebDAV 客户端基于既有 reqwest/rustls 复用 config::http_request_raw
  (二进制变体 http_request_bytes):PROPFIND/MKCOL/PUT(ETag+If-Match)/GET;
  同步先拉取合并再条件写回,412 冲突即拒绝覆盖。
- 合并复用 export_import 既有 uid 去重语义;配置恢复按白名单经各模块
  既有 save_* 原子写回,未知键自动丢弃。
- Tauri 命令与 axum 路由双宿主对等:get/save_webdav_config、
  webdav_test_connection、webdav_backup、webdav_restore[_preview]、
  webdav_sync_now、webdav_info;配置口令只落盘一次,接口一律回脱敏视图。
- 前端:设置页新增「WebDAV 备份 / 跨设备同步」卡片(配置 + 测试连接 +
  备份/同步/从云端恢复),恢复弹框支持勾选账号并可选写回配置。
- 测试:14 条单测(信封往返/错密/URL 归一化/口令保留/配置快照跨设备)
  + 1 条进程内双设备全链路 e2e(内置最小 WebDAV 服务器);
  并实测本地 WebDAV stub + webui 服务端到端跑通 8 个路由。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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