fix(android): share public legal URLs with cloud builds
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
VITE_APP_TERMS_URL=https://peilian.njzhmj.top/legal/terms.html
|
||||||
|
VITE_APP_PRIVACY_URL=https://peilian.njzhmj.top/legal/privacy.html
|
||||||
Generated
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "aihr-mobile-uni",
|
"name": "aihr-mobile-uni",
|
||||||
"version": "0.1.11",
|
"version": "0.1.12",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "aihr-mobile-uni",
|
"name": "aihr-mobile-uni",
|
||||||
"version": "0.1.11",
|
"version": "0.1.12",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dcloudio/uni-app": "3.0.0-alpha-5020220260725001",
|
"@dcloudio/uni-app": "3.0.0-alpha-5020220260725001",
|
||||||
"@dcloudio/uni-app-plus": "3.0.0-alpha-5020220260725001",
|
"@dcloudio/uni-app-plus": "3.0.0-alpha-5020220260725001",
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"$schema": "https://json.schemastore.org/package",
|
"$schema": "https://json.schemastore.org/package",
|
||||||
"name": "aihr-mobile-uni",
|
"name": "aihr-mobile-uni",
|
||||||
"version": "0.1.11",
|
"version": "0.1.12",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { readFileSync, writeFileSync } from 'node:fs';
|
import { readFileSync, writeFileSync } from 'node:fs';
|
||||||
import { resolve } from 'node:path';
|
import { resolve } from 'node:path';
|
||||||
|
import { loadEnv } from 'vite';
|
||||||
import { renderAndroidPrivacy } from './app-legal-config.mjs';
|
import { renderAndroidPrivacy } from './app-legal-config.mjs';
|
||||||
|
|
||||||
const projectRoot = resolve(import.meta.dirname, '..');
|
const projectRoot = resolve(import.meta.dirname, '..');
|
||||||
@@ -13,8 +14,13 @@ const argumentValue = (name) => {
|
|||||||
return process.argv.find((argument) => argument.startsWith(prefix))?.slice(prefix.length);
|
return process.argv.find((argument) => argument.startsWith(prefix))?.slice(prefix.length);
|
||||||
};
|
};
|
||||||
|
|
||||||
const termsUrl = argumentValue('terms-url') || process.env.VITE_APP_TERMS_URL;
|
const publicBuildEnv = loadEnv(process.env.NODE_ENV || 'production', projectRoot, 'VITE_');
|
||||||
const privacyUrl = argumentValue('privacy-url') || process.env.VITE_APP_PRIVACY_URL;
|
const termsUrl = argumentValue('terms-url')
|
||||||
|
|| process.env.VITE_APP_TERMS_URL
|
||||||
|
|| publicBuildEnv.VITE_APP_TERMS_URL;
|
||||||
|
const privacyUrl = argumentValue('privacy-url')
|
||||||
|
|| process.env.VITE_APP_PRIVACY_URL
|
||||||
|
|| publicBuildEnv.VITE_APP_PRIVACY_URL;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rendered = renderAndroidPrivacy(
|
const rendered = renderAndroidPrivacy(
|
||||||
|
|||||||
@@ -13,11 +13,38 @@ $ErrorActionPreference = 'Stop'
|
|||||||
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
|
$scriptDirectory = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||||
$projectRoot = Split-Path -Parent $scriptDirectory
|
$projectRoot = Split-Path -Parent $scriptDirectory
|
||||||
|
|
||||||
|
function Get-ProjectEnvValue {
|
||||||
|
param([string]$Name)
|
||||||
|
|
||||||
|
$publicEnvPath = Join-Path $projectRoot '.env'
|
||||||
|
if (-not (Test-Path -LiteralPath $publicEnvPath -PathType Leaf)) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
$prefix = "$Name="
|
||||||
|
foreach ($line in Get-Content -LiteralPath $publicEnvPath) {
|
||||||
|
$trimmed = $line.Trim()
|
||||||
|
if ($trimmed.StartsWith($prefix, [StringComparison]::Ordinal)) {
|
||||||
|
return $trimmed.Substring($prefix.Length).Trim().Trim('"').Trim("'")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($ExpectedTermsUrl)) {
|
if ([string]::IsNullOrWhiteSpace($ExpectedTermsUrl)) {
|
||||||
$ExpectedTermsUrl = $env:VITE_APP_TERMS_URL
|
$ExpectedTermsUrl = if (-not [string]::IsNullOrWhiteSpace($env:VITE_APP_TERMS_URL)) {
|
||||||
|
$env:VITE_APP_TERMS_URL
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Get-ProjectEnvValue -Name 'VITE_APP_TERMS_URL'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if ([string]::IsNullOrWhiteSpace($ExpectedPrivacyUrl)) {
|
if ([string]::IsNullOrWhiteSpace($ExpectedPrivacyUrl)) {
|
||||||
$ExpectedPrivacyUrl = $env:VITE_APP_PRIVACY_URL
|
$ExpectedPrivacyUrl = if (-not [string]::IsNullOrWhiteSpace($env:VITE_APP_PRIVACY_URL)) {
|
||||||
|
$env:VITE_APP_PRIVACY_URL
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Get-ProjectEnvValue -Name 'VITE_APP_PRIVACY_URL'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
[string]::IsNullOrWhiteSpace($ExpectedTermsUrl) -xor
|
[string]::IsNullOrWhiteSpace($ExpectedTermsUrl) -xor
|
||||||
@@ -25,6 +52,17 @@ if (
|
|||||||
) {
|
) {
|
||||||
throw 'ExpectedTermsUrl and ExpectedPrivacyUrl must be provided together.'
|
throw 'ExpectedTermsUrl and ExpectedPrivacyUrl must be provided together.'
|
||||||
}
|
}
|
||||||
|
$uncheckedConsentMessage = -join @(
|
||||||
|
[char]0x8BF7,
|
||||||
|
[char]0x5148,
|
||||||
|
[char]0x9605,
|
||||||
|
[char]0x8BFB,
|
||||||
|
[char]0x5E76,
|
||||||
|
[char]0x52FE,
|
||||||
|
[char]0x9009,
|
||||||
|
[char]0x540C,
|
||||||
|
[char]0x610F
|
||||||
|
)
|
||||||
|
|
||||||
if ([string]::IsNullOrWhiteSpace($ApkPath)) {
|
if ([string]::IsNullOrWhiteSpace($ApkPath)) {
|
||||||
$ApkPath = Join-Path $projectRoot 'dist\debug\android_debug.apk'
|
$ApkPath = Join-Path $projectRoot 'dist\debug\android_debug.apk'
|
||||||
@@ -163,14 +201,20 @@ try {
|
|||||||
if ($legalAppServiceFiles.Count -ne 1) {
|
if ($legalAppServiceFiles.Count -ne 1) {
|
||||||
throw "Expected exactly one App service for login legal-link verification, found $($legalAppServiceFiles.Count)."
|
throw "Expected exactly one App service for login legal-link verification, found $($legalAppServiceFiles.Count)."
|
||||||
}
|
}
|
||||||
$legalAppService = Get-Content -Raw -Encoding UTF8 -LiteralPath $legalAppServiceFiles[0]
|
$legalAppServicePath = if ($legalAppServiceFiles[0] -is [IO.FileInfo]) {
|
||||||
|
$legalAppServiceFiles[0].FullName
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[string]$legalAppServiceFiles[0]
|
||||||
|
}
|
||||||
|
$legalAppService = Get-Content -Raw -Encoding UTF8 -LiteralPath $legalAppServicePath
|
||||||
if (-not $legalAppService.Contains($ExpectedTermsUrl)) {
|
if (-not $legalAppService.Contains($ExpectedTermsUrl)) {
|
||||||
throw 'Packaged login flow is missing the expected service agreement URL.'
|
throw 'Packaged login flow is missing the expected service agreement URL.'
|
||||||
}
|
}
|
||||||
if (-not $legalAppService.Contains($ExpectedPrivacyUrl)) {
|
if (-not $legalAppService.Contains($ExpectedPrivacyUrl)) {
|
||||||
throw 'Packaged login flow is missing the expected privacy policy URL.'
|
throw 'Packaged login flow is missing the expected privacy policy URL.'
|
||||||
}
|
}
|
||||||
if (-not $legalAppService.Contains('请先阅读并勾选同意')) {
|
if (-not $legalAppService.Contains($uncheckedConsentMessage)) {
|
||||||
throw 'Packaged login flow is missing the unchecked-consent failure message.'
|
throw 'Packaged login flow is missing the unchecked-consent failure message.'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
import { readFileSync, existsSync, readdirSync } from 'node:fs';
|
||||||
import { relative, resolve } from 'node:path';
|
import { relative, resolve } from 'node:path';
|
||||||
|
import { loadEnv } from 'vite';
|
||||||
import {
|
import {
|
||||||
validateAndroidPrivacyDocument,
|
validateAndroidPrivacyDocument,
|
||||||
validateLegalUrlPair
|
validateLegalUrlPair
|
||||||
@@ -12,6 +13,7 @@ const requireLegalConsent = process.argv.includes('--require-legal-consent');
|
|||||||
const checkLegalUrls = process.argv.includes('--check-legal-urls');
|
const checkLegalUrls = process.argv.includes('--check-legal-urls');
|
||||||
const failures = [];
|
const failures = [];
|
||||||
let releaseLegalUrls;
|
let releaseLegalUrls;
|
||||||
|
const publicBuildEnv = loadEnv(process.env.NODE_ENV || 'production', projectRoot, 'VITE_');
|
||||||
|
|
||||||
const fail = (message) => failures.push(message);
|
const fail = (message) => failures.push(message);
|
||||||
const compiledAppRoot = resolve(projectRoot, 'dist/build/app');
|
const compiledAppRoot = resolve(projectRoot, 'dist/build/app');
|
||||||
@@ -260,8 +262,8 @@ if (requireLegalConsent) {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
releaseLegalUrls = validateLegalUrlPair(
|
releaseLegalUrls = validateLegalUrlPair(
|
||||||
process.env.VITE_APP_TERMS_URL,
|
process.env.VITE_APP_TERMS_URL || publicBuildEnv.VITE_APP_TERMS_URL,
|
||||||
process.env.VITE_APP_PRIVACY_URL
|
process.env.VITE_APP_PRIVACY_URL || publicBuildEnv.VITE_APP_PRIVACY_URL
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
fail(`release build legal URL environment is invalid: ${error instanceof Error ? error.message : String(error)}`);
|
fail(`release build legal URL environment is invalid: ${error instanceof Error ? error.message : String(error)}`);
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
"appid" : "__UNI__B36D8BE",
|
"appid" : "__UNI__B36D8BE",
|
||||||
"description" : "帮道员工端",
|
"description" : "帮道员工端",
|
||||||
"vueVersion" : "3",
|
"vueVersion" : "3",
|
||||||
"versionName" : "0.1.11",
|
"versionName" : "0.1.12",
|
||||||
"versionCode" : "111",
|
"versionCode" : "112",
|
||||||
"uniStatistics" : {
|
"uniStatistics" : {
|
||||||
"enable" : false
|
"enable" : false
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -137,6 +137,20 @@ test('正式法务地址必须使用不同的公网 HTTPS 页面', () => {
|
|||||||
));
|
));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('登录页公网法务地址由版本化公共环境配置供 npm 与 HBuilderX 共用', async () => {
|
||||||
|
const [publicEnv, configureScript, verifier] = await Promise.all([
|
||||||
|
readFile(new URL('../.env', import.meta.url), 'utf8'),
|
||||||
|
readFile(new URL('../scripts/configure-android-privacy.mjs', import.meta.url), 'utf8'),
|
||||||
|
readFile(new URL('../scripts/verify-app-assets.mjs', import.meta.url), 'utf8')
|
||||||
|
]);
|
||||||
|
|
||||||
|
assert.match(publicEnv, /^VITE_APP_TERMS_URL=https:\/\/peilian\.njzhmj\.top\/legal\/terms\.html$/m);
|
||||||
|
assert.match(publicEnv, /^VITE_APP_PRIVACY_URL=https:\/\/peilian\.njzhmj\.top\/legal\/privacy\.html$/m);
|
||||||
|
assert.doesNotMatch(publicEnv, /(?:TOKEN|SECRET|PASSWORD|KEY)=/i);
|
||||||
|
assert.match(configureScript, /loadEnv\(process\.env\.NODE_ENV \|\| 'production', projectRoot, 'VITE_'\)/);
|
||||||
|
assert.match(verifier, /loadEnv\(process\.env\.NODE_ENV \|\| 'production', projectRoot, 'VITE_'\)/);
|
||||||
|
});
|
||||||
|
|
||||||
test('Android 原生隐私配置明确关闭弹窗,法务地址仍须通过登录页构建校验', async () => {
|
test('Android 原生隐私配置明确关闭弹窗,法务地址仍须通过登录页构建校验', async () => {
|
||||||
const template = await readFile(new URL('../androidPrivacy.json.example', import.meta.url), 'utf8');
|
const template = await readFile(new URL('../androidPrivacy.json.example', import.meta.url), 'utf8');
|
||||||
const rendered = renderAndroidPrivacy(
|
const rendered = renderAndroidPrivacy(
|
||||||
@@ -201,6 +215,8 @@ test('APK 门禁区分自定义调试基座与内置业务资源的测试包', a
|
|||||||
assert.match(verifier, /Packaged login flow is missing the expected service agreement URL/);
|
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 expected privacy policy URL/);
|
||||||
assert.match(verifier, /Packaged login flow is missing the unchecked-consent failure message/);
|
assert.match(verifier, /Packaged login flow is missing the unchecked-consent failure message/);
|
||||||
|
assert.match(verifier, /\$legalAppServiceFiles\[0\]\.FullName/);
|
||||||
|
assert.doesNotMatch(verifier, /[^\x00-\x7F]/, 'Windows PowerShell 5.1 脚本必须保持纯 ASCII');
|
||||||
assert.match(verifier, /dist\\build\\app\\app-service\.js/);
|
assert.match(verifier, /dist\\build\\app\\app-service\.js/);
|
||||||
assert.match(verifier, /dist\\build\\app-plus\\app-service\.js/);
|
assert.match(verifier, /dist\\build\\app-plus\\app-service\.js/);
|
||||||
assert.match(verifier, /fixed test SMS code/);
|
assert.match(verifier, /fixed test SMS code/);
|
||||||
|
|||||||
Reference in New Issue
Block a user