check-cross-client-sync.mjs

4.1 KB · raw

1import { execFileSync } from "node:child_process";2import { existsSync, readFileSync } from "node:fs";3import { dirname, resolve } from "node:path";4import { fileURLToPath } from "node:url";56const browserRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");7const androidRoot = resolve(browserRoot, "../peach-android");8const localJavaHome = "/opt/homebrew/opt/openjdk@17";9const javaHome = process.env.JAVA_HOME ??10  (existsSync(localJavaHome) ? localJavaHome : undefined);11const browserCoordinator = readFileSync(12  resolve(browserRoot, "src/background/sync-coordinator.ts"),13  "utf8",14);15const androidCoordinator = readFileSync(16  resolve(androidRoot, "app/src/main/java/com/peachpasswords/sync/SyncCoordinator.kt"),17  "utf8",18);19const browserSyncTypes = readFileSync(resolve(browserRoot, "src/shared/sync-types.ts"), "utf8");20const androidManifest = readFileSync(21  resolve(androidRoot, "app/src/main/java/com/peachpasswords/sync/DeviceManifestSupport.kt"),22  "utf8",23);24const browserPairedDevices = readFileSync(25  resolve(browserRoot, "src/background/paired-devices.ts"),26  "utf8",27);28const androidPairedDevices = readFileSync(29  resolve(androidRoot, "app/src/main/java/com/peachpasswords/sync/PairedDeviceStore.kt"),30  "utf8",31);3233if (browserCoordinator.includes('helloIn.version === localVersion')) {34  throw new Error("Browser still contains the forbidden equal-version fast path");35}36if (!browserCoordinator.includes("helloIn.deviceManifestVersion === DEVICE_MANIFEST_VERSION")) {37  throw new Error("Browser does not negotiate device manifests from SYNC_HELLO");38}39if (!androidCoordinator.includes("val exchangeDeviceManifest = vault.negotiatesDeviceManifest(hello)")) {40  throw new Error("Android does not negotiate device manifests from SYNC_HELLO");41}42if (!androidCoordinator.includes("peerVersion == DEVICE_MANIFEST_VERSION")) {43  throw new Error("Android does not require an exact device-manifest version match");44}45if (!browserSyncTypes.includes("DEVICE_MANIFEST_VERSION = 0x04") ||46    !androidManifest.includes("DEVICE_MANIFEST_VERSION = 0x04")) {47  throw new Error("Browser and Android device-manifest versions differ");48}49if (!browserPairedDevices.includes("MAX_REVOCATIONS = 500") ||50    !androidPairedDevices.includes("MAX_REVOCATION_RECORDS = 500")) {51  throw new Error("Browser and Android revocation ledger caps differ");52}53if (!browserPairedDevices.includes("enqueueDeviceMutation") ||54    !androidPairedDevices.includes("RegistryMutationGate")) {55  throw new Error("A paired-device registry lacks whole-list mutation serialization");56}57if (!browserPairedDevices.includes("function capRevocations") ||58    !androidPairedDevices.includes("fun capRevocationRecords")) {59  throw new Error("A client lacks largest-issuer-first revocation retention");60}6162execFileSync(63  "npm",64  [65    "test", "--", "--run",66    "src/background/sync-coordinator.test.ts",67    "src/shared/sync-padding.test.ts",68    "src/shared/rendezvous.test.ts",69    "src/shared/device-manifest.test.ts",70    "src/crypto/peachPayload.test.ts",71    "src/shared/sync-entry-envelope.kat.test.ts",72    "src/shared/vault-adopt.test.ts",73    "src/background/paired-devices.test.ts",74    "src/background/relay-adoption-bg.test.ts",75  ],76  { cwd: browserRoot, stdio: "inherit" },77);78execFileSync(79  resolve(androidRoot, "gradlew"),80  [81    "--no-configuration-cache",82    "testDebugUnitTest",83    "--tests",84    "com.peachpasswords.sync.SyncCoordinatorTest",85    "--tests",86    "com.peachpasswords.sync.LockedSyncSpoolModelTest",87    "--tests",88    "com.peachpasswords.sync.SyncPaddingTest",89    "--tests",90    "com.peachpasswords.sync.DeviceManifestSupportTest",91    "--tests",92    "com.peachpasswords.CrossPlatformKATTest",93    "--tests",94    "com.peachpasswords.vault.PeachScriptTest",95    "--tests",96    "com.peachpasswords.sync.SyncEntryEnvelopeKatTest",97    "--tests",98    "com.peachpasswords.sync.VaultAdoptTest",99    "--tests",100    "com.peachpasswords.sync.PairedDeviceRevocationTest",101  ],102  {103    cwd: androidRoot,104    env: { ...process.env, ...(javaHome ? { JAVA_HOME: javaHome } : {}) },105    stdio: "inherit",106  },107);108109console.log("Cross-client sync protocol gate passed.");