vojo/electron/afterPack.cjs

42 lines
2 KiB
JavaScript

/* eslint-disable @typescript-eslint/no-var-requires -- electron-builder loads this hook as a CommonJS module; require is required. */
// electron-builder afterPack hook: harden Electron fuses on the packaged binary.
//
// By default Electron ships with several fuses ON that let a local process turn
// the signed app into a generic Node interpreter or attach a debugger:
// - RunAsNode (ELECTRON_RUN_AS_NODE)
// - EnableNodeCliInspectArguments (--inspect)
// - EnableNodeOptionsEnvironmentVariable (NODE_OPTIONS injection)
// We flip them OFF. OnlyLoadAppFromAsar + EnableEmbeddedAsarIntegrityValidation
// are intentionally left for later: integrity validation is only meaningful once
// the binary is code-signed (no signing in the current build chain).
const path = require('node:path');
const { existsSync } = require('node:fs');
const { flipFuses, FuseVersion, FuseV1Options } = require('@electron/fuses');
exports.default = async function afterPack(context) {
const { appOutDir, packager, electronPlatformName } = context;
const productName = packager.appInfo.productFilename;
const isMac = electronPlatformName === 'darwin' || electronPlatformName === 'mas';
let electronBinary;
if (isMac) {
electronBinary = path.join(appOutDir, `${productName}.app`, 'Contents', 'MacOS', productName);
} else if (electronPlatformName === 'win32') {
electronBinary = path.join(appOutDir, `${productName}.exe`);
} else {
electronBinary = path.join(appOutDir, packager.executableName || productName);
}
if (!existsSync(electronBinary)) {
throw new Error(`afterPack: could not find Electron binary to harden at ${electronBinary}`);
}
await flipFuses(electronBinary, {
version: FuseVersion.V1,
// Re-applies the ad-hoc signature macOS needs after the binary is mutated.
resetAdHocDarwinSignature: isMac,
[FuseV1Options.RunAsNode]: false,
[FuseV1Options.EnableNodeCliInspectArguments]: false,
[FuseV1Options.EnableNodeOptionsEnvironmentVariable]: false,
});
};