From e05198041dde447221f4711d0c655ceb3439ff94 Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Tue, 6 Jan 2026 16:39:34 -0800 Subject: [PATCH 1/5] Add unique-slug@5.0.0 to package-lock.json --- package-lock.json | 34 ++++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6c4c125..c92dafd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,8 @@ "devDependencies": { "electron": "^39.2.7", "electron-builder": "^26.4.0", - "jimp": "^1.6.0" + "jimp": "^1.6.0", + "unique-slug": "^5.0.0" } }, "node_modules/@develar/schema-utils": { @@ -398,6 +399,7 @@ "dev": true, "license": "BSD-2-Clause", "optional": true, + "peer": true, "dependencies": { "cross-dirname": "^0.1.0", "debug": "^4.3.4", @@ -419,6 +421,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", @@ -435,6 +438,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "universalify": "^2.0.0" }, @@ -449,6 +453,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": ">= 10.0.0" } @@ -2177,7 +2182,8 @@ "integrity": "sha512-+R08/oI0nl3vfPcqftZRpytksBXDzOUveBq/NBVx0sUp1axwzPQrKinNx5yd5sxPu8j1wIy8AfnVQ+5eFdha6Q==", "dev": true, "license": "MIT", - "optional": true + "optional": true, + "peer": true }, "node_modules/cross-spawn": { "version": "7.0.6", @@ -2684,6 +2690,7 @@ "dev": true, "hasInstallScript": true, "license": "MIT", + "peer": true, "dependencies": { "@electron/asar": "^3.2.1", "debug": "^4.1.1", @@ -2704,6 +2711,7 @@ "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -4492,7 +4500,6 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=12" }, @@ -4555,6 +4562,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "dependencies": { "commander": "^9.4.0" }, @@ -4572,6 +4580,7 @@ "dev": true, "license": "MIT", "optional": true, + "peer": true, "engines": { "node": "^12.20.0 || >=14" } @@ -4820,6 +4829,7 @@ "deprecated": "Rimraf versions prior to v4 are no longer supported", "dev": true, "license": "ISC", + "peer": true, "dependencies": { "glob": "^7.1.3" }, @@ -5300,6 +5310,7 @@ "integrity": "sha512-yYrrsWnrXMcdsnu/7YMYAofM1ktpL5By7vZhf15CrXijWWrEYZks5AXBudalfSWJLlnen/QUJUB5aoB0kqZUGA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "mkdirp": "^0.5.1", "rimraf": "~2.6.2" @@ -5363,6 +5374,7 @@ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "minimist": "^1.2.6" }, @@ -5481,7 +5493,13 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "dev": true, - "license": "MIT" + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, "node_modules/unique-filename": { "version": "4.0.0", @@ -5496,10 +5514,10 @@ "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/undici-types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", - "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", "dev": true, "license": "ISC", "dependencies": { From 088496aee447d8ed78c582f1aa96569bae2560cb Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Wed, 7 Jan 2026 08:33:03 -0800 Subject: [PATCH 2/5] Add explicit PKG installer signing for MAS builds --- .github/workflows/release.yml | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 092896c..170a646 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -168,7 +168,49 @@ jobs: set -o pipefail # Build MAS package (notarization disabled by unsetting APPLE_API_KEY* vars above) npm run build:desktop:mas 2>&1 | tee /tmp/electron-builder-mas.log - exit ${PIPESTATUS[0]} + BUILD_EXIT=$? + + # Verify and fix PKG signing if needed + PKG_FILE=$(find dist -name "*.pkg" -type f | head -1) + if [ -n "$PKG_FILE" ] && [ -f "$PKG_FILE" ]; then + echo "Checking PKG signature: $PKG_FILE" + + # Check if PKG is signed with installer certificate + if ! pkgutil --check-signature "$PKG_FILE" 2>&1 | grep -q "3rd Party Mac Developer Installer"; then + echo "⚠️ PKG not signed with installer certificate, re-signing..." + + # Find installer identity + INSTALLER_IDENTITY=$(security find-identity -v -p basic | grep "3rd Party Mac Developer Installer" | head -1 | sed 's/.*"\(.*\)".*/\1/') + + if [ -n "$INSTALLER_IDENTITY" ]; then + echo "Found installer identity: $INSTALLER_IDENTITY" + + # Re-sign the PKG with installer certificate + TEMP_PKG="${PKG_FILE}.temp" + productsign --sign "$INSTALLER_IDENTITY" "$PKG_FILE" "$TEMP_PKG" + + if [ -f "$TEMP_PKG" ]; then + mv "$TEMP_PKG" "$PKG_FILE" + echo "✅ PKG re-signed with installer certificate" + + # Verify the signature + pkgutil --check-signature "$PKG_FILE" + else + echo "❌ Failed to re-sign PKG" + exit 1 + fi + else + echo "❌ Could not find 3rd Party Mac Developer Installer certificate" + exit 1 + fi + else + echo "✅ PKG already signed with installer certificate" + fi + else + echo "⚠️ No PKG file found" + fi + + exit $BUILD_EXIT env: # Enable signing for MAS builds (but NOT notarization) CI: true From a7d9c621cd20d0e7c6b0ef2e28d816e7465578d8 Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Wed, 7 Jan 2026 13:55:33 -0800 Subject: [PATCH 3/5] Fix MAS signing: Remove --options runtime flag The --options runtime flag causes codesign to add the com.apple.developer.team-identifier entitlement, which is not in the MAS provisioning profile. This flag is only for Developer ID distribution, not Mac App Store builds. Fixes Transporter validation error 409. --- scripts/fix-mas-icon.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/fix-mas-icon.js b/scripts/fix-mas-icon.js index 55577c2..d50af7b 100755 --- a/scripts/fix-mas-icon.js +++ b/scripts/fix-mas-icon.js @@ -118,7 +118,8 @@ exports.default = async function(context) { const helperPath = path.join(helpersPath, helper); if (fs.statSync(helperPath).isFile() && !helper.endsWith('.plist')) { try { - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" --options runtime "${helperPath}"`, { + // Don't use --options runtime for MAS builds (that's for Developer ID only) + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" "${helperPath}"`, { stdio: 'inherit' }); console.log(`✅ Re-signed helper: ${helper}`); @@ -133,8 +134,8 @@ exports.default = async function(context) { helperApps.sort((a, b) => b.split(path.sep).length - a.split(path.sep).length); for (const helperApp of helperApps) { try { - // Sign the helper app - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" --options runtime "${helperApp}"`, { + // Sign the helper app (no --options runtime for MAS builds) + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" "${helperApp}"`, { stdio: 'inherit' }); @@ -154,25 +155,25 @@ exports.default = async function(context) { const electronFrameworkPath = path.join(frameworksPath, 'Electron Framework.framework'); const electronFrameworkExecutable = path.join(electronFrameworkPath, 'Versions', 'A', 'Electron Framework'); if (fs.existsSync(electronFrameworkExecutable)) { - // Sign the executable inside the framework first - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" --options runtime "${electronFrameworkExecutable}"`, { + // Sign the executable inside the framework first (no --options runtime for MAS) + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" "${electronFrameworkExecutable}"`, { stdio: 'inherit' }); // Then sign the framework bundle - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" --options runtime "${electronFrameworkPath}"`, { + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" "${electronFrameworkPath}"`, { stdio: 'inherit' }); console.log('✅ Re-signed Electron Framework (executable and bundle)'); } else if (fs.existsSync(electronFrameworkPath)) { // Fallback: sign the framework bundle if executable path doesn't exist - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" --options runtime "${electronFrameworkPath}"`, { + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlementsInherit}" "${electronFrameworkPath}"`, { stdio: 'inherit' }); console.log('✅ Re-signed Electron Framework (bundle only)'); } - // Sign main app bundle last - execSync(`codesign --force --sign "${identity}" --entitlements "${entitlements}" --options runtime "${appBundlePath}"`, { + // Sign main app bundle last (no --options runtime for MAS builds) + execSync(`codesign --force --sign "${identity}" --entitlements "${entitlements}" "${appBundlePath}"`, { stdio: 'inherit' }); console.log('✅ App bundle re-signed successfully'); From 06156bde4c03ae90c99a734420b3a6f30c3fbd86 Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Wed, 7 Jan 2026 14:16:59 -0800 Subject: [PATCH 4/5] Fix MAS build: Disable hardenedRuntime for Mac App Store hardenedRuntime is for Developer ID apps (notarization), not MAS. When enabled for MAS, it adds com.apple.developer.team-identifier entitlement which is not in the provisioning profile. MAS apps don't need hardened runtime - they're sandboxed. Fixes Transporter error 409. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7cdd350..52f6bd2 100644 --- a/package.json +++ b/package.json @@ -70,7 +70,7 @@ "mas": { "category": "public.app-category.productivity", "icon": "desktop/assets/icon.icns", - "hardenedRuntime": true, + "hardenedRuntime": false, "gatekeeperAssess": false, "entitlements": "desktop/entitlements.mas.plist", "entitlementsInherit": "desktop/entitlements.mas.inherit.plist", From a752e7fecd1143f5de73560169c0efeda654e5ac Mon Sep 17 00:00:00 2001 From: Ian Miller Date: Wed, 7 Jan 2026 16:58:53 -0800 Subject: [PATCH 5/5] Remove App Groups entitlement - not enabled on App ID The App ID does not have App Groups capability enabled, so this entitlement must be removed from the bundle to match the provisioning profile. Fixes Transporter validation error. --- desktop/entitlements.mas.plist | 4 ---- 1 file changed, 4 deletions(-) diff --git a/desktop/entitlements.mas.plist b/desktop/entitlements.mas.plist index a071326..77a321b 100644 --- a/desktop/entitlements.mas.plist +++ b/desktop/entitlements.mas.plist @@ -4,10 +4,6 @@ com.apple.security.app-sandbox - com.apple.security.application-groups - - 4MSL3T2696.com.iandmiller.visualtimer - com.apple.security.network.client com.apple.security.files.user-selected.read-write