# 常用网站一体化与统一 Cloudflare（现行至 1.9.69）

## 1.9.73 授权界面

设置只显示整体授权状态和“授权连接/更新连接/完成连接”等当前主要操作，隐藏 MCP、个人数据云、网站与账号的三个状态框。服务仍独立部署，不合并 D1 或密钥。部分开通/恢复错误仍明确显示；已保存连接不是每次页面进入都实时健康检测。

个人数据 Worker 升至 v8 以保留十列布局，用户通过设置更新连接完成部署，无 D1 表迁移。原数据库及加密 Secret 必须保留。organizer 对旧云停止同步并保留待同步本机数据。

## 用户流程

1. 重载插件，进入设置 → 我的 Cloudflare，点击“绑定 Cloudflare”。一次 OAuth 授权并选账号。无需填写密码库邮箱或选择功能。
2. 插件先只读核对现有连接与未来 Worker 地址。首次账号须确认 workers.dev 子域名；预检不创建子域名。
3. 点击“完成开通”，在同一次真实点击中申请三个精确 Worker 网站权限，自动顺序部署 MCP、个人数据云、Warden，然后统一清除短期 OAuth。
4. 统一检查并连接：MCP 核对资格与 health 后启用；新网站账号库自动初始化，已有自动访问库恢复密钥；缺少原访问密钥的旧库保留并显示恢复状态，不能重新创建或覆盖。
5. 常用网站新增窗口直接录入网址、可选账号/密码/两步验证；同一站点可选择多个已存账号或新增。卡片点击跳转，角落菜单进入编辑。独立验证器在同一入口另一个 Tab。日常无需解锁。

已有连接与另一云账号不一致时停止，原件保留。权限/部署/连接部分成功必须分别显示；不能宣称全部完成。MCP 资格到期不启用；从账号备份恢复连接不会自动启用，仅用户明确完成连接或开关才启用。浏览器权限提示仍需确认，不保证浏览器永不询问。

## 数据边界

| 数据 | 存放、保护及恢复 |
| --- | --- |
| MCP Tool、任务和报告 | 浏览器本机，用户 Worker + DO 实时中转，不写业务 D1/R2 |
| 邮箱凭据、记事本、普通网址 | 用户数据 Worker 的 Secret 加密本人 D1，本机设备加密缓存；无需主密码 |
| 网站账号、密码、关联/独立 TOTP | 本机 Warden Type 2 加密，用户独立 Warden D1；不复制进普通网址记录 |
| 自动访问秘密 | 本机设备加密缓存 + 用户数据 Worker 的 AES-GCM 加密 D1 单例，官方不保存 |
| 邮件正文、附件 | 本机；用户可另外备份本人百度/WebDAV，不放 Cloudflare 邮件内容表 |
| Cloudflare OAuth | 仅本次本机部署短期使用，完成后清除；不是自动访问秘密 |

保留独立 MIT Warden 服务端与自行实现的兼容客户端，不引入 Bitwarden GPL 客户端，不是官方 Bitwarden，也未经独立安全审计。Warden 条目仍是密文，但用户数据 Worker 可读取用于解密它们的访问秘密，因此整个部署不具有独立主密码端到端保护。不得宣称零知识、云端无法解密或没有数据丢失风险。旧手动库转换后原主密码被加密保存用于自动访问，不再仅内存使用。

官方已有 AI API / 远程 MCP 凭据账号同步不变；常用网站、TOTP、记事本和邮箱凭据不加入该官方接口。没有脚本 API，USER_SCRIPT、offscreen 脚本、MAIN world、MCP 和 AI 均不得读取此库。

## 模块与协议

- `cloudflare-setup.mjs`：AUTHORIZE / PREPARE / DEPLOY / CONNECT。PREPARE 只读预检，不创建数据库/子域名；计算按账号作用域命名的精确 origins。DEPLOY 后端再次核对权限和账号，以 MCP→data→vault 顺序部署。三个子部署复用 OAuth，最后统一清除。缺少子域名时保留授权以待明确确认。
- `warden-deploy.mjs`：`resolveWardenIdentity` 先读已有用户邮箱，保持旧身份；新库用 scope@sellerfeeds.invalid 内部标识，不要求真实邮箱。既有 D1/JWT/加密 Secret 都保留。
- `views/cloudflare.mjs`：主要按钮动态变为授权、确认子域名、完成开通、完成连接或更新；浏览器 permission request 必须先于点击链中的异步 RPC。不再有二次连接按钮。
- `mcp-runtime.mjs`：显式设置连接调用 `activatePersonalMcpAfterSetup`，先资格/health，再复核账号/地址，启用原通道。
- `personal-organizer.mjs`：note/bookmark 设备加密、operationId、严格 revision CAS、1000条上限。网址只关联 Warden ID，不包含密码或 OTP。每10分钟同步；离线内容保留。
- 用户数据 Worker：新增 `vault_auto_access(id=1,payload_ciphertext)`，只允许 GET/PUT `/vault/access`，需 ACCESS_TOKEN + OWNER_SCOPE + 允许的插件来源。AES-GCM AAD 使用 scope:vault-auto-access。INSERT OR IGNORE 后读回比较，同值可重试，不同秘密409；加密密钥丢失不覆盖旧数据。更新仅增表，原邮箱、organizer、library 表不重设。
- `warden-store.mjs`：automatic-access 与 state 分开设备加密存储。`warden-sync.mjs` 的 `ensureAutomaticWarden` 在 serial queue 外部执行；先保留/读回秘密，再注册。注册不确定响应重试同一秘密，409后验证登录；不能为重试随机换钥匙。
- `enableAutomaticWarden`：原密码正确解锁、同步确认，再保留秘密并读回；失败不覆盖旧值。自动会话不做五分钟锁定。账号退出/切换失去内存会话，恢复前必须核对当前设备登录会话。
- `views/bookmarks.mjs`：统一网址/账号/验证器窗口、同站多个账号、二维码本机解析、复制账号/密码/验证码。关闭弹窗及账号变化清除明文；隐藏页面保留编辑草稿，遮住密码并暂停验证码。异步回填检查账号/窗口 generation。网址保存与账号保存是两套存储，不伪装成跨库原子事务；部分保存显示实际结果，保留已存账号供重试。
- `vault-autofill.mjs`：保持 HTTPS 精确 origin、顶层隔离、同源表单 action、URL/会话 lease复核、多账号选择。网站保存提示仍须插件来源窗口明确确认，未确认候选只内存两分钟；确认后增加普通网址记录，不开放秘密给宿主网页。自动填充/提交默认关闭。

`CF_SETUP_*`、`ORGANIZER_*` 与 `WARDEN_*` 的管理来源必须按 protocol+host+pathname 校验，拒绝 userScriptId；不能用 URL.origin 的 null 相等判断插件来源。密码提示只接受插件 popup，网站来源只接受顶层 HTTPS 隔离脚本。活动设备失效后不恢复自动访问。

## 旧数据与失败处理

- 原 AES-GCM 记事/验证器/登录信息仍只复制迁移、读回核对、保留原件；主密码/恢复密钥仅为历史读取。
- 原 Warden 手动库首次输入原主密码启用自动访问，不改身份、包裹密钥或原条目；错误密码/远端自动访问秘密冲突停止。
- 原 Warden 书签和登录账号可显式复制成普通网站，sourceId 防重复，实际远端副本读回确认；原登录账号/TOTP 不删除。
- 删除网站不删除账号；删除账号/验证器是独立的明确确认操作。多个账号共用网站时只变更用户选中的条目。
- 同步使用严格 CAS，不确定创建用 operationId 核对；冲突保留两份或采用云端须由用户选择。用户删除整个云账号、D1、ENCRYPTION_KEY/JWT Secret 仍可能失去访问，不能自动重建覆盖。

## 验收与交付

回归入口：`tests/warden-automatic.test.mjs`（注册不确定响应、无闲置锁、换设备密钥恢复、原库转换、错误密码/身份不覆盖）、`personal-data-cloud.test.mjs`（真实 SQLite 加密/鉴权/不可覆盖密钥）、`cloudflare-setup.test.mjs`（预检不修改、精确权限、默认全服务、部分失败、OAuth清理、显式MCP启用及到期）、`warden-vault.test.mjs`（格式、CAS、迁移、填充lease）、`personal-organizer.test.mjs` 与管理页回归。

本轮仅本地打包。真实用户 Cloudflare 更新、跨电脑恢复、实际网站填充仍须用户重载新版并验收；开发者 CLI 账号不能替用户账号部署。旧 Worker 不会随本地打包自动升级：在设置更新个人云以取得自动访问表/API。先保留原 D1/Secret，旧 Warden 库按提示验证一次原主密码。不得把虚构接口浏览器检查冒充真实账号验收。

1.9.64 本机验收：真实 Chromium + 虚构接口已检查新增网站同时保存账号/TOTP、网址仅持有账号 ID、关闭弹窗清空明文、同站两个账号切换、独立验证码显示，以及一次 OAuth + 一次合并的精确 Worker 权限申请（userActivation 为真）。这些是界面/协议虚构测试，不代表用户真实云库已更新或实际网站登录已验收。截图见 `output/playwright/websites-{cards,editor,cloudflare}-1.9.64.png`。


## 1.9.67 自动访问修复（2026-10-02）

账号和验证码编辑不要求用户设置或输入主密码。`WARDEN_AUTO_READY` 以及管理页 `WARDEN_SAVE` 在设备会话与来源校验后使用 `ensureAutomaticWarden({create:true})`；网页填充、脚本和定时访问仍不创建新库。仅 `initialized === false`（部署时已查询本人 D1）且持有 setupKey、没有原 profile 时允许预留随机访问秘密并注册；网关再查用户数，非空拒绝注册。未知状态返回 `WARDEN_SETUP_REQUIRED`，到设置完成开通；已初始化或存在 profile 却缺密钥，返回 `WARDEN_ACCESS_RECOVERY_REQUIRED`，保留原库。自动访问凭据认证失败同样显示恢复状态，不能换秘密重试或重设 D1。

编辑器不再显示“旧库首次转换需原主密码”的日常说明。恢复状态只表示缺少原访问材料，不能把所有连接失败解释为旧主密码问题；确有原加密库时，移除提示不等于已能解密，原加密密钥仍不可绕过。处理连接按钮打开统一 Cloudflare 设置，并不保证更新 Worker 能找回丢失的密钥。新增验证器直接显示种子／otpauth 和二维码，不再调用网站账号选择逻辑隐藏输入框。真实用户云端恢复／填充仍需实际账号验收。

本轮验证：995 项 Node 测试全部通过；源码检查通过。Chromium 使用虚构云连接及凭据验证新增验证码与网站账号保存、密钥输入可见、恢复／未开通失败保留草稿并停止写入、440px 窄屏布局。测试不代表用户真实旧库密钥已恢复，本轮未代云端部署。

## 1.9.68：编辑窗内完成一次旧库恢复

用户已选择保留旧库并使用原主密码恢复一次。本轮不创建另一数据库或改变云地址。`views/bookmarks.mjs` 收到 WARDEN_ACCESS_RECOVERY_REQUIRED 后直接展示恢复表单；按钮调用 WARDEN_AUTO_ENABLE，而非跳转设置。后台先核对管理页来源、设备会话及 UI ownerLicense 与当前账号，再验证原密码、syncWarden 核对并 confirmAutomatic。成功后继续原来的保存按钮流程，错误时清除恢复密码，保留账号／OTP 草稿。core 恢复等待已有自动准备结束并绑定原 scope，不能将旧账号密码请求转到新账号。

验证码、账号和笔记编辑在浏览器标签页切换时保留 DOM／内存草稿。隐藏只暂停验证码请求、隐藏当前验证码并遮住密码；返回同账号恢复刷新。没有 localStorage／IndexedDB 草稿备份；明确关闭、账号变化、退出或关闭页面仍清理。查看已保存条目的验证码定时器与异步响应须核对页面可见、编辑代数与账号。新库开通的连接检测按钮在原编辑窗调用 CF_SETUP_CONNECT 并保留草稿；确需首次部署仍须通过统一设置授权，不能用连接检查冒充部署。

本轮验证：995 项完整 Node 测试通过；加强原库转换测试后，77 项相关回归通过。使用实际构建页面在 Chromium 中，以虚构云接口验证错误密码停止写入且保留草稿、正确密码恢复后自动继续保存、关闭弹窗和账号退出清理敏感输入。浏览器自动化环境不产生正常标签页可见性切换，因此显式模拟 visibilitychange 验证隐藏／返回时的草稿保留与密码遮蔽；不能将此写成已安装插件的真实多标签页验收。截图为 output/playwright/authenticator-restore-1.9.68.png。清理函数修改 hidden 属性必须先比较现值，避免 modal-root MutationObserver 循环触发导致界面卡住。真实用户旧库恢复需重载后由用户输入原密码，本轮未代云端部署。


## 1.9.69 同步节奏覆盖

个人空间账号、验证码、网站、笔记和布局保存后不再立即同步，先保存本机，十分钟检查与手动同步才联网；同步 flight 不阻塞本机队列。已恢复的自动访问可从本机缓存解密条目，首次初始化／恢复仍保留原流程。邮箱凭据授权与实际收发继续原网络路径，邮箱内容不进用户 D1。个人数据 Worker 升 v6 支持单组件布局、邮箱组件与缓存图标，原 D1 和 Secret 保留，无数据库迁移。本机布局及记录变更必须等定时或手动确认后才显示已同步。
