@interopio/desktop-cli
Version:
CLI tool for setting up, building and packaging io.Connect Desktop projects
244 lines • 11 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.signAndNotarizeMacOS = signAndNotarizeMacOS;
exports.signBinary = signBinary;
const osx_sign_1 = require("@electron/osx-sign");
const notarize_1 = require("@electron/notarize");
const path_1 = require("path");
const path_2 = require("../../utils/path");
const fs_1 = require("fs");
const logger_1 = require("../../utils/logger");
const fs_extra_1 = __importDefault(require("fs-extra"));
const config_service_1 = require("../config/config.service");
const logger = logger_1.Logger.getInstance();
// Turn on all osx-sign logs
// import debug from "debug";
// debug.enable("electron-osx-sign*");
async function signAndNotarizeMacOS() {
const path = path_2.PathUtils.getIOCDAppBundlePath();
await signBinary(path);
await notarizeOnMacOS(path);
}
// readme - https://github.com/electron/osx-sign
async function signBinary(pathToSign) {
logger.info('Starting code signing process on macOS...');
const codeSignConfig = config_service_1.ConfigManager.config.mac.codeSign;
switch (codeSignConfig.type) {
case 'off':
logger.info('Code signing is disabled (type: off)');
return;
case 'keychain':
await signWithKeychain(pathToSign);
break;
case 'custom':
await signWithCustomScript(pathToSign);
break;
default:
throw new Error(`Unsupported code signing type: ${codeSignConfig.type}`);
}
logger.info('Code signing completed successfully!');
}
async function signWithKeychain(pathToSign) {
logger.debug('Signing with keychain...');
const codeSignConfig = config_service_1.ConfigManager.config.mac.codeSign;
logger.debug(`Removing _CodeSignature directory if it exists...`);
const codeSignaturePath = (0, path_1.join)(path_2.PathUtils.getIOCDDir(), '_CodeSignature');
if ((0, fs_1.existsSync)(codeSignaturePath)) {
fs_extra_1.default.removeSync(codeSignaturePath);
logger.debug(`Removed existing _CodeSignature directory`);
}
else {
logger.debug(`No existing _CodeSignature directory found`);
}
// things we don't need to sign
const IGNORE_EXT = [
".png", ".jpg", ".jpeg", ".gif", ".icns", ".ico", ".svg",
".ttf", ".otf", ".woff", ".woff2",
".pak", ".bin", ".dat", ".json", ".plist", ".md", ".txt", ".rtf",
".html", ".css", ".map",
".mp3", ".mp4", ".wav", ".webm", ".mov", ".ttf",
".asar", ".DS_Store" // do not sign app.asar
];
// remove embedded.provisionprofile file if it is in the app bundle - it gets added by code-signing during dev builds
const embeddedProvisionProfilePath = (0, path_1.join)(path_2.PathUtils.getIOCDDir(), 'embedded.provisionprofile');
if ((0, fs_1.existsSync)(embeddedProvisionProfilePath)) {
logger.debug('Removing embedded.provisionprofile from app bundle...');
fs_extra_1.default.removeSync(embeddedProvisionProfilePath);
logger.debug('embedded.provisionprofile removed');
}
const configPath = path_2.PathUtils.getConfigDir();
const entitlementsPath = (0, path_1.join)(configPath, "mac-build", "entitlements.mac.plist");
if (!(0, fs_1.existsSync)(entitlementsPath)) {
logger.error(`Entitlements file not found at path: ${entitlementsPath}`);
throw new Error(`Entitlements file not found at path: ${entitlementsPath}`);
}
let config = {
app: pathToSign,
entitlements: entitlementsPath,
entitlementsInherit: entitlementsPath,
"entitlements-inherit": entitlementsPath,
"hardened-runtime": true,
hardenedRuntime: true,
preAutoEntitlements: false,
"pre-auto-entitlements": false,
gatekeeperAssess: false, // skip assessment during sign
"gatekeeper-assess": false,
force: true, // re-sign even if already signed
strictVerify: true,
"strict-verify": true,
}; // Add identity if specified
if (codeSignConfig.identity) {
config.identity = codeSignConfig.identity;
logger.debug(`Using code signing identity: ${codeSignConfig.identity}`);
} // Add keychain if specified
if (codeSignConfig.keychain) {
config.keychain = codeSignConfig.keychain;
logger.debug(`Using keychain: ${codeSignConfig.keychain}`);
}
config.ignore = (filePath) => {
// skip obvious non-executables by extension
const lower = filePath.toLowerCase();
if (IGNORE_EXT.some(ext => lower.endsWith(ext)))
return true;
// never sign signature metadata
if (lower.includes("/contents/_codesignature/"))
return true;
if (lower.endsWith("/contents/coderesources"))
return true;
// otherwise let it sign
logger.debug(`Signing file: ${filePath}`);
return false;
};
config.optionsForFile = () => {
return config;
};
const provisionProfilePath = (0, path_1.join)(process.cwd(), 'config', 'mac-build', 'io.cd.provisionprofile');
logger.debug('Checking for provisioning profile at:', provisionProfilePath);
if ((0, fs_1.existsSync)(provisionProfilePath)) {
logger.debug('Using provisioning profile:', provisionProfilePath);
config.provisioningProfile = provisionProfilePath;
}
else {
logger.debug('No provisioning profile found at:', provisionProfilePath);
}
logger.debug(`Signing with config`, config);
await (0, osx_sign_1.sign)(config);
}
async function signWithCustomScript(pathToSign) {
logger.debug('Signing with custom script...');
const codeSignConfig = config_service_1.ConfigManager.config.mac.codeSign;
if (!codeSignConfig.customCodeSignScriptPath) {
throw new Error('Custom code signing requires customCodeSignScriptPath to be configured');
}
if (!(0, fs_1.existsSync)(codeSignConfig.customCodeSignScriptPath)) {
throw new Error(`Custom code signing script not found: ${codeSignConfig.customCodeSignScriptPath}`);
}
try {
logger.debug(`Loading custom code signing script: ${codeSignConfig.customCodeSignScriptPath}`);
// Clear require cache to ensure fresh script load
const scriptPath = (0, path_1.resolve)(codeSignConfig.customCodeSignScriptPath);
delete require.cache[scriptPath];
const customScript = require(scriptPath);
let signFunction;
// Support multiple export formats
if (typeof customScript === 'function') {
signFunction = customScript;
}
else if (typeof customScript.default === 'function') {
signFunction = customScript.default;
}
else if (typeof customScript.sign === 'function') {
signFunction = customScript.sign;
}
else {
throw new Error('Custom code signing script must export a function (either as default export, named "sign" export, or direct export)');
}
// Execute the signing function with the app bundle path and full config
await signFunction(pathToSign, codeSignConfig);
logger.debug('Custom code signing script executed successfully');
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Custom code signing script failed: ${error.message}`);
}
else {
throw new Error(`Custom code signing script failed: ${String(error)}`);
}
}
}
// readme - https://github.com/electron/notarize
async function notarizeOnMacOS(pathToNotarize) {
logger.info('Starting notarization process on macOS...');
const notarizationConfig = config_service_1.ConfigManager.config.mac.notarization;
switch (notarizationConfig.type) {
case 'off':
logger.info('Notarization is disabled (type: off)');
return;
case 'notarytool':
await notarizeWithNotarytool(pathToNotarize);
break;
case 'custom':
await notarizeWithCustomScript(pathToNotarize);
break;
default:
throw new Error(`Unsupported notarization type: ${notarizationConfig.type}`);
}
logger.info('Notarization completed successfully!');
}
async function notarizeWithNotarytool(pathToNotarize) {
logger.debug('Notarizing with notarytool...');
const notarizationConfig = config_service_1.ConfigManager.config.mac.notarization;
let config = {
appPath: pathToNotarize,
appleId: notarizationConfig.appleId ?? "",
appleIdPassword: notarizationConfig.appleIdPassword ?? "",
teamId: notarizationConfig.appleTeamId ?? "",
};
await (0, notarize_1.notarize)(config);
}
async function notarizeWithCustomScript(pathToNotarize) {
logger.debug('Notarizing with custom script...');
const notarizationConfig = config_service_1.ConfigManager.config.mac.notarization;
if (!notarizationConfig.customNotarizationScriptPath) {
throw new Error('Custom notarization requires customNotarizationScriptPath to be configured');
}
if (!(0, fs_1.existsSync)(notarizationConfig.customNotarizationScriptPath)) {
throw new Error(`Custom notarization script not found: ${notarizationConfig.customNotarizationScriptPath}`);
}
try {
logger.debug(`Loading custom notarization script: ${notarizationConfig.customNotarizationScriptPath}`);
// Clear require cache to ensure fresh script load
const scriptPath = (0, path_1.resolve)(notarizationConfig.customNotarizationScriptPath);
delete require.cache[scriptPath];
const customScript = require(scriptPath);
let notarizeFunction;
// Support multiple export formats
if (typeof customScript === 'function') {
notarizeFunction = customScript;
}
else if (typeof customScript.default === 'function') {
notarizeFunction = customScript.default;
}
else if (typeof customScript.notarize === 'function') {
notarizeFunction = customScript.notarize;
}
else {
throw new Error('Custom notarization script must export a function (either as default export, named "notarize" export, or direct export)');
}
// Execute the notarization function with the app bundle path and full config
await notarizeFunction(pathToNotarize, notarizationConfig);
logger.debug('Custom notarization script executed successfully');
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Custom notarization script failed: ${error.message}`);
}
else {
throw new Error(`Custom notarization script failed: ${String(error)}`);
}
}
}
//# sourceMappingURL=macOS.helper.js.map