@@ -9,6 +9,9 @@ import { FusesPlugin } from '@electron-forge/plugin-fuses';
99import { FuseV1Options , FuseVersion } from '@electron/fuses' ;
1010import { PublisherGithub } from '@electron-forge/publisher-github' ;
1111import dotenv from 'dotenv' ;
12+ import { execSync } from 'child_process' ;
13+ import * as fs from 'fs' ;
14+ import * as path from 'path' ;
1215
1316// Load environment variables from .env file (local development only)
1417dotenv . config ( ) ;
@@ -68,6 +71,64 @@ const config: ForgeConfig = {
6871 } ,
6972 } ,
7073 rebuildConfig : { } ,
74+ // Hooks for post-processing after packaging
75+ hooks : {
76+ postPackage : async ( _config , options ) => {
77+ // Only run for MAS builds on macOS
78+ if ( ! isMAS || options . platform !== 'mas' ) {
79+ return ;
80+ }
81+
82+ console . log ( '[postPackage] Re-signing helper apps with correct entitlements for MAS...' ) ;
83+
84+ const appPath = options . outputPaths [ 0 ] ;
85+ const frameworksPath = path . join ( appPath , 'Contents' , 'Frameworks' ) ;
86+ const identity = process . env . SIGNING_IDENTITY_APPSTORE || 'Apple Distribution' ;
87+ const childEntitlements = path . resolve ( 'entitlements.child.plist' ) ;
88+
89+ if ( ! fs . existsSync ( frameworksPath ) ) {
90+ console . log ( '[postPackage] No Frameworks directory found, skipping helper re-signing' ) ;
91+ return ;
92+ }
93+
94+ // Find all helper apps
95+ const items = fs . readdirSync ( frameworksPath ) ;
96+ const helperApps = items . filter ( item => item . endsWith ( '.app' ) ) ;
97+
98+ for ( const helperApp of helperApps ) {
99+ const helperPath = path . join ( frameworksPath , helperApp ) ;
100+ console . log ( `[postPackage] Re-signing helper: ${ helperApp } ` ) ;
101+
102+ try {
103+ // Re-sign the helper app with child entitlements (inherit only)
104+ execSync (
105+ `codesign --force --sign "${ identity } " --entitlements "${ childEntitlements } " --timestamp=none "${ helperPath } "` ,
106+ { stdio : 'inherit' }
107+ ) ;
108+ console . log ( `[postPackage] ✅ Successfully re-signed: ${ helperApp } ` ) ;
109+ } catch ( error ) {
110+ console . error ( `[postPackage] ❌ Failed to re-sign ${ helperApp } :` , error ) ;
111+ throw error ;
112+ }
113+ }
114+
115+ // Re-sign the main app to update the seal after helper modifications
116+ console . log ( '[postPackage] Re-signing main app to update seal...' ) ;
117+ const mainEntitlements = path . resolve ( 'entitlements.mas.plist' ) ;
118+ try {
119+ execSync (
120+ `codesign --force --sign "${ identity } " --entitlements "${ mainEntitlements } " --timestamp=none "${ appPath } "` ,
121+ { stdio : 'inherit' }
122+ ) ;
123+ console . log ( '[postPackage] ✅ Successfully re-signed main app' ) ;
124+ } catch ( error ) {
125+ console . error ( '[postPackage] ❌ Failed to re-sign main app:' , error ) ;
126+ throw error ;
127+ }
128+
129+ console . log ( '[postPackage] Helper re-signing complete' ) ;
130+ } ,
131+ } ,
71132 makers : [
72133 // macOS: DMG (primary) and ZIP (backup/CI) for Developer ID distribution
73134 new MakerDMG ( {
0 commit comments