Harden auth/vault path sanitization and clean WeKnora docs

This commit is contained in:
Agent Board
2026-07-28 17:04:27 +08:00
parent 2deaf59f7b
commit 26ff1a9c9a
190 changed files with 13454 additions and 4987 deletions
+25 -16
View File
@@ -19,7 +19,7 @@ echo $!
sleep 8 && grep -E 'gateway 已启动|Running' /tmp/mnote-dev.log
```
**关键点:**
- 启动命令是 `npm run dev:hot`不是 desktop:hot
- 启动命令是 `npm run dev:hot`唯一热启动入口
- `dev:hot` 默认启用 `MNOTE_WEB_ALLOW_DEV_FIXTURES=1`
- 使用 cargo-watch 自动重编译
- 端口固定为 3000
@@ -35,8 +35,9 @@ paseo_browser_wait url=localhost:3000 timeoutMs=15000
# 3. 截图(如果返回 "tab not painted",等 3 秒重试)
paseo_browser_screenshot
# 4. 快速登录(snapshot 找到 @e5 即"测试账号快速登录"按钮)
paseo_browser_click ref=@e5
# 4. 标准登录(7-76:无「测试账号快速登录按钮)
# 在 snapshot 中定位账号/密码输入框与「登录」提交按钮后填表提交;
# 或脚本侧:require('./lib/browser-auth-login').loginViaAuthForm(page)
# 5. 等待进入工作区
paseo_browser_wait url=localhost:3000 text=工作区
@@ -45,10 +46,18 @@ paseo_browser_wait url=localhost:3000 text=工作区
paseo_browser_screenshot
```
### 4. 测试账号
- 邮箱:`mnote.e2e@example.com`
- 密码:`MnoteE2E123!`
- 用户名:`mnote-e2e`
### 4. 测试账号7-76 方案 Aadmin / user / AI 主体分离)
| 用途 | 用户名 | 邮箱 | 密码(本地/dev | control-plane `role` | admin 能力 |
|------|--------|------|------------------|----------------------|------------|
| **Ops admin** | `mnote-admin` | `mnote.admin@example.com` | `MnoteAdmin123!` | `admin` | 是(`/admin/*`、access-policy、代签) |
| **AI 主体** | `mnote-e2e` | `mnote.e2e@example.com` | `MnoteE2E123!` | `ai_service` | **否** |
| **个人用户示例** | `liaibo` | (本地) | (本地) | `user` | **否** |
- 登录方式:标准表单 / `POST /api/auth` / `scripts/lib/browser-auth-login.js`
- 产品/AI 主体:`loginViaAuthForm` / `loginViaAuthApi`(默认 e2e
- 管理面 seed`loginAsAdminViaAuthForm` / `withAdminBrowserSession`
- **不要**依赖快速登录按钮;**不要**把 `mnote-e2e` 放进 `MNOTE_ADMIN_USER_IDS``access-policy.admins`
### 5. 常见问题
| 问题 | 原因 | 解决 |
@@ -56,7 +65,6 @@ paseo_browser_screenshot
| ERR_CONNECTION_REFUSED | 服务器未启动 | 先运行 `npm run dev:hot` |
| tab not painted | 页面未渲染完成 | 等待 3 秒后重试截图 |
| Paseo 终端无输出 | 前台进程阻塞 | 用 `nohup ... &` 后台启动 |
| `desktop:hot` vs `dev:hot` | 启动命令不同 | 浏览器测试用 `dev:hot` |
### 6. AI 密码本读密 / 登录态(12-2 · **不依赖 3000**
@@ -97,7 +105,7 @@ cargo test -p mnote-web --lib routes::vault -- --nocapture 2>&1 | rg -n "login_r
- 2026-05-20 起,默认主入口固定按 `http://127.0.0.1:3000` 理解;历史记录里的 `3001` 只代表当时临时 mnote-web 实例,不再作为默认验收入口。
- 历史 smoke 分为 `current``retired/debug` 两类维护;退役脚本不应进入默认回归,除非脚本自身要求显式环境变量。
- 2026-05-27 起,默认 smoke 基线只覆盖 `3000 Rust SSR + leptos-tiptap + local-first` 主路径;Convex export、Convex 兼容、Next、3104、BlockNote 默认路径脚本不再放在默认候选里。
- 依赖 `/api/dev/seed` 的 browser smoke 默认使用 `npm run dev:hot``dev:hot` 默认启用 `MNOTE_WEB_ALLOW_DEV_FIXTURES=1``desktop:hot`生产启动仍默认关闭。修改 Node 启动脚本或环境变量后必须重启 `dev:hot` 主进程,不能只等待 cargo-watch 重载 Rust。
- 依赖 `/api/dev/seed` 的 browser smoke 默认使用 `npm run dev:hot``dev:hot` 默认启用 `MNOTE_WEB_ALLOW_DEV_FIXTURES=1`,生产启动仍默认关闭。修改 Node 启动脚本或环境变量后必须重启 `dev:hot` 主进程,不能只等待 cargo-watch 重载 Rust。
## 0. 当前 smoke 状态清单
@@ -124,7 +132,7 @@ node scripts/task490-runtime-surfaces-smoke.js
- Rust SSR 文档页 / Page Aggregatelocal-first 默认优先 `task167-local-markdown-title-body-options-no-convex-smoke.js`Page Aggregate browser conversion / compat fallback 改动补跑 `task522-page-aggregate-compat-fallback-contract.js`cloud/control-plane 文档可补跑 `task110-page-title-single-truth-smoke.js``task-page-aggregate-body-sync-smoke.js``task-page-aggregate-options-sync-smoke.js``task-page-aggregate-refresh-persistence-smoke.js`
- leptos-tiptap runtime surface`task490-runtime-surfaces-smoke.js`;需要验证保存回读可补跑 `task121-rust-web-editor-island-hydration-smoke.js`,但它仍使用 `/api/tree/commands create` 准备文档,不作为无 Convex 默认基线;需要验证浮层互斥和更多菜单状态时再跑 `task158-e30-menu-state-smoke.js`
- local-first 本地工作区:`task164-desktop-hot-local-folder-main-entry-smoke.js``task166-local-first-managed-workspace-no-convex-smoke.js``task167-local-markdown-title-body-options-no-convex-smoke.js``task436-local-markdown-open-document-external-change-smoke.js``task443-local-markdown-asset-upload-smoke.js``task451-local-markdown-conflict-resolution-ui-smoke.js``task452-local-search-index-browser-smoke.js``task453-local-folder-page-ai-changed-files-smoke.js`WorkspacePath / ObjectIdentity runtime 消费统一改动补跑 `task524-workspace-object-identity-matrix-smoke.js``task452` 只覆盖普通本地搜索、settings API、tag/backlink API 和旧 local-index UI 不复活;资料库问答、PDF/Office/image source ingestion 与引用回跳改跑 LightRAG / provider-neutral knowledge-rag 脚本。
- LightRAG / Knowledge RAG 资料库:LightRAG 是默认 provider。资料源、摄取、source scope 与 watcher 改动优先跑 `task532-knowledge-rag-docx-ingestion-smoke.js``task533-knowledge-rag-source-watcher-sync-smoke.js``task534-knowledge-rag-source-management-scope-smoke.js``task538-knowledge-rag-source-scope-api-smoke.js`;引用和 Page AI final answer 改动补跑 `task529-knowledge-rag-citation-resource-tab-smoke.js``task530-knowledge-rag-page-ai-final-answer-smoke.js`;真实 Pi + LightRAG 服务可用时补跑 `task-pi-lab-real-lightrag-smoke.js`WeKnora 仅是历史/备用 provider,不进入默认回归。旧 OpenHub 专项资料库 smoke 已软归档到 `recycle/20260712-pi-ts-openhub-retirement/`;旧 `task526-local-folder-ocr-api-smoke.js` / OCR sidecar 链路已退役并软归档;`/api/search/documents` 不作为 LightRAG、LiteParse、OCR sidecar 或 evidence.sqlite 的资料库问答 fallback。
- LightRAG / Knowledge RAG 资料库:LightRAG 是默认 provider。资料源、摄取、source scope 与 watcher 改动优先跑 `task532-knowledge-rag-docx-ingestion-smoke.js``task533-knowledge-rag-source-watcher-sync-smoke.js``task534-knowledge-rag-source-management-scope-smoke.js``task538-knowledge-rag-source-scope-api-smoke.js`;引用和 Page AI final answer 改动补跑 `task529-knowledge-rag-citation-resource-tab-smoke.js``task530-knowledge-rag-page-ai-final-answer-smoke.js`;真实 Pi + LightRAG 服务可用时补跑 `task-pi-lab-real-lightrag-smoke.js`。旧 OpenHub 专项资料库 smoke 已软归档到 `recycle/20260712-pi-ts-openhub-retirement/`;旧 `task526-local-folder-ocr-api-smoke.js` / OCR sidecar 链路已退役并软归档;`/api/search/documents` 不作为 LightRAG、LiteParse、OCR sidecar 或 evidence.sqlite 的资料库问答 fallback。
- local Markdown conflict regression`task510-local-markdown-conflict-regression-group.js` 串联真实冲突、连续上传、新建页面、外部恢复、多 tab CAS 与上传 409 孤儿策略;可用 `MNOTE_CONFLICT_REGRESSION_TASKS=a.js,b.js` 做定点子集。
- tree realtime / live cache`task446-tree-rename-dual-browser-live-smoke.js``task447-tree-move-order-dual-browser-live-smoke.js``task448-tree-resync-recovery-dual-browser-smoke.js``task449-tree-sse-reconnect-snapshot-recovery-smoke.js`
- 资源对象与 mindmap`task455-local-folder-mindmap-clean-smoke.js``task456-resource-object-shell-sync-smoke.js``task166-mindmap-phase6-block-smoke.js``task167-mindmap-kmind-parity-smoke.js``task168-mindmap-put-validator-smoke.js`Page AI mindmap skill / 资源生成改动补跑 `task503-mindmap-skill-capability-smoke.js`,真实 mindmap resource tab / Page AI target 改动补跑 `task525-page-ai-mindmap-resource-target-smoke.js`
@@ -139,7 +147,7 @@ node scripts/task490-runtime-surfaces-smoke.js
- 旧 Convex 兼容 smoke 已软删除到 `recycle/20260527-legacy-cleanup/convex/scripts/`,包括 `task163``task174``task175``task427``task428``task429``task430``task431``task432``task433``task434`
- `task179-tree-create-delete-no-reload-smoke.js`:覆盖 `/tree` debug shell。`/tree` 已是显式 debug/internal 边界,脚本默认阻断;只有设置 `MNOTE_ALLOW_DEBUG_TREE_SMOKE=1` 时才可执行。
- `task123-rust-web-tree-live-stream-consumer-smoke.js`:只证明 `/api/tree/events` SSE fallback 仍可用。当前 realtime 主链是 WebSocket push + SSE fallback;验证主链时优先使用 446 / 447 / 448,只有排查 fallback 时再跑 123。
- WeKnora 默认 provider 脚本(`task544``task769``task772``task777``task781``task783``task784``task785``task787``task788``task789``task790``task79x`)已退役;它们与 LightRAG 默认 provider 主线相反
- 历史非 LightRAG 默认 provider 脚本(`task544``task769``task772``task777``task781``task783``task784``task785``task787``task788``task789``task790``task79x`)已退役并软归档到 `recycle/scripts/` 下对应归档目录(及历史 recycle);不进入 LightRAG 默认回归
- Hermes/ACP/Reasonix 页面 AI 主流程 smoke 已退役;只保留 `task-hermes-page-ai-retirement-guard.js` 防止旧 runtime 复活。`task762-page-ai-board-first-smoke.js` 也已退役。
-`task019``task021``task022` 这类早期 UI regression 脚本已软删除到 `recycle/scripts/retired-ui-regressions/`,只作为历史对照;后续默认不要用于当前 Rust SSR / local-first 主路径验收。
- `task494-filetree-lazy-loading-dedup-smoke.js``task498-starred-page-tree-scope-and-local-edit-smoke.js``task499-sidebar-tree-view-state-smoke.js`2026-07-21 诊断为 fixture/契约过时(非 Playwright 安装问题),已迁到 `recycle/scripts/obsolete-tree-smokes-20260721/`。全局 Playwright 栈:`~/.agent-infra/playwright-stack`(见该目录 `use-in-project.md`)。树移动排序优先 `task447-tree-move-order-dual-browser-live-smoke.js` 或 Hermes tree QA。
@@ -236,8 +244,9 @@ node scripts/task490-runtime-surfaces-smoke.js
- 默认测试账号:
- 邮箱:`mnote.e2e@example.com`
- 密码:`MnoteE2E123!`
- 快捷按钮:`测试账号快速登录`
- 通过 API 或 UI 兜底完成认证
- UI:标准登录表单(`#account` + `#password` + `[data-auth-submit]`
- 共享 helper`scripts/lib/browser-auth-login.js``tree-shell-smoke-helpers.js`
- 通过 API 或 UI 兜底完成认证(7-76 P0 起无快速登录按钮)
- 为 smoke 自动创建、重命名、清理临时页面
后续新脚本优先复用这些 helper,不要在每个任务里再复制一套登录和清理逻辑。
@@ -246,7 +255,7 @@ node scripts/task490-runtime-surfaces-smoke.js
- 需要 `setupWorkspaceAccess``seedAiPolicy``seedAiRuntime` 等测试数据准备能力时,先确认服务由 `npm run dev:hot` 启动。
- `npm run dev:hot` 默认开启 dev fixtures;可用 `MNOTE_WEB_ALLOW_DEV_FIXTURES=0 npm run dev:hot` 显式关闭。
- `npm run desktop:hot` 保持生产近似的安全默认,不自动开放 `/api/dev/seed`;确需复用时显式执行 `MNOTE_WEB_ALLOW_DEV_FIXTURES=1 npm run desktop:hot`
- 生产启动不自动开放 `/api/dev/seed`;本地仅 `dev:hot` 默认开启 fixtures
- smoke 遇到 `dev_seed_disabled` 时不得标记为“功能未验证后跳过”;应先按上述契约重启服务,再重新执行完整 smoke。
## 2. 当前推荐测试顺序
@@ -411,7 +420,7 @@ node scripts/task097-homepage-entry-smoke.js
推荐:
- `开启宽版后 htmlWide 应为 true,实际 false`
- `测试账号登录后仍停留在 /auth`
- `标准登录后仍停留在 /auth`
- `本地首屏未捕获工作区特征`
不推荐:
@@ -524,7 +533,7 @@ const controlPlaneEnv = buildControlPlaneTestEnv(dataRoot, process.env);
### 7.3 例外
- `scripts/lib/control-plane-dev-seed.js``scripts/lib/control-plane-test-env.js` 本身是批准 helper。
- `scripts/desktop-hot.js``scripts/dev-hot.js``scripts/prod-build-start.js` 作为启动基础设施,设置环境变量路径是必要的。
- `scripts/mnote-web-hot.js``scripts/dev-hot.js``scripts/prod-build-start.js` 作为启动基础设施,设置环境变量路径是必要的。
- `rust/crates/` 下的 Rust 代码通过 `ControlPlaneStore` trait 访问数据库是正常路径。
- `scripts/task-control-plane-admin-libsql-roundtrip-smoke.js` 使用 `cargo run --bin control-plane-admin`,走 Rust admin CLI。
- `sqlite` fallback、admin CLI、legacy evidence/local_search 不在脚本纪律约束范围内。