@@ -5,6 +5,11 @@ import { join, resolve } from 'node:path';
55import { afterEach , describe , expect , it } from 'vitest' ;
66
77const tempRoots : string [ ] = [ ] ;
8+ const scannerPath = resolve ( process . cwd ( ) , 'scripts/verify-release-privacy.mjs' ) ;
9+
10+ function runScanner ( artifact : string ) {
11+ return spawnSync ( process . execPath , [ scannerPath , artifact ] , { encoding : 'utf8' } ) ;
12+ }
813
914afterEach ( ( ) => {
1015 for ( const root of tempRoots . splice ( 0 ) ) rmSync ( root , { force : true , recursive : true } ) ;
@@ -23,13 +28,29 @@ describe('release privacy verification', () => {
2328 writeFileSync ( join ( externalDirectory , 'private.txt' ) , '/Users/private-owner/secret' ) ;
2429 symlinkSync ( externalDirectory , join ( artifact , 'Applications' ) ) ;
2530
26- const result = spawnSync (
27- process . execPath ,
28- [ resolve ( process . cwd ( ) , 'scripts/verify-release-privacy.mjs' ) , artifact ] ,
29- { encoding : 'utf8' } ,
30- ) ;
31+ const result = runScanner ( artifact ) ;
3132
3233 expect ( result . status , result . stderr ) . toBe ( 0 ) ;
3334 expect ( result . stdout ) . toContain ( 'Release privacy check passed (1 files, 1 symlinks)' ) ;
3435 } ) ;
36+
37+ it ( 'allows only the embedded provisioning profiles required by signed apps' , ( ) => {
38+ const tempRoot = mkdtempSync ( join ( tmpdir ( ) , 'voyager-release-privacy-' ) ) ;
39+ tempRoots . push ( tempRoot ) ;
40+
41+ const contents = join ( tempRoot , 'Voyager.app' , 'Contents' ) ;
42+ const extensionContents = join ( contents , 'PlugIns' , 'Voyager Extension.appex' , 'Contents' ) ;
43+ mkdirSync ( contents , { recursive : true } ) ;
44+ mkdirSync ( extensionContents , { recursive : true } ) ;
45+ writeFileSync ( join ( contents , 'embedded.provisionprofile' ) , 'signed profile content' ) ;
46+ writeFileSync ( join ( extensionContents , 'embedded.provisionprofile' ) , 'signed profile content' ) ;
47+
48+ const expectedProfileResult = runScanner ( tempRoot ) ;
49+ expect ( expectedProfileResult . status , expectedProfileResult . stderr ) . toBe ( 0 ) ;
50+
51+ writeFileSync ( join ( contents , 'exported.provisionprofile' ) , 'unexpected profile content' ) ;
52+ const unexpectedProfileResult = runScanner ( tempRoot ) ;
53+ expect ( unexpectedProfileResult . status ) . toBe ( 1 ) ;
54+ expect ( unexpectedProfileResult . stderr ) . toContain ( 'forbidden release filename' ) ;
55+ } ) ;
3556} ) ;
0 commit comments