diff --git a/apps/mobile-shell/app.json b/apps/mobile-shell/app.json index 3c49c05d..b9fe72ee 100644 --- a/apps/mobile-shell/app.json +++ b/apps/mobile-shell/app.json @@ -35,6 +35,12 @@ "bundleIdentifier": "world.genarrative.mobile", "buildNumber": "1", "supportsTablet": true, + "infoPlist": { + "ITSAppUsesNonExemptEncryption": false, + "NSAppTransportSecurity": { + "NSAllowsArbitraryLoads": false + } + }, "associatedDomains": [ "applinks:app.genarrative.world" ] @@ -42,6 +48,7 @@ "android": { "package": "world.genarrative.mobile", "versionCode": 1, + "usesCleartextTraffic": false, "adaptiveIcon": { "foregroundImage": "./assets/icon.png", "backgroundColor": "#fffdf9" diff --git a/apps/mobile-shell/scripts/check-config.mjs b/apps/mobile-shell/scripts/check-config.mjs index eebd4d29..6a51b57d 100644 --- a/apps/mobile-shell/scripts/check-config.mjs +++ b/apps/mobile-shell/scripts/check-config.mjs @@ -221,6 +221,16 @@ if (appConfig.ios?.buildNumber !== '1') { throw new Error('mobile shell iOS build number must start at 1'); } +if (appConfig.ios?.infoPlist?.ITSAppUsesNonExemptEncryption !== false) { + throw new Error('mobile shell iOS encryption export flag must be explicit'); +} + +if ( + appConfig.ios?.infoPlist?.NSAppTransportSecurity?.NSAllowsArbitraryLoads !== false +) { + throw new Error('mobile shell iOS ATS must not allow arbitrary network loads'); +} + if (appConfig.android?.package !== 'world.genarrative.mobile') { throw new Error('mobile shell Android package must be world.genarrative.mobile'); } @@ -229,6 +239,10 @@ if (appConfig.android?.versionCode !== 1) { throw new Error('mobile shell Android versionCode must start at 1'); } +if (appConfig.android?.usesCleartextTraffic !== false) { + throw new Error('mobile shell Android package must disable cleartext traffic'); +} + if ( appConfig.android?.adaptiveIcon?.foregroundImage !== './assets/icon.png' || appConfig.android?.adaptiveIcon?.backgroundColor !== brandBackgroundColor diff --git a/docs/project-memory/shared-memory/decision-log.md b/docs/project-memory/shared-memory/decision-log.md index ff08316d..70ad59c5 100644 --- a/docs/project-memory/shared-memory/decision-log.md +++ b/docs/project-memory/shared-memory/decision-log.md @@ -55,6 +55,7 @@ - 2026-06-18 壳生产代码禁用临时替身:Expo 与 Tauri 壳的生产源码和配置不得出现 mock / fake / placeholder / stub / TODO / FIXME 以及对应中文脚手架词;测试文件仍可使用 mock。两端壳配置检查会扫描生产入口、配置和壳实现,防止把临时替身、占位文案或伪实现带进可分发壳。 - 2026-06-18 移动壳启动页与 adaptive icon:Expo 移动壳启动页和 Android adaptive icon 复用现有真实品牌图标 `apps/mobile-shell/assets/icon.png`,背景色固定为 H5 壳根背景 `#fffdf9`。该 PNG 是 1024x1024 RGBA 透明前景品牌资产,不新增占位图;配置检查会校验图标尺寸、透明像素、splash 和 adaptive icon 指向,避免后续换成非品牌或占位素材。 - 2026-06-18 桌面壳 bundle 图标集:Tauri 桌面壳从现有真实品牌 PNG `apps/desktop-shell/src-tauri/icons/icon.png` 派生 `32x32.png`、`128x128.png`、`128x128@2x.png`、`icon.ico` 和 `icon.icns`,并在 `bundle.icon` 中同时声明这些平台图标。检查脚本会校验 PNG 尺寸、ICO 多尺寸头部、ICNS 容器长度和 bundle 图标列表,避免后续退回单图标或替换为非品牌 / 占位素材。 +- 2026-06-18 移动壳网络安全元数据:Expo 移动壳默认包配置显式禁用 Android 明文流量 `usesCleartextTraffic=false`,iOS ATS 禁用任意加载 `NSAllowsArbitraryLoads=false`,并设置 `ITSAppUsesNonExemptEncryption=false` 作为当前未接入自定义加密能力的出口合规声明;本地 Vite 联调只通过 development build 显式环境变量进入,不把任意明文流量开关带进默认包配置。 - 影响范围:`src/services/host-bridge/`、未来 `apps/mobile-shell/`、未来 `apps/desktop-shell/`、移动端支付 / 分享 / 深链 / 推送、桌面端系统能力、AI H5 sandbox 的 GameBridge 边界。 - 验证方式:普通浏览器、小程序、Expo 壳、Tauri 壳都能返回正确 `getHostRuntime()`;未支持能力能回退 H5;固定玩法在各宿主中读取同一作品数据和运行态 snapshot;AI sandbox 无法直接调用 HostBridge;Tauri release 不允许任意远端页面调用桌面命令。 - 关联文档:`docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md`、`docs/【前端架构】宿主壳能力统一协议-2026-06-17.md`。 diff --git a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md index 591ffd04..d0fdd907 100644 --- a/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md +++ b/docs/【前端架构】ExpoReactNative与Tauri宿主壳方案-2026-06-17.md @@ -313,6 +313,8 @@ GameBridge 禁止: 2026-06-18 追加:桌面壳 bundle 图标集从现有真实品牌 PNG `apps/desktop-shell/src-tauri/icons/icon.png` 派生,补齐 `32x32.png`、`128x128.png`、`128x128@2x.png`、`icon.ico` 和 `icon.icns`,Tauri `bundle.icon` 同时声明这些平台图标。没有引入外部素材或占位图;`apps/desktop-shell/scripts/check-config.mjs` 会校验 PNG 尺寸、ICO 多尺寸头部、ICNS 容器长度和 bundle 图标列表,避免后续退回单图标或替换为非品牌素材。 +2026-06-18 追加:移动壳生产包网络安全元数据显式收紧。Android `usesCleartextTraffic=false`,iOS `NSAppTransportSecurity.NSAllowsArbitraryLoads=false`,并设置 `ITSAppUsesNonExemptEncryption=false` 作为当前未接入自定义加密能力的出口合规声明;开发联调本机 Vite 仍通过显式 `EXPO_PUBLIC_GENARRATIVE_WEB_URL=http://127.0.0.1:3000/` 进入 development build,不把任意明文流量开关带进默认包配置。`apps/mobile-shell/scripts/check-config.mjs` 会校验这些网络安全字段。 + ### Phase 4:宿主能力扩展 - 移动端接入系统分享、推送、原生登录和渠道支付。