From 25b794c1f3a9e267608c904728e49779d82432d1 Mon Sep 17 00:00:00 2001 From: kdletters Date: Sat, 20 Jun 2026 10:47:46 +0800 Subject: [PATCH] =?UTF-8?q?=E9=94=81=E5=AE=9A=E6=A1=8C=E9=9D=A2=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=E5=AE=BF=E4=B8=BB=E4=B8=8A=E4=B8=8B=E6=96=87=E6=B8=85?= =?UTF-8?q?=E6=B4=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 桌面入口 URL 单测覆盖旧宿主 query 被清理 桌面壳配置检查反查入口上下文清洗测试 共享决策日志补充桌面入口 query 边界 --- apps/desktop-shell/scripts/check-config.mjs | 1 + apps/desktop-shell/src-tauri/src/shell/url.rs | 20 +++++++++++++++++++ .../shared-memory/decision-log.md | 1 + 3 files changed, 22 insertions(+) diff --git a/apps/desktop-shell/scripts/check-config.mjs b/apps/desktop-shell/scripts/check-config.mjs index cc6388bef..38b85641b 100644 --- a/apps/desktop-shell/scripts/check-config.mjs +++ b/apps/desktop-shell/scripts/check-config.mjs @@ -2297,6 +2297,7 @@ const requiredRustHostSnippets = [ 'emit_desktop_image_drop_event(&drop_window, paths, drop_position)', 'app.notification().builder()', 'desktop_entry_url_with_host_context', + 'desktop_entry_url_removes_stale_host_context_before_appending_current_context', 'desktop_h5_url_with_host_context', 'desktop_h5_url_with_host_context(target_url)', 'desktop_h5_url_with_host_context(normalized_url)', diff --git a/apps/desktop-shell/src-tauri/src/shell/url.rs b/apps/desktop-shell/src-tauri/src/shell/url.rs index 27298b28c..c223323a3 100644 --- a/apps/desktop-shell/src-tauri/src/shell/url.rs +++ b/apps/desktop-shell/src-tauri/src/shell/url.rs @@ -243,4 +243,24 @@ mod tests { assert!(packaged_url.contains(&format!("hostCapabilities={}", capabilities().join(",")))); assert!(packaged_url.ends_with("#works")); } + + #[test] + fn desktop_entry_url_removes_stale_host_context_before_appending_current_context() { + let url = desktop_entry_url_with_host_context( + "index.html?clientRuntime=browser&hostShell=old_shell&hostCapabilities=old&work=PZ-1#works", + ); + let query = url.split_once('?').expect("context query").1; + + assert!(url.contains("work=PZ-1")); + assert!(url.contains("clientRuntime=native_app")); + assert!(url.contains("hostShell=tauri_desktop")); + assert!(url.contains(&format!("hostCapabilities={}", capabilities().join(",")))); + assert_eq!(query.matches("clientRuntime=").count(), 1); + assert_eq!(query.matches("hostShell=").count(), 1); + assert_eq!(query.matches("hostCapabilities=").count(), 1); + assert!(!url.contains("clientRuntime=browser")); + assert!(!url.contains("hostShell=old_shell")); + assert!(!url.contains("hostCapabilities=old")); + assert!(url.ends_with("#works")); + } } diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index cd5d2ca56..934706178 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -126,6 +126,7 @@ - 2026-06-18 桌面壳观测与渠道 SDK 边界:Tauri 桌面壳默认不接入崩溃上报、analytics、遥测日志、自动更新或渠道分发 SDK;Sentry、Datadog、PostHog、Segment、Amplitude、Bugsnag、OpenTelemetry、Tauri log / updater 等 Node / Cargo 依赖、`package-lock.json` / `Cargo.lock` 解析包和 Rust 初始化片段都会被配置检查拒绝。后续只有在真实端点、采集字段、用户授权、隐私披露、签名和发布流程确定后,才能按单项能力更新方案并接入。 - 2026-06-18 桌面壳 HostBridge 版本边界:Tauri release / dev 入口 URL 的 `hostVersion` 由 Rust `shell/url.rs` 从 Cargo package 版本统一补写;`host.getRuntime` 回包继续使用 `env!("CARGO_PKG_VERSION")`,配置检查会确认 `tauri.conf.json`、`apps/desktop-shell/package.json` 和 Cargo package 版本一致,并拒绝在 Tauri 配置里手写入口 query 版本。 - 2026-06-18 桌面壳运行时平台 query:Tauri 静态配置不再写入 `hostPlatform` 或其它宿主上下文 query;Rust `setup` 手动创建主窗口前必须把基础入口改写为当前 `macos` / `windows` / `linux` 平台和完整宿主上下文,保证 H5 首屏 query 与 `host.getRuntime` 回读的平台一致。第二实例参数、外部 deep link 或 H5 自报值不得覆盖该字段;桌面壳测试和配置检查会拒绝绕过该归一流程。 +- 2026-06-20 桌面入口 URL 宿主上下文清洗:`desktop_entry_url_with_host_context(...)` 对 dev URL 和打包入口补写宿主上下文前必须先移除旧 `clientRuntime`、`hostShell`、`hostCapabilities` 等宿主 query,再追加当前 Tauri 壳真实上下文;Rust 单测和桌面配置检查反查旧 query 不会在首屏入口中重复或覆盖当前壳身份。 - 2026-06-18 桌面壳顶层导航边界:Tauri 主 WebView 只允许打包资产 URL 和 `https://app.genarrative.world` 同源 H5 route 留在主窗口;外域 `http:` / `https:`、`mailto:`、`tel:` 导航与 `window.open` 请求交给系统 opener 后拒绝 WebView 留壳;`javascript:`、`file:` 等危险协议直接拒绝。该规则不进入 HostBridge capability,不开放 opener JS guest API,配置检查和 cargo test 覆盖导航策略。 - 2026-06-18 桌面壳默认下载边界:Tauri 主 WebView 的下载事件默认拒绝网页自动下载和 `` 落盘,桌面文件保存只能通过 `file.exportText`、`file.exportImage`、`file.exportAudio` 等已声明 HostBridge method 进入 Rust 侧系统保存对话框,并继续执行 MIME、大小、文件名清洗和用户确认。该规则不进入 HostBridge capability,配置检查和 cargo test 覆盖下载拒绝策略。 - 2026-06-18 桌面壳文件 bytes 校验:Tauri 图片 / 音频导入导出不得只信扩展名或 H5 声明 MIME;Rust 侧必须识别 PNG / JPEG / WebP、MP3 / MP4-M4A / WAV / OGG / WebM bytes 头部,要求导入文件扩展名对应 MIME 与真实 bytes 匹配,导出 payload 的 `mimeType` 与 `base64Data` 解码 bytes 匹配。不匹配返回 `invalid_request`,继续不暴露本机绝对路径或通用文件系统能力。配置检查和 cargo test 覆盖该边界。