diff --git a/apps/mobile-shell/scripts/check-config.mjs b/apps/mobile-shell/scripts/check-config.mjs index 4bca38ea6..47e8717b4 100644 --- a/apps/mobile-shell/scripts/check-config.mjs +++ b/apps/mobile-shell/scripts/check-config.mjs @@ -1503,6 +1503,7 @@ for (const snippet of [ 'SafeAreaView', 'MOBILE_SHELL_SAFE_AREA_EDGES', 'resolveMobileShellBaseWebUrl', + 'originWhitelist={[allowedWebOrigin]}', 'javaScriptCanOpenWindowsAutomatically={false}', 'mixedContentMode="never"', 'allowFileAccess={false}', @@ -1537,6 +1538,10 @@ if (!shellAppTestSource.includes('blocked WebView file downloads are logged for throw new Error('mobile shell tests must cover blocked WebView file download diagnostics'); } +if (!shellAppTestSource.includes('WebView origin whitelist is limited to the resolved H5 origin')) { + throw new Error('mobile shell tests must cover WebView origin whitelist boundaries'); +} + for (const snippet of [ "describe('mobile shell safe area'", "test('protects the WebView from every device edge'", diff --git a/apps/mobile-shell/src/shell/ShellApp.test.tsx b/apps/mobile-shell/src/shell/ShellApp.test.tsx index 5596908d4..5bf318e10 100644 --- a/apps/mobile-shell/src/shell/ShellApp.test.tsx +++ b/apps/mobile-shell/src/shell/ShellApp.test.tsx @@ -440,6 +440,19 @@ describe('ShellApp QR scanner HostBridge flow', () => { }); describe('ShellApp HostBridge event injection', () => { + test('WebView origin whitelist is limited to the resolved H5 origin', async () => { + const ShellApp = await importShellApp(); + render(); + + const webViewProps = shellHarness.webViewProps.current as { + originWhitelist?: string[]; + source?: { uri?: string }; + }; + const webViewUrl = webViewProps.source?.uri ?? 'https://app.genarrative.world/'; + + expect(webViewProps.originWhitelist).toEqual([new URL(webViewUrl).origin]); + }); + test('AppState changes inject app.lifecycle events into WebView', async () => { const ShellApp = await importShellApp(); render();