diff --git a/packages/app-desktop/build-mac/entitlements.mac.inherit.plist b/packages/app-desktop/build-mac/entitlements.mac.inherit.plist new file mode 100644 index 0000000000..46f43d4a07 --- /dev/null +++ b/packages/app-desktop/build-mac/entitlements.mac.inherit.plist @@ -0,0 +1,12 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.allow-dyld-environment-variables + + + diff --git a/packages/app-desktop/package-lock.json b/packages/app-desktop/package-lock.json index 115de9fa20..f96f6301f7 100644 --- a/packages/app-desktop/package-lock.json +++ b/packages/app-desktop/package-lock.json @@ -5956,6 +5956,75 @@ "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-0.3.0.tgz", "integrity": "sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=" }, + "electron-notarize": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.0.0.tgz", + "integrity": "sha512-dsib1IAquMn0onCrNMJ6gtEIZn/azG8hZMCYOuZIMVMUeRMgBYHK1s5TK9P8xAcrAjh/2aN5WYHzgVSWX314og==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "dependencies": { + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "fs-extra": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^1.0.0" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + }, + "dependencies": { + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "universalify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "dev": true + } + } + }, "electron-publish": { "version": "22.9.1", "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-22.9.1.tgz", diff --git a/packages/app-desktop/package.json b/packages/app-desktop/package.json index d386cea236..db784e30a9 100644 --- a/packages/app-desktop/package.json +++ b/packages/app-desktop/package.json @@ -27,6 +27,7 @@ "appId": "net.cozic.joplin-desktop", "productName": "Joplin", "npmRebuild": false, + "afterSign": "./tools/notarizeMacApp.js", "extraResources": [ "build/icons/*", "build/images/*" @@ -73,7 +74,9 @@ }, "mac": { "icon": "../../Assets/macOs.icns", - "target": "dmg" + "target": "dmg", + "hardenedRuntime": true, + "entitlements": "./build-mac/entitlements.mac.inherit.plist" }, "linux": { "icon": "../../Assets/LinuxIcons", @@ -101,6 +104,7 @@ "babel-preset-react": "^6.24.1", "electron": "^10.1.6", "electron-builder": "22.9.1", + "electron-notarize": "^1.0.0", "electron-rebuild": "^2.3.2", "glob": "^7.1.6", "gulp": "^4.0.2", diff --git a/packages/app-desktop/tools/notarizeMacApp.js b/packages/app-desktop/tools/notarizeMacApp.js new file mode 100644 index 0000000000..701f00cbd2 --- /dev/null +++ b/packages/app-desktop/tools/notarizeMacApp.js @@ -0,0 +1,57 @@ +const fs = require('fs'); +const path = require('path'); +const electron_notarize = require('electron-notarize'); + +module.exports = async function(params) { + if (process.platform !== 'darwin') return; + + console.info('Checking if notarization should be done...'); + + if (process.env.TRAVIS_PULL_REQUEST) { + console.info('Detected Travis pull request build - skipping notarization'); + return; + } + + if (!!process.env.TRAVIS && !process.env.TRAVIS_TAG) { + console.info('Detected Travis environment but no tag - skipping notarization'); + return; + } + + if (!process.env.APPLE_ID || !process.env.APPLE_ID_PASSWORD) { + console.warn('Environment variables APPLE_ID and APPLE_ID_PASSWORD not found - notarization will NOT be done.'); + return; + } + + // Same appId in electron-builder. + const appId = 'net.cozic.joplin-desktop'; + + const appPath = path.join(params.appOutDir, `${params.packager.appInfo.productFilename}.app`); + if (!fs.existsSync(appPath)) { + throw new Error(`Cannot find application at: ${appPath}`); + } + + console.log(`Notarizing ${appId} found at ${appPath}`); + + await electron_notarize.notarize({ + appBundleId: appId, + appPath: appPath, + + // Apple Developer email address + appleId: process.env.APPLE_ID, + + // App-specific password: https://support.apple.com/en-us/HT204397 + appleIdPassword: process.env.APPLE_ID_PASSWORD, + + // When Apple ID is attached to multiple providers (eg if the + // account has been used to build multiple apps for different + // companies), in that case the provider "Team Short Name" (also + // known as "ProviderShortname") must be provided. + // + // Use this to get it: + // + // xcrun altool --list-providers -u APPLE_ID -p APPLE_ID_PASSWORD + ascProvider: process.env.APPLE_ASC_PROVIDER, + }); + + console.log(`Done notarizing ${appId}`); +};