62 lines
1.8 KiB
JavaScript
62 lines
1.8 KiB
JavaScript
import { readFile } from "node:fs/promises";
|
|||
|
|
import path from "node:path";
|
||
|
|
import { repositoryRoot } from "./repository-files.mjs";
|
||
|
|
|
||
|
|
const manifestPath = path.join(repositoryRoot, "app", "src", "main", "AndroidManifest.xml");
|
||
|
|
const backupRulesPath = path.join(
|
||
|
|
repositoryRoot,
|
||
|
|
"app",
|
||
|
|
"src",
|
||
|
|
"main",
|
||
|
|
"res",
|
||
|
|
"xml",
|
||
|
|
"backup_rules.xml",
|
||
|
|
);
|
||
|
|
const extractionRulesPath = path.join(
|
||
|
|
repositoryRoot,
|
||
|
|
"app",
|
||
|
|
"src",
|
||
|
|
"main",
|
||
|
|
"res",
|
||
|
|
"xml",
|
||
|
|
"data_extraction_rules.xml",
|
||
|
|
);
|
||
|
|
|
||
|
|
const [manifest, backupRules, extractionRules] = await Promise.all([
|
||
|
|
readFile(manifestPath, "utf8"),
|
||
|
|
readFile(backupRulesPath, "utf8"),
|
||
|
|
readFile(extractionRulesPath, "utf8"),
|
||
|
|
]);
|
||
|
|
|
||
|
|
const failures = [];
|
||
|
|
if (!manifest.includes('android:allowBackup="false"')) {
|
||
|
|
failures.push("Android backup must remain disabled");
|
||
|
|
}
|
||
|
|
if (!manifest.includes('android:usesCleartextTraffic="false"')) {
|
||
|
|
failures.push("cleartext traffic must remain disabled");
|
||
|
|
}
|
||
|
|
if (/android\.permission\.INTERNET/u.test(manifest)) {
|
||
|
|
failures.push("the offline application must not request INTERNET permission");
|
||
|
|
}
|
||
|
|
|
||
|
|
for (const domain of ["root", "file", "database", "sharedpref", "external"]) {
|
||
|
|
const exclusion = `<exclude domain="${domain}" path="." />`;
|
||
|
|
if (!backupRules.includes(exclusion)) {
|
||
|
|
failures.push(`legacy backup rules do not exclude ${domain}`);
|
||
|
|
}
|
||
|
|
const extractionOccurrences = extractionRules.split(exclusion).length - 1;
|
||
|
|
if (extractionOccurrences !== 2) {
|
||
|
|
failures.push(
|
||
|
|
`data extraction rules must exclude ${domain} from cloud backup and device transfer`,
|
||
|
|
);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (failures.length > 0) {
|
||
|
|
console.error("Local-data boundary verification failed:");
|
||
|
|
for (const failure of failures) console.error(`- ${failure}`);
|
||
|
|
process.exitCode = 1;
|
||
|
|
} else {
|
||
|
|
console.log("Local-data boundary verification passed.");
|
||
|
|
}
|