Retire ACP/Hermes/OpenCode surfaces and rename hermes_tools to mnote_agent_tools so Page AI stays on Pi Lab only. Add Chrome vault extension + extension token route, pre-release purge design, and soft-retire legacy smokes for the small-group production cut.
97 lines
5.1 KiB
Markdown
97 lines
5.1 KiB
Markdown
# MNote Vault · Chrome 扩展(MV3)
|
||
|
||
将外站登录/注册账号与浏览器 Cookie 保存到 MNote 密码箱。
|
||
|
||
设计稿:`design/12-vault/process/12-3-chrome-extension-vault-save-v1.md`
|
||
|
||
## 安装(unpacked)
|
||
|
||
1. 启动 mnote-web(默认 `http://127.0.0.1:3000`)。
|
||
2. Chrome → `chrome://extensions` → 开启「开发者模式」→「加载已解压的扩展程序」。
|
||
3. 选择本目录:`extensions/mnote-vault`。
|
||
4. 打开扩展 **Options**:
|
||
- baseUrl:本机 `http://127.0.0.1:3000`,或外网 frp 完整地址(如 `https://www.xxx.nyat.app:44938`,含端口)
|
||
- MNote 账号/密码 → **连接并登录**
|
||
- **首次外网连接会弹「允许访问该网站」**,必须点允许;否则 Chrome 报 `Failed to fetch`(不是隧道挂了)
|
||
- **rootUri 一般不用填**:登录后自动取该账号默认工作区
|
||
(`POST /api/local-folder/workspaces/default` → `…/users/<actor>/workspaces/my-space`)。
|
||
仅当要把密码箱写到别的 local_folder 时,在「高级」里覆盖。
|
||
5. 在登录页 **提交** 表单;跳转成功后页面右下角弹出确认层(可显示/隐藏密码核对)。
|
||
也可点工具栏「保存当前页账号」(优先使用 pending draft)。
|
||
6. **登录态(Cookie)依赖网站访问权限**:v0.2.3 起连接 Options / 点保存时会申请 `http://*/*` + `https://*/*`。
|
||
Chrome 提示「读取和更改所有网站的数据」时必须点允许,否则只能保存账号密码、无法写入 `sessions/`。
|
||
若仍提示「未捕获到 Cookie」:`chrome://extensions` → MNote Vault → 网站访问权限 → **所有网站**。
|
||
7. **去重(v0.2.3)**:同一站点 + 同一用户名 + 同一密码已保存后,再次登录**不再弹确认层**(仅必要时静默补写 Cookie)。
|
||
点「取消」会暂时不再询问;勾选「此网站不再询问」后该 origin 永久跳过自动提示(仍可用工具栏手动保存)。
|
||
|
||
## 保存流程(P0–P1)
|
||
|
||
对齐 KeePassXC / Bitwarden 思路,**不使用 `webRequest`**:
|
||
|
||
```text
|
||
content: form submit / 提交按钮
|
||
→ PENDING_SAVE(background 内存 + chrome.storage.session)
|
||
→ SPA 约 1.5s 仍在同 URL:直接弹确认层
|
||
→ 整页跳转:tabs.onUpdated status=complete
|
||
同站 hostname 匹配 → OPEN_SAVE_UI_WITH_DRAFT
|
||
用户确认
|
||
→ SAVE_CREDENTIAL(此时再 cookies.getAll)
|
||
→ P1:约 2.5s 后二次 PUT session(setTimeout + alarms 备份)
|
||
```
|
||
|
||
| 项 | 说明 |
|
||
|----|------|
|
||
| 主触发 | **submit / 提交按钮**,不是 password blur |
|
||
| 凭证跨导航 | background `pendingByTab`,TTL 约 3 分钟 |
|
||
| 弹窗时机 | **登录后页面**(或 SPA 同页 fallback) |
|
||
| Cookie | 确认保存时抓取;空则提示 + 自动二次捕获 |
|
||
| 密码核对 | 确认层密码框可「显示/隐藏」 |
|
||
| 鉴权 | `POST /api/auth` 后 `POST /api/vault/extension/token` → Bearer `mnext1.*` |
|
||
| 写账号 | `POST /api/vault/items` 或 `PATCH` 追加账号 |
|
||
| 写登录态 | `PUT /api/vault/items/{id}/session` → `sessions/{id}/{accountId}.json` |
|
||
|
||
### 消息类型(background)
|
||
|
||
| type | 作用 |
|
||
|------|------|
|
||
| `PENDING_SAVE` | content 提交时缓存 draft |
|
||
| `GET_PENDING` / `CLEAR_PENDING` / `MARK_PENDING_PROMPTED` | 查询 / 取消 / 防重复弹窗 |
|
||
| `PROMPT_PENDING` | 工具栏打开确认层(优先 pending) |
|
||
| `OPEN_SAVE_UI` / `OPEN_SAVE_UI_WITH_DRAFT` | background → content 展示 UI |
|
||
| `SAVE_CREDENTIAL` | 真正写 vault + session |
|
||
| `LIST_FOLDERS` | 拉取已有 `folderPath` 列表 + 上次选用分组(确认层下拉) |
|
||
| `UPDATE_SESSION` | 工具栏手动更新 Cookie |
|
||
|
||
### 分组(folderPath)
|
||
|
||
确认层提供:
|
||
|
||
- 下拉:已有分组(来自 vault list 的 `folderPath`,含父路径前缀)+「(无分组)」+「+ 新建分组…」
|
||
- 新建:自由填写名称,支持 `/` 分层(如 `工作/客户`)
|
||
- 默认选中:上次保存时选用的分组(`chrome.storage.local.lastFolderPath`)
|
||
- **不再**硬编码 `imported/browser`
|
||
|
||
## 自测建议
|
||
|
||
1. 普通表单登录(整页跳转)→ 登录后应出现确认层,密码可显示核对。
|
||
2. SPA 登录(URL 不变)→ 约 1.5s 后同页弹层。
|
||
3. 工具栏「保存当前页」:若刚提交过,应预填 pending 密码。
|
||
4. 取消确认层 → pending 清除,不再重复弹。
|
||
5. 保存后 cookie 为空时:提示二次捕获;稍后可用「更新登录态」。
|
||
|
||
```bash
|
||
# 后端 token + session 单测
|
||
cd rust && cargo test -p mnote-web --lib routes::vault_extension_token::tests
|
||
cd rust && cargo test -p mnote-web --lib routes::vault_store::tests::session_file_put_resolve_and_share_copy
|
||
|
||
# API smoke(需 3000 已起 + 测试账号)
|
||
node scripts/vault-extension-api-smoke.js
|
||
```
|
||
|
||
## 权限
|
||
|
||
- `storage` / `cookies` / `activeTab` / `scripting` / `tabs` / `alarms`
|
||
- **无** `webRequest` / `webNavigation`(P0–P1 用 `tabs.onUpdated` 足够)
|
||
- `optional_host_permissions`:Options 点击时申请 baseUrl;保存 Cookie 时申请目标站 origin
|
||
- 外网带非标端口时 origin 含端口,例如 `https://www.xxx.nyat.app:44938/*`
|