统一移动壳外链协议来源
让移动壳导航测试按共享 HostBridge 外链协议清单反查 增加移动壳配置门禁防止 WebView 外链协议在 shell 层重新硬编码 补充共享决策记录说明 WebView 外链协议必须复用共享归一化逻辑
This commit is contained in:
@@ -1265,7 +1265,9 @@ for (const snippet of [
|
||||
}
|
||||
|
||||
for (const snippet of [
|
||||
'normalizeHostBridgeExternalUrl',
|
||||
'resolveMobileShellWebViewUrl',
|
||||
'return normalizeHostBridgeExternalUrl(rawUrl)',
|
||||
'shouldOpenInMobileShellWebView(rawUrl, allowedOrigin)',
|
||||
'new URL(rawUrl, allowedOrigin).toString()',
|
||||
]) {
|
||||
@@ -1274,6 +1276,17 @@ for (const snippet of [
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
navigationSource.includes('javascript:') ||
|
||||
navigationSource.includes('mailto:') ||
|
||||
navigationSource.includes('tel:+') ||
|
||||
navigationSource.includes("protocol === '")
|
||||
) {
|
||||
throw new Error(
|
||||
'mobile shell WebView external protocol policy must use shared HostBridge normalizer',
|
||||
);
|
||||
}
|
||||
|
||||
if (shellAppSource.includes('127.0.0.1:3000')) {
|
||||
throw new Error(
|
||||
'mobile shell ShellApp must not hard-code localhost as the default H5 URL',
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { describe, expect, test } from 'vitest';
|
||||
|
||||
import { HOST_BRIDGE_EXTERNAL_URL_PROTOCOLS } from '../../../../packages/shared/src/contracts/hostBridge';
|
||||
import {
|
||||
resolveMobileShellExternalUrl,
|
||||
resolveMobileShellWebViewUrl,
|
||||
@@ -52,15 +53,16 @@ describe('shouldOpenInMobileShellWebView', () => {
|
||||
});
|
||||
|
||||
test('只有允许协议能交给系统外部应用打开', () => {
|
||||
expect(resolveMobileShellExternalUrl(' https://example.com/path ')).toBe(
|
||||
'https://example.com/path',
|
||||
);
|
||||
expect(resolveMobileShellExternalUrl('mailto:hi@example.com')).toBe(
|
||||
'mailto:hi@example.com',
|
||||
);
|
||||
expect(resolveMobileShellExternalUrl('tel:+12345678')).toBe(
|
||||
'tel:+12345678',
|
||||
);
|
||||
for (const protocol of HOST_BRIDGE_EXTERNAL_URL_PROTOCOLS) {
|
||||
const url =
|
||||
protocol === 'mailto:'
|
||||
? 'mailto:hi@example.com'
|
||||
: protocol === 'tel:'
|
||||
? 'tel:+12345678'
|
||||
: `${protocol}//example.com/path`;
|
||||
expect(resolveMobileShellExternalUrl(` ${url} `)).toBe(url);
|
||||
}
|
||||
|
||||
expect(resolveMobileShellExternalUrl('javascript:alert(1)')).toBeNull();
|
||||
expect(resolveMobileShellExternalUrl('file:///etc/passwd')).toBeNull();
|
||||
expect(resolveMobileShellExternalUrl('/relative/path')).toBeNull();
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
- 2026-06-18 外链接入:H5 新增 `openHostExternalUrl()` facade,`native_app` 下会把外链归一化为允许协议的绝对 URL 后请求 `app.openExternalUrl`;ICP备案号和 RPG 资产调试原图入口已优先走宿主系统浏览器,普通浏览器和小程序保留原 `<a>` 行为,宿主不可用或拒绝时回退浏览器外链。
|
||||
- 2026-06-18 外链协议白名单门禁:`packages/shared/src/contracts/hostBridge.ts` 的 `HOST_BRIDGE_EXTERNAL_URL_PROTOCOLS` 是 `app.openExternalUrl` 唯一协议来源,当前只允许 `http:`、`https:`、`mailto:`、`tel:`;Expo 直接复用共享归一化逻辑,Tauri Rust 侧必须用 URL parser 镜像同一清单,根级 `npm run check:native-shells` 会拒绝共享契约与桌面壳协议清单漂移。
|
||||
- 2026-06-18 移动壳 WebView 导航收紧:Expo WebView 自身拦截外域导航时复用 HostBridge 外链协议白名单,只把 `http:`、`https:`、`mailto:`、`tel:` 交给 `Linking.openURL`,`javascript:`、`file:`、相对异常路径等危险目标直接阻断,避免离开同源主站后仍保留完整 HostBridge。
|
||||
- 2026-06-19 移动壳 WebView 外链协议共源:`apps/mobile-shell/src/shell/navigation.ts` 的 WebView 外链离壳判断必须调用共享 `normalizeHostBridgeExternalUrl`,不得在 shell 层另写协议判断;`apps/mobile-shell/scripts/check-config.mjs` 会拒绝重新硬编码 `mailto:` / `tel:` / `javascript:` 等协议分支,`navigation.test.ts` 用 `HOST_BRIDGE_EXTERNAL_URL_PROTOCOLS` 反查当前允许协议。
|
||||
- 2026-06-19 移动壳系统分享 URL 边界:Expo `share.open` 调用 React Native 系统分享面板前,只允许把 `url`、`href`、`path`、`targetPath` 和 `work` 归一为 `https://app.genarrative.world` 同源公开 URL;外域、协议相对 URL、`javascript:` 等危险目标必须返回 `invalid_request`,且显式非法 payload 不得回退到之前缓存的 `share.setTarget` 目标。分享实现复用移动壳入口 URL 的生产主站 origin,配置检查会拒绝重新声明同值 origin 或移除协议相对 URL 拦截。
|
||||
- 2026-06-19 桌面壳系统分享 URL 边界:Tauri `share.open` 写入系统剪贴板前同样只允许把 `url`、`href`、`path`、`targetPath` 和 `work` 归一为 `https://app.genarrative.world` 同源公开 URL;外域、协议相对 URL、`javascript:` 等危险目标必须返回 `invalid_request`,且显式非法 payload 不得回退到之前缓存的 `share.setTarget` 目标。桌面壳配置检查会拒绝移除同源分享 URL 归一和协议相对 URL 拦截。
|
||||
- 2026-06-18 能力声明收紧:`packages/shared/src/contracts/hostBridge.ts` 提供 HostBridge method / capability 白名单,H5 的 `getHostRuntime()` 会解析并过滤 `hostCapabilities`;`openHostShare`、`writeHostClipboardText`、`requestHostHapticsImpact`、`setHostAppTitle`、`exportHostTextFile` 等 native 能力只在宿主声明对应 capability 后调用。发布分享弹窗只有声明 `share.open` 时才显示“系统分享”,避免旧壳或裁剪壳露出不可用入口。
|
||||
|
||||
Reference in New Issue
Block a user