收紧原生壳桥接权限边界
移动壳 HostBridge 协议名和版本改为共享契约常量 移动壳配置检查锁定主动导航和 deep link 宿主上下文补写 桌面壳主窗口 capability 移除 Tauri core 默认权限 桌面壳配置检查拒绝 core 默认权限和插件权限外露 更新原生壳方案与共享决策记录
This commit is contained in:
@@ -51,6 +51,8 @@
|
||||
- 2026-06-18 移动壳键盘布局:Expo Android 壳 `softwareKeyboardLayoutMode` 固定为 `resize`,让系统键盘打开时真实调整 WebView 可视高度;H5 继续使用已有 viewport / 输入法聚焦适配承接创作表单、聊天输入和玩法输入框,壳层不新增键盘遮挡补偿 UI、不伪造键盘状态。移动壳配置检查和 Expo public config smoke 会拒绝该字段缺失或漂移。
|
||||
- 2026-06-18 移动壳媒体策略:Expo WebView 允许内联媒体播放和用户触发的全屏视频,但保留 `mediaPlaybackRequiresUserAction`,不允许无手势自动播放;固定玩法和 AI H5 sandbox 的音频仍由 H5 用户开关、运行态状态和宿主生命周期控制,壳层不注入额外播放器或假播放状态。移动壳配置检查会拒绝 WebView 媒体策略漂移。
|
||||
- 2026-06-18 移动壳启动 URL 归一:Expo 壳的 `EXPO_PUBLIC_GENARRATIVE_WEB_URL` 和 deep link 基准地址只接受生产主站 `https://app.genarrative.world`,以及本机开发联调 `http://127.0.0.1`、`http://localhost`、`http://[::1]`;空值、相对路径、外域、`file:`、`javascript:` 等非法配置回退到默认 H5 地址后再附加 `native_app` 宿主上下文;deep link 仍只映射归一后基准 origin 的 H5 路径,禁止把外域或危险协议页面装进带完整 HostBridge 的 WebView。
|
||||
- 2026-06-18 移动壳主动导航上下文:Expo 壳的 `navigation.openNativePage` 与 deep link 都必须复用 `buildMobileShellUrl(...)` 补写 `native_app`、`expo_mobile`、真实平台、版本和 capability 清单;受控导航只接受当前允许 origin 的同源 H5 URL。移动壳配置检查会拒绝主动导航或 deep link 绕过该宿主上下文构造入口。
|
||||
- 2026-06-18 移动壳协议常量来源:Expo 壳的 HostBridge 事件注入、入口 URL `bridgeVersion`、`host.getRuntime` 回包和 Expo public config smoke 必须使用 `packages/shared/src/contracts/hostBridge.ts` 的 `HOST_BRIDGE_PROTOCOL` / `HOST_BRIDGE_VERSION`,不得在壳层重新写死协议名或版本字面量;配置检查会拒绝这些常量漂移。
|
||||
- 2026-06-18 移动壳默认入口:Expo 壳默认 H5 地址固定为 `https://app.genarrative.world/`,开发联调本机 Vite 必须显式设置 `EXPO_PUBLIC_GENARRATIVE_WEB_URL=http://127.0.0.1:3000/`、`http://localhost:3000/` 或 `http://[::1]:3000/`;生产包不得在未配置环境变量时加载设备本机 localhost,也不得通过环境变量把第三方外域 H5 放入带完整 HostBridge 的 WebView。
|
||||
- 2026-06-18 移动壳安装包身份:Expo 移动壳的 iOS bundle identifier 与 Android package 统一固定为 `world.genarrative.mobile`,应用版本固定为 `0.1.0`,iOS `buildNumber` 从字符串 `"1"` 起步,Android `versionCode` 从整数 `1` 起步;后续分发安装包时递增构建号 / versionCode,产品版本号按发布节奏调整。移动壳配置检查会校验 `app.json` 与 `package.json` 版本一致,并拒绝缺失或漂移的包标识,当前不写入假商店元数据、假更新端点或占位渠道 SDK 配置。
|
||||
- 2026-06-18 移动壳 HostBridge 版本单一来源:Expo 移动壳的 H5 入口 query 和 `host.getRuntime` 回包都读取 `MOBILE_SHELL_HOST_VERSION`,该常量必须与 `app.json` / `package.json` 版本一致;配置检查会拒绝 `App.tsx` 或 `bridge.ts` 重新散落硬编码版本,避免安装包版本升级时 H5 首屏上下文与 runtime 回读分叉。
|
||||
@@ -77,6 +79,7 @@
|
||||
- 2026-06-18 移动壳文件 bytes 校验:Expo 图片 / 音频导入导出不得只信系统 picker 返回 MIME、文件扩展名或 H5 声明 MIME;移动壳必须识别 PNG / JPEG / WebP、MP3 / MP4-M4A / WAV / OGG / WebM base64 bytes 头部,要求导入 MIME 归一结果与真实 bytes 匹配,导出 payload 的 `mimeType` 与 `base64Data` 解码 bytes 匹配。不匹配返回 `invalid_request`,不会写入缓存文件、调起系统分享或把内容回传给 H5。移动图片导出还必须按 MIME 给系统分享 / 保存面板补齐 `.png` / `.jpg` / `.webp` 文件名扩展,避免缓存文件名与真实图片类型漂移。配置检查和移动壳测试覆盖该边界。
|
||||
- 2026-06-18 桌面壳 DevTools 边界:Tauri 主 WebView 配置必须显式 `devtools=false`,Cargo 依赖不得启用 Tauri `devtools` feature;桌面壳本地调试走普通浏览器和 Vite,不把 debug / release 桌面包变成可打开浏览器检查器的调试容器。配置检查会拒绝主窗口 DevTools 或 release feature 被重新打开。
|
||||
- 2026-06-18 桌面壳 Tauri 命令白名单:桌面壳源码、Tauri build manifest、主窗口 capability 和本地自动生成权限目录都只能暴露 `host_bridge_request` 一个受控 command;所有桌面能力继续在 Rust 内部按 HostBridge method 白名单分发,不新增可被 H5 直接 `invoke` 的 Tauri command,也不授予插件 JS guest API。检查脚本会拒绝多余 command、权限列表顺序漂移和残留的自动生成权限文件。
|
||||
- 2026-06-18 桌面壳 capability 最小化:Tauri 主窗口 capability 只授予 `allow-host-bridge-request`,不得授予 `core:default`、`core:*:default`、任意 core 子权限或 dialog / fs / notification / opener / clipboard / deep-link / window-state 等插件权限。窗口、菜单、托盘、剪贴板、文件、通知和外链能力只能由 Rust 壳内部调用,再经 `host_bridge_request` 分发。
|
||||
- 2026-06-18 HostBridge request id replay:Expo 和 Tauri 壳都必须按 request id 回放首次完成结果;同 id 进行中的请求共享同一执行结果,已完成请求直接回放缓存响应,避免系统分享、外链、剪贴板、文件选择 / 保存、本地通知、窗口导航等宿主副作用被重复触发。两端配置检查和测试会锁住 replay 结构。
|
||||
- 2026-06-18 HostBridge request envelope 校验:共享契约提供 `isHostBridgeMethod` 与 `normalizeHostBridgeRequestId`,Expo 壳直接复用,Tauri 壳镜像同一白名单和 id 规则;空 id、控制字符 id、超长 id 和未知 method 都必须在 replay / 能力分发前返回 `invalid_request`,已知但当前壳未实现的登录 / 支付等 method 才返回 `unsupported_method`。
|
||||
- 2026-06-18 HostBridge method 白名单跨壳门禁:`packages/shared/src/contracts/hostBridge.ts` 的 `HOST_BRIDGE_METHODS` 是唯一协议来源;Expo 壳 HostBridge 分发不得处理共享契约外 method,Tauri 壳 Rust `HOST_BRIDGE_METHODS` 必须与共享契约逐项一致。新增宿主 method 必须先更新共享契约,再落两端壳实现或明确 unsupported。
|
||||
|
||||
@@ -182,6 +182,7 @@ Tauri 壳同样只负责桌面宿主能力,不承接玩法业务。
|
||||
- H5 通过 `window.__TAURI__.core.invoke('host_bridge_request', request)` 或后续封装的 `nativeAppHostBridge` 调用桌面能力。
|
||||
- Rust 侧只暴露一个受控 `host_bridge_request` command,再在 Rust 内部按 method 白名单分发。
|
||||
- Tauri capabilities 只授予主窗口所需命令;默认不开放文件系统、shell、全局剪贴板或任意插件能力。
|
||||
- 主窗口 capability 只授予 `allow-host-bridge-request`;不得使用 `core:default`、`core:*:default` 或插件 command 权限作为兜底。窗口、菜单、托盘、剪贴板、文件、通知和外链能力只能由 Rust 壳内部调用,再通过 `host_bridge_request` 的 HostBridge method 白名单分发给 H5。
|
||||
- 桌面支付首期走现有 H5 / 二维码 / 外部浏览器路径,不在 Rust 侧保存支付凭据。
|
||||
- 文件导出、作品卡保存、图片拖拽导入、应用菜单、系统托盘、自动更新等桌面能力按后续需求逐项开放;其中应用菜单和系统托盘属于桌面壳自有能力,不作为 HostBridge method 暴露给 H5。
|
||||
- 主 WebView 默认拒绝网页自动下载或 `<a download>` 触发的落盘动作;用户保存文本、图片、音频等内容必须走已声明的 `file.exportText`、`file.exportImage`、`file.exportAudio` HostBridge method,由 Rust 侧执行 MIME、大小、文件名清洗和系统保存对话框确认。
|
||||
@@ -319,6 +320,10 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:移动壳启动 H5 URL 增加宿主侧归一。`EXPO_PUBLIC_GENARRATIVE_WEB_URL` 和 deep link 基准地址只接受生产主站 `https://app.genarrative.world`,以及本机开发联调的 `http://127.0.0.1`、`http://localhost`、`http://[::1]` 入口;空值、相对路径、外域、`file:`、`javascript:` 等非法配置统一回退到默认 H5 地址,再附加 `native_app` 宿主上下文。deep link 仍只允许映射到归一后基准 origin 的 H5 路径,避免外域页面被装进带完整 HostBridge 的 WebView。
|
||||
|
||||
2026-06-18 追加:移动壳 `navigation.openNativePage` 与 deep link 共享同一宿主上下文补写口径。受控主动导航先解析为当前允许 origin 的同源 H5 URL,再通过 `buildMobileShellUrl(...)` 重新附加 `clientRuntime=native_app`、`hostShell=expo_mobile`、当前平台、版本和真实 capability 清单;deep link 同样在同源路径归一后复用该构造函数。`apps/mobile-shell/scripts/check-config.mjs` 会拒绝主动导航或 deep link 绕过宿主上下文构造入口,避免新页面按普通浏览器运行态启动。
|
||||
|
||||
2026-06-18 追加:移动壳 HostBridge 协议名和协议版本统一从 `packages/shared/src/contracts/hostBridge.ts` 的 `HOST_BRIDGE_PROTOCOL` / `HOST_BRIDGE_VERSION` 读取。Expo 入口 query、WebView 事件注入、`host.getRuntime` 回包和 Expo public config smoke 都必须反查共享常量;移动壳配置检查会拒绝重新写死 `GenarrativeHostBridge` 或字面量版本。
|
||||
|
||||
2026-06-18 追加:移动壳默认 H5 地址固定为 `https://app.genarrative.world/`。开发联调如需加载本机 Vite,必须显式设置 `EXPO_PUBLIC_GENARRATIVE_WEB_URL=http://127.0.0.1:3000/`、`http://localhost:3000/` 或 `http://[::1]:3000/`;生产包不得在未配置环境变量时默认加载设备本机 localhost,也不得通过环境变量把第三方外域 H5 放入带完整 HostBridge 的 WebView。
|
||||
|
||||
2026-06-18 追加:移动壳系统深链声明固定为生产主站唯一入口。iOS `associatedDomains` 只能包含 `applinks:app.genarrative.world`;Android `intentFilters` 只能存在一个 `VIEW` / `autoVerify=true` 的 App Link 过滤器,category 只能是 `BROWSABLE` 和 `DEFAULT`,data 只能绑定 `https://app.genarrative.world`,不得额外声明外域、明文协议、pathPattern 或其它可接管范围。实际 deep link 解析仍由壳层把同源路径归一后附加 HostBridge 上下文,非法来源回退默认首页。
|
||||
@@ -348,6 +353,8 @@ GameBridge 禁止:
|
||||
|
||||
2026-06-18 追加:桌面壳当前真实能力完整清单为 `host.getRuntime`、`appearance.getColorScheme`、`host.events`、`app.lifecycle`、`share.open`、`share.setTarget`、`navigation.openNativePage`、`navigation.canGoBack`、`app.reloadWebView`、`app.openExternalUrl`、`app.setTitle`、`app.setBadgeCount`、`network.status`、`network.statusChanged`、`clipboard.writeText`、`clipboard.readText`、`file.exportText`、`file.importText`、`file.exportImage`、`file.importImage`、`file.importAudio`、`file.exportAudio`、`file.imageDropped` 和 `notification.showLocal`。`npm run check:native-shells` 会从 Rust capability 清单反查本段,避免实现、入口 URL 和方案文档再次漂移。
|
||||
|
||||
2026-06-18 追加:桌面壳主窗口 capability 最小化为 `allow-host-bridge-request`。Tauri `core:default` 会同时包含 event、window、webview、menu、tray 等默认命令集合,其中 webview 默认集包含 DevTools 内部切换命令;当前壳不再授予这些 core / plugin JS 权限。`apps/desktop-shell/scripts/check-config.mjs` 会拒绝 `core:default`、`core:*:default`、任意 core 子权限和 dialog / fs / notification / opener / clipboard / deep-link / window-state 等插件权限进入主窗口 capability。
|
||||
|
||||
2026-06-18 追加:桌面壳的网络状态同样只通过 HostBridge 暴露给 H5。H5 外部生成队列概览在桌面壳明确离线或不可达时暂停轮询,窗口恢复在线后重新刷新;Tauri 仍不开放任意网络探测、shell 或文件系统能力给主站。
|
||||
|
||||
2026-06-18 追加:桌面壳声明并实现 `file.importText`,通过系统文件选择框读取用户选择的文本文件,只接受 `text/plain`、`text/markdown`、`text/csv`、`application/json` 对应扩展名,单次不超过 5 MiB;成功只返回清洗后的文件名、MIME、UTF-8 文本内容和字节数,不暴露本机绝对路径,也不开放通用文件系统。H5 创作 Agent 工作台复用同一 HostBridge 文本导入入口和后端解析接口;普通浏览器、小程序和未声明该能力的裁剪壳继续保留原 `<input type="file">` 路径。
|
||||
|
||||
Reference in New Issue
Block a user