fix(android): use login consent instead of native privacy prompt

This commit is contained in:
key
2026-07-29 09:59:41 +08:00
parent f322f2b21b
commit 7f3357c7a1
10 changed files with 181 additions and 131 deletions
+23 -9
View File
@@ -94,7 +94,11 @@ test('Android 启动阶段不主动索取设备信息或外部存储权限', asy
const android = manifest['app-plus']?.distribute?.android;
const modules = manifest['app-plus']?.modules;
assert.equal(manifest['app-plus']?.distribute?.splashscreen?.useOriginalMsgbox, true);
assert.equal(
manifest['app-plus']?.distribute?.splashscreen?.useOriginalMsgbox,
false,
'受控企业内测不展示 DCloud 原生隐私弹窗,协议同意统一放在登录页'
);
assert.equal(android?.permissionPhoneState?.request, 'none');
assert.equal(android?.permissionExternalStorage?.request, 'none');
assert.ok(Object.hasOwn(modules || {}, 'Camera'), '媒体功能仍需按用户操作动态申请相机权限');
@@ -133,7 +137,7 @@ test('正式法务地址必须使用不同的公网 HTTPS 页面', () => {
));
});
test('Android 隐私模板的首次与二次弹窗使用同一组最终链接', async () => {
test('Android 原生隐私配置明确关闭弹窗,法务地址仍须通过登录页构建校验', async () => {
const template = await readFile(new URL('../androidPrivacy.json.example', import.meta.url), 'utf8');
const rendered = renderAndroidPrivacy(
template,
@@ -143,13 +147,18 @@ test('Android 隐私模板的首次与二次弹窗使用同一组最终链接',
const privacy = JSON.parse(rendered);
assert.deepEqual(validateAndroidPrivacyDocument(privacy), {
termsUrl: 'https://legal.company.cn/bangdao/terms',
privacyUrl: 'https://legal.company.cn/bangdao/privacy'
prompt: 'none',
version: '20260729'
});
assert.doesNotMatch(rendered, /__TERMS_URL__|__PRIVACY_URL__/);
privacy.second.message = privacy.second.message.replace('/privacy', '/other-privacy');
assert.throws(() => validateAndroidPrivacyDocument(privacy), /must use the same legal links/);
assert.doesNotMatch(rendered, /服务协议|隐私政策|buttonAccept|buttonRefuse|second/);
assert.throws(
() => validateAndroidPrivacyDocument({ ...privacy, prompt: 'template' }),
/prompt=none/
);
assert.throws(
() => validateAndroidPrivacyDocument({ ...privacy, message: 'unexpected native prompt' }),
/must not contain message/
);
});
test('Android 隐私配置写入 uni-app CLI 输入目录并校验编译产物', async () => {
@@ -164,6 +173,7 @@ test('Android 隐私配置写入 uni-app CLI 输入目录并校验编译产物',
assert.match(configureScript, /resolve\(projectRoot, 'src', 'androidPrivacy\.json'\)/);
assert.match(verifier, /dist\/build\/app\/androidPrivacy\.json/);
assert.match(verifier, /compiledManifest\.plus\?\.distribute\?\.splashscreen\?\.useOriginalMsgbox !== false/);
});
test('App 登录页法务地址校验不依赖浏览器 URL 构造器', async () => {
@@ -187,6 +197,10 @@ test('APK 门禁区分自定义调试基座与内置业务资源的测试包', a
assert.match(verifier, /assets\\apps/);
assert.match(verifier, /bundled androidPrivacy\.json/);
assert.match(verifier, /DCloud custom base APK contains only the native debug runtime/);
assert.match(verifier, /prompt=none/);
assert.match(verifier, /Packaged login flow is missing the expected service agreement URL/);
assert.match(verifier, /Packaged login flow is missing the expected privacy policy URL/);
assert.match(verifier, /Packaged login flow is missing the unchecked-consent failure message/);
assert.match(verifier, /dist\\build\\app\\app-service\.js/);
assert.match(verifier, /dist\\build\\app-plus\\app-service\.js/);
assert.match(verifier, /fixed test SMS code/);
@@ -209,5 +223,5 @@ test('8 月 1 日 RC 脚本默认拒绝脏工作区且记录完整构建证据',
assert.match(script, /AllowDirtyRehearsal/);
assert.match(script, /RC build changed the previously clean worktree/);
assert.match(script, /releaseEligible = \$releaseEligible/);
assert.match(script, /APK metadata, legal links, signature, content match and sensitive-value scan/);
assert.match(script, /APK metadata, login legal links, no native privacy prompt, signature, content match and sensitive-value scan/);
});