diff --git a/build/entitlements.mac.plist b/build/entitlements.mac.plist new file mode 100644 index 000000000..00e256e02 --- /dev/null +++ b/build/entitlements.mac.plist @@ -0,0 +1,25 @@ + + + + + com.apple.security.cs.allow-dyld-environment-variables + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.device.audio-input + + com.apple.security.device.microphone + + com.apple.security.files.downloads.read-write + + com.apple.security.files.user-selected.read-write + + com.apple.security.network.client + + + + diff --git a/package.json b/package.json index d7902d1c4..88a6718ef 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "build": "electron-builder --config.extraMetadata.environment=$SIGNAL_ENV", "build-release": "SIGNAL_ENV=production npm run build -- --config.directories.output=release", "sign-release": "node ts/updater/generateSignature.js", + "notarize": "node ts/build/notarize.js", "build-module-protobuf": "pbjs --target static-module --wrap commonjs --out ts/protobuf/compiled.js protos/*.proto && pbts --out ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "clean-module-protobuf": "rm -f ts/protobuf/compiled.d.ts ts/protobuf/compiled.js", "build-protobuf": "yarn build-module-protobuf", @@ -59,6 +60,7 @@ "electron-editor-context-menu": "1.1.1", "electron-is-dev": "0.3.0", "electron-mocha": "8.1.1", + "electron-notarize": "0.1.1", "emoji-datasource": "4.1.0", "emoji-datasource-apple": "4.1.0", "emoji-regex": "8.0.0", @@ -194,6 +196,8 @@ "artifactName": "${name}-mac-${version}.${ext}", "category": "public.app-category.social-networking", "darkModeSupport": true, + "hardenedRuntime": true, + "entitlements": "./build/entitlements.mac.plist", "icon": "build/icons/mac/icon.icns", "publish": [ { diff --git a/prepare_import_build.js b/prepare_import_build.js index e74a168ed..4fb59e55a 100644 --- a/prepare_import_build.js +++ b/prepare_import_build.js @@ -60,6 +60,11 @@ checkValue(packageJson, WIN_ASSET_PATH, WIN_ASSET_START_VALUE); _.set(packageJson, MAC_ASSET_PATH, MAC_ASSET_END_VALUE); _.set(packageJson, WIN_ASSET_PATH, WIN_ASSET_END_VALUE); +const MAC_BUILD_TARGET = 'build.mac.target'; +const MAC_BUILD_TARGET_END_VALUE = ['dmg']; + +_.set(packageJson, MAC_BUILD_TARGET, MAC_BUILD_TARGET_END_VALUE); + // --- fs.writeFileSync( diff --git a/ts/build/notarize.ts b/ts/build/notarize.ts new file mode 100644 index 000000000..51aea826a --- /dev/null +++ b/ts/build/notarize.ts @@ -0,0 +1,76 @@ +import { join, resolve } from 'path'; +import { readdir as readdirCallback } from 'fs'; + +import pify from 'pify'; + +import { notarize } from 'electron-notarize'; + +// @ts-ignore +import * as packageJson from '../../package.json'; + +const readdir = pify(readdirCallback); + +/* tslint:disable:no-console */ + +// tslint:disable-next-line:no-floating-promises +go(); + +async function go() { + if (process.platform !== 'darwin') { + console.log('notarize: Skipping, not on macOS'); + + return; + } + + const appPath = await findDMG(); + const appBundleId = packageJson.build.appId; + if (!appBundleId) { + throw new Error( + 'appBundleId must be provided in package.json: build.appId' + ); + } + + const appleId = process.env.APPLE_USERNAME; + if (!appleId) { + throw new Error( + 'appleId must be provided in environment variable APPLE_USERNAME' + ); + } + + const appleIdPassword = process.env.APPLE_PASSWORD; + if (!appleIdPassword) { + throw new Error( + 'appleIdPassword must be provided in environment variable APPLE_PASSWORD' + ); + } + + console.log('Notarizing with...'); + console.log(` file: ${appPath}`); + console.log(` primaryBundleId: ${appBundleId}`); + console.log(` username: ${appleId}`); + + await notarize({ + appBundleId, + appPath, + appleId, + appleIdPassword, + }); +} + +const IS_DMG = /\.dmg$/; +async function findDMG(): Promise { + const releaseDir = resolve('release'); + const files: Array = await readdir(releaseDir); + + const max = files.length; + for (let i = 0; i < max; i += 1) { + const file = files[i]; + const fullPath = join(releaseDir, file); + + if (IS_DMG.test(file)) { + return fullPath; + } + } + + throw new Error("No suitable file found in 'release' folder!"); +} diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 5c27b582c..417d4ae99 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -3352,6 +3352,46 @@ "reasonCategory": "falseMatch", "updated": "2019-04-10T19:08:25.356Z" }, + { + "rule": "jQuery-load(", + "path": "node_modules/electron-notarize/node_modules/debug/dist/debug.js", + "line": " createDebug.enable(createDebug.load());", + "lineNumber": 721, + "reasonCategory": "falseMatch", + "updated": "2019-10-10T18:29:02.491Z" + }, + { + "rule": "jQuery-load(", + "path": "node_modules/electron-notarize/node_modules/debug/dist/debug.js", + "line": " function load() {", + "lineNumber": 855, + "reasonCategory": "falseMatch", + "updated": "2019-10-10T18:29:02.491Z" + }, + { + "rule": "jQuery-load(", + "path": "node_modules/electron-notarize/node_modules/debug/src/browser.js", + "line": "function load() {", + "lineNumber": 211, + "reasonCategory": "falseMatch", + "updated": "2019-10-10T18:29:02.491Z" + }, + { + "rule": "jQuery-load(", + "path": "node_modules/electron-notarize/node_modules/debug/src/common.js", + "line": "\tcreateDebug.enable(createDebug.load());", + "lineNumber": 261, + "reasonCategory": "falseMatch", + "updated": "2019-10-10T18:29:02.491Z" + }, + { + "rule": "jQuery-load(", + "path": "node_modules/electron-notarize/node_modules/debug/src/node.js", + "line": "function load() {", + "lineNumber": 216, + "reasonCategory": "falseMatch", + "updated": "2019-10-10T18:29:02.491Z" + }, { "rule": "eval", "path": "node_modules/electron/electron.d.ts", diff --git a/yarn.lock b/yarn.lock index 4225ae9fe..3c83d93cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2881,6 +2881,14 @@ electron-mocha@8.1.1: which "^1.3.1" yargs "^13.3.0" +electron-notarize@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-0.1.1.tgz#c3563d70c5e7b3315f44e8495b30050a8c408b91" + integrity sha512-TpKfJcz4LXl5jiGvZTs5fbEx+wUFXV5u8voeG5WCHWfY/cdgdD8lDZIZRqLVOtR3VO+drgJ9aiSHIO9TYn/fKg== + dependencies: + debug "^4.1.1" + fs-extra "^8.0.1" + electron-publish@21.2.0: version "21.2.0" resolved "https://registry.yarnpkg.com/electron-publish/-/electron-publish-21.2.0.tgz#cc225cb46aa62e74b899f2f7299b396c9802387d" @@ -3875,7 +3883,7 @@ fs-extra@^7.0.1: jsonfile "^4.0.0" universalify "^0.1.0" -fs-extra@^8.1.0: +fs-extra@^8.0.1, fs-extra@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" integrity sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==