fix(mobile): 恢复 SSO Canary 匿名 OTA 更新 - #3824
Conversation
Signed-off-by: guyong <guyong@xd.com>
|
| Filename | Overview |
|---|---|
| apps/mobile/src/update/manualUpdateCheck.ts | 删除通用 consent 检查后,自建匿名 OTA 可以放行,但非自建手动检查也失去了隐私闸门。 |
| apps/mobile/app/settings.tsx | 手动检查仍以 Updates.isEnabled 对所有 Expo Updates 包开放,并直接调用 Expo check/fetch API。 |
| apps/mobile/app.config.js | 自建原生更新配置新增共享 EAS-Client-ID requestHeaders,非自建 EAS 配置保持原有标识行为。 |
| apps/mobile/src/update/canaryChannelStore.ts | 所有自建通道统一覆盖共享 client ID,Canary/Beta 额外保留通道 header。 |
| apps/mobile/src/update/useStartupOtaGate.ts | 自建启动 OTA 不再等待 analytics consent,并在检查前配置共享 ID 和通道 header。 |
| apps/mobile/src/update/resumeUpdateCheck.ts | 回前台 OTA 移除 consent 检查,但其 hook 仍由自建构建条件约束。 |
| apps/mobile/src/update/otaRequestConfig.json | 新增原生配置与 JS 共用的 OTA header 名称和固定共享 UUID。 |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
U[用户手动检查更新] --> S{自建更新包?}
S -->|是| H[覆盖共享 EAS-Client-ID]
H --> O[请求自建 OTA manifest]
S -->|否| E[Updates.isEnabled]
E --> N[直接请求 u.expo.dev]
N --> I[携带原生单安装 EAS-Client-ID]
Comments Outside Diff (1)
-
apps/mobile/src/update/manualUpdateCheck.ts, line 62 (link)当未同意隐私政策的用户在启用了 Expo Updates 的非自建 EAS/TestFlight 包中手动检查更新时,这里不再检查 consent,并直接请求
u.expo.dev;由于共享EAS-Client-ID的原生与运行时 override 都只存在于自建分支,请求仍会发送 Expo 生成的单安装标识。How this was verified: 设置页在非自建包中以Updates.isEnabled直接调用 Expo 更新 API,而仓库中唯一的运行时 header override 和原生共享 header 均受 self-host 条件限制。Context Used: 使用和PR描述相同的语言进行评论 (source)
Prompt To Fix With AI
This is a comment left during a code review. Path: apps/mobile/src/update/manualUpdateCheck.ts Line: 62 Comment: **非自建更新泄露安装标识** 当未同意隐私政策的用户在启用了 Expo Updates 的非自建 EAS/TestFlight 包中手动检查更新时,这里不再检查 consent,并直接请求 `u.expo.dev`;由于共享 `EAS-Client-ID` 的原生与运行时 override 都只存在于自建分支,请求仍会发送 Expo 生成的单安装标识。**How this was verified:** 设置页在非自建包中以 `Updates.isEnabled` 直接调用 Expo 更新 API,而仓库中唯一的运行时 header override 和原生共享 header 均受 self-host 条件限制。 **Context Used:** 使用和PR描述相同的语言进行评论 ([source](https://app.greptile.com/review/custom-context?memory=instruction-0)) --- For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Prompt To Fix All With AI
### Issue 1
apps/mobile/src/update/manualUpdateCheck.ts:62
**非自建更新泄露安装标识**
当未同意隐私政策的用户在启用了 Expo Updates 的非自建 EAS/TestFlight 包中手动检查更新时,这里不再检查 consent,并直接请求 `u.expo.dev`;由于共享 `EAS-Client-ID` 的原生与运行时 override 都只存在于自建分支,请求仍会发送 Expo 生成的单安装标识。**How this was verified:** 设置页在非自建包中以 `Updates.isEnabled` 直接调用 Expo 更新 API,而仓库中唯一的运行时 header override 和原生共享 header 均受 self-host 条件限制。
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Reviews (1): Last reviewed commit: "fix(mobile): 恢复 SSO Canary 匿名 OTA 更新" | Re-trigger Greptile
|
这个 PR 改了 Mobile 原生 球不在作者这边。维护者请直接在 PR 上 Approve;若要改,请 Request Changes。讨论 issue:#3825 |
|
命中 UI 路径(apps/mobile/app.config.js / apps/mobile/app/settings.tsx / apps/mobile/src/update/canaryChannelStore.ts 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范 |
|
按新的交付约束撤销本方案:后续改为不修改 Mobile 原生配置与 runtime fingerprint 的实现,并从最新 需要保留的边界是:纯 OTA 代码无法自动触达已被 #3359 的 |
这次改了什么
摘要
#3359 为阻止用户同意隐私政策前发送单安装
EAS-Client-ID,把启动、回前台和手动 OTA 都绑定到了 analytics consent。企业 SSO 按既有产品约定不经过协议门、也不写 analytics consent,因此consent=false + Canary=true的用户会被永久挡在 OTA 之外。本 PR 将两件事解耦:
EAS-Client-ID,不再发送单设备标识;Canary/Beta 继续携带x-cindy-update-channel。acceptPrivacyConsent()。SSO + consent=false + Canary=true回归测试,并守护 SSO 不进入 TapDB opt-in 路径。Expo 会把下载更新时的 URL / requestHeaders 记录下来,并在下次启动时据此筛选 bundle。因此固定 ID 同时写入自建包原生
updates.requestHeaders,与 JS override 共用同一配置源,避免只改 JS 后出现已下载 bundle 的 header 不匹配。变更类型
fix缺陷修复feat新功能refactor/perf重构或性能优化docs/test/chore文档、测试或工程维护范围
UI 变化
不涉及:
settings.tsx仅删除更新检查的 consent 依赖注入,没有修改渲染、交互、样式或 UI 文案。怎么验证的
自动验证
手工验证
不涉及:未生成签名 APK/IPA,未进行双平台真机 OTA 流程。
未执行的验证
EAS-Client-ID,且两台设备取值一致。/latest安装新 APK/IPA 后进入新 runtime,并只接收新 runtime 的 OTA。风险
风险分类
影响与回滚
updates.requestHeaders必须与 JS override 保持一致,否则 Expo 可能因 requestHeaders 不匹配而不再选择已下载 bundle。该配置会形成新 runtime。consent=false的旧客户端不会主动检查 OTA,无法通过旧 runtime 的热更自救;必须先通过匿名/latest分发新版 APK/IPA,再向新 runtime 发布 OTA。/latest,最后只向新 runtime 发布 OTA。提交前检查
git commit -s,见 DCO)