feat: new per-file API with defaults that work out of the box (#253)
BREAKING CHANGE: The entire API changed
This commit is contained in:
Родитель
6bdaabfba2
Коммит
af53ad09d6
|
@ -28,21 +28,21 @@ version: 2
|
|||
jobs:
|
||||
test-mac-16:
|
||||
macos:
|
||||
xcode: "11.0.0"
|
||||
xcode: "11.6.0"
|
||||
environment:
|
||||
NODE_VERSION: "16"
|
||||
<<: *steps-test
|
||||
|
||||
test-mac-14:
|
||||
macos:
|
||||
xcode: "11.0.0"
|
||||
xcode: "11.6.0"
|
||||
environment:
|
||||
NODE_VERSION: "14"
|
||||
<<: *steps-test
|
||||
|
||||
test-mac-12:
|
||||
macos:
|
||||
xcode: "11.0.0"
|
||||
xcode: "11.6.0"
|
||||
environment:
|
||||
NODE_VERSION: "12"
|
||||
<<: *steps-test
|
||||
|
|
72
README.md
72
README.md
|
@ -77,10 +77,7 @@ The examples below assume that `--pre-auto-entitlements` is enabled.
|
|||
electron-osx-sign path/to/my.app --provisioning-profile=path/to/my.provisionprofile
|
||||
```
|
||||
|
||||
- To specify the entitlements file:
|
||||
```sh
|
||||
electron-osx-sign path/to/my.app --entitlements=path/to/my.entitlements
|
||||
```
|
||||
- To specify custom entitlements files you have to use the JS API.
|
||||
|
||||
- It is recommended to make use of `--version` while signing legacy versions of Electron:
|
||||
```sh
|
||||
|
@ -151,34 +148,21 @@ Needs file extension `.app`.
|
|||
Path to additional binaries that will be signed along with built-ins of Electron.
|
||||
Default to `undefined`.
|
||||
|
||||
`entitlements` - *String*
|
||||
`optionsForFile` - *Function*
|
||||
|
||||
Path to entitlements file for signing the app.
|
||||
Default to built-in entitlements file, Sandbox enabled for Mac App Store platform.
|
||||
See [default.entitlements.mas.plist](https://github.com/electron-userland/electron-osx-sign/blob/master/default.entitlements.mas.plist) or [default.entitlements.darwin.plist](https://github.com/electron-userland/electron-osx-sign/blob/master/default.entitlements.darwin.plist) with respect to your platform.
|
||||
Function that receives the path to a file and can return the entitlements to use for that file to override the default behavior. The
|
||||
object this function returns can include any of the following optional keys.
|
||||
|
||||
`entitlements-inherit` - *String*
|
||||
|
||||
Path to child entitlements which inherit the security settings for signing frameworks and bundles of a distribution. *This option only applies when signing with entitlements.*
|
||||
See [default.entitlements.mas.inherit.plist](https://github.com/electron-userland/electron-osx-sign/blob/master/default.entitlements.mas.inherit.plist) or [default.entitlements.darwin.inherit.plist](https://github.com/electron-userland/electron-osx-sign/blob/master/default.entitlements.darwin.inherit.plist) with respect to your platform.
|
||||
|
||||
`entitlements-loginhelper` - *String*
|
||||
|
||||
Path to login helper entitlement file. When using App Sandbox, the inherited entitlement should not be used since this is a standalone executable. *This option only applies when signing with entitlements.*
|
||||
Default to the same entitlements file used for signing the app bundle.
|
||||
|
||||
`entitlementsForFile` - *Function*
|
||||
|
||||
Function that receives the path to a file and the current codesign arguments as parameters. If you wish to override the entitlements used for this file path this function should return the absolute path to a different entitlements file.
|
||||
| Option | Description | Usage Example |
|
||||
|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------|
|
||||
| `entitlements` | String specifying the path to an `entitlements.plist` file. Will default to built-in entitlements files. Can also be an array of entitlement keys that osx-sign will write to an entitlements file for you. | `'path/to/entitlements'` |
|
||||
| `hardenedRuntime` | Boolean flag to enable the Hardened Runtime when signing the app. Enabled by default. | `false` |
|
||||
| `requirements` | String specifying the [requirements](https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html) that you recommend to be used to evaluate the code signature. | `'anchor apple or anchor = "/var/db/yourcorporateanchor.cert"'` |
|
||||
| `signatureFlags` | List of [code signature flags](https://developer.apple.com/documentation/security/seccodesignatureflags?language=objc). Accepts an array of strings or a comma-separated string. | `['kSecCodeSignatureRestrict']` |
|
||||
| `timestamp` | String specifying the URL of the timestamp authority server. Defaults to the server provided by Apple. Please note that this default server may not support signatures not furnished by Apple. Disable the timestamp service with `none`. | `'https://different.timeserver'` |
|
||||
|
||||
**Note:** Only available via the JS API
|
||||
|
||||
`gatekeeper-assess` - *Boolean*
|
||||
|
||||
Flag to enable/disable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates.
|
||||
Gatekeeper assessment is enabled by default on `darwin` platform.
|
||||
Default to `true`.
|
||||
|
||||
`hardenedRuntime` or `hardened-runtime` - *Boolean*
|
||||
|
||||
Flag to enable the Mojave hardened runtime when signing the app. Disabled by default, requires Xcode >= 10 and
|
||||
|
@ -191,7 +175,7 @@ Default to be selected with respect to `provisioning-profile` and `platform` fro
|
|||
|
||||
Signing platform `mas` will look for `3rd Party Mac Developer Application: * (*)`, and platform `darwin` will look for `Developer ID Application: * (*)` by default.
|
||||
|
||||
`identity-validation` - *Boolean*
|
||||
`identityValidation` - *Boolean*
|
||||
|
||||
Flag to enable/disable validation for the signing identity. If enabled, the `identity` provided will be validated in the `keychain` specified.
|
||||
Default to `true`.
|
||||
|
@ -213,49 +197,27 @@ Build platform of Electron.
|
|||
Allowed values: `darwin`, `mas`.
|
||||
Default to auto detect by presence of `Squirrel.framework` within the application bundle.
|
||||
|
||||
`pre-auto-entitlements` - *Boolean*
|
||||
`preAutoEntitlements` - *Boolean*
|
||||
|
||||
Flag to enable/disable automation of `com.apple.security.application-groups` in entitlements file and update `Info.plist` with `ElectronTeamID`.
|
||||
Default to `true`.
|
||||
|
||||
`pre-embed-provisioning-profile` - *Boolean*
|
||||
`preEmbedProvisioningProfile` - *Boolean*
|
||||
|
||||
Flag to enable/disable embedding of provisioning profile in the current working directory.
|
||||
Default to `true`.
|
||||
|
||||
`provisioning-profile` - *String*
|
||||
`provisioningProfile` - *String*
|
||||
|
||||
Path to provisioning profile.
|
||||
|
||||
`requirements` - *String*
|
||||
|
||||
Specify the criteria that you recommend to be used to evaluate the code signature.
|
||||
See more info from https://developer.apple.com/library/mac/documentation/Security/Conceptual/CodeSigningGuide/RequirementLang/RequirementLang.html
|
||||
Default to `undefined`.
|
||||
|
||||
`restrict` - *Boolean*
|
||||
|
||||
**To be deprecated, see `signature-flags`.**
|
||||
Restrict dyld loading. See doc about this [code signature flag](https://developer.apple.com/documentation/security/seccodesignatureflags/kseccodesignaturerestrict?language=objc) for more details. Disabled by default.
|
||||
|
||||
`signature-flags` - *String*
|
||||
Comma separated string or array for [code signature flag](https://developer.apple.com/documentation/security/seccodesignatureflags?language=objc). Default to `undefined`.
|
||||
|
||||
`signature-size` - *Number*
|
||||
Provide a value to be passed to `codesign` along with the `--signature-size` flag, to work around the *signature too large to embed* issue. A value of `12000` should do it - see the [FAQ](https://github.com/electron/electron-osx-sign/wiki/FAQ) for details. Default to `undefined`.
|
||||
|
||||
`strict-verify` - *Boolean|String|Array.<String>*
|
||||
`strictVerify` - *Boolean|String|Array.<String>*
|
||||
|
||||
Flag to enable/disable `--strict` flag when verifying the signed application bundle.
|
||||
If provided as a string, each component should be separated with comma (`,`).
|
||||
If provided as an array, each item should be a string corresponding to a component.
|
||||
Default to `true`.
|
||||
|
||||
`timestamp` - *String*
|
||||
|
||||
Specify the URL of the timestamp authority server, default to server provided by Apple. Please note that this default server may not support signatures not furnished by Apple.
|
||||
Disable the timestamp service with `none`.
|
||||
|
||||
`type` - *String*
|
||||
|
||||
Specify whether to sign app for development or for distribution.
|
||||
|
@ -354,7 +316,7 @@ Default to be selected with respect to `platform` from `keychain` or keychain by
|
|||
|
||||
Flattening platform `mas` will look for `3rd Party Mac Developer Installer: * (*)`, and platform `darwin` will look for `Developer ID Installer: * (*)` by default.
|
||||
|
||||
`identity-validation` - *Boolean*
|
||||
`identityValidation` - *Boolean*
|
||||
|
||||
Flag to enable/disable validation for signing identity. If enabled, the `identity` provided will be validated in the `keychain` specified.
|
||||
Default to `true`.
|
||||
|
|
|
@ -17,7 +17,7 @@ DESCRIPTION
|
|||
Name of certificate to use when signing.
|
||||
Default to selected with respect to --platform from --keychain specified or keychain by system default.
|
||||
|
||||
--identity-validation, --no-identity-validation
|
||||
--identityValidation, --no-identityValidation
|
||||
Flag to enable/disable validation for the signing identity.
|
||||
|
||||
--install=install-path
|
||||
|
|
|
@ -13,26 +13,6 @@ DESCRIPTION
|
|||
embedded-binary ...
|
||||
Path to additional binaries that will be signed along with built-ins of Electron, spaced.
|
||||
|
||||
--entitlements=file
|
||||
Path to entitlements file for signing the app.
|
||||
Default to built-in entitlements file, Sandbox enabled for Mac App Store platform.
|
||||
|
||||
--entitlements-inherit=file
|
||||
Path to child entitlements which inherit the security settings for signing frameworks and bundles of a distribution.
|
||||
This option only applies when signing with entitlements.
|
||||
|
||||
--entitlements-loginhelper=file
|
||||
Path to login helper entitlement file. When using App Sandbox, the inherited entitlement should not be used since this is a standalone executable.
|
||||
This option only applies when signing with entitlements.
|
||||
|
||||
--gatekeeper-assess, --no-gatekeeper-assess
|
||||
Flag to enable/disable Gatekeeper assessment after signing the app. Disabling it is useful for signing with self-signed certificates.
|
||||
Gatekeeper assessment is enabled by default on ``darwin'' platform.
|
||||
|
||||
--hardened-runtime
|
||||
Flag to enable the Mojave hardened runtime when signing the app. Disabled by default, requires Xcode >= 10 and macOS
|
||||
>= 10.13.6.
|
||||
|
||||
--help
|
||||
Flag to display all commands.
|
||||
|
||||
|
@ -40,7 +20,7 @@ DESCRIPTION
|
|||
Name of certificate to use when signing.
|
||||
Default to selected with respect to --provisioning-profile and --platform from --keychain specified or keychain by system default.
|
||||
|
||||
--identity-validation, --no-identity-validation
|
||||
--identityValidation, --no-identityValidation
|
||||
Flag to enable/disable validation for the signing identity.
|
||||
|
||||
--ignore=path
|
||||
|
@ -64,28 +44,11 @@ DESCRIPTION
|
|||
--provisioning-profile=file
|
||||
Path to provisioning profile.
|
||||
|
||||
--requirements=requirements
|
||||
Specify the criteria that you recommend to be used to evaluate the code signature.
|
||||
|
||||
--restrict
|
||||
(This will be deprecated soon, see --sign-flags.)
|
||||
Flag to enable restrict mode. Disabled by default.
|
||||
|
||||
--signature-flags=flags
|
||||
Code signature flags. Default to none.
|
||||
|
||||
--signature-size=size
|
||||
Signature size. Default to none.
|
||||
|
||||
--strict-verify, --strict-verify=options, --no-strict-verify
|
||||
--strictVerify, --strictVerify=options, --no-strictVerify
|
||||
Flag to enable/disable ``--strict'' flag when verifying the signed application bundle.
|
||||
Each component should be separated in ``options'' with comma (``,'').
|
||||
Enabled by default.
|
||||
|
||||
--timestamp=timestamp
|
||||
Specify the URL of the timestamp authority server, default to server provided by Apple.
|
||||
Disable the timestamp service with ``none''.
|
||||
|
||||
--type=type
|
||||
Specify whether to sign app for development or for distribution.
|
||||
Allowed values: ``development'', ``distribution''.
|
||||
|
|
|
@ -6,21 +6,16 @@ const args = require('minimist')(process.argv.slice(2), {
|
|||
string: [
|
||||
'signature-flags'
|
||||
],
|
||||
number: [
|
||||
'signature-size'
|
||||
],
|
||||
boolean: [
|
||||
'help',
|
||||
'pre-auto-entitlements',
|
||||
'pre-embed-provisioning-profile',
|
||||
'gatekeeper-assess',
|
||||
'hardened-runtime',
|
||||
'restrict'
|
||||
],
|
||||
default: {
|
||||
'pre-auto-entitlements': true,
|
||||
'pre-embed-provisioning-profile': true,
|
||||
'gatekeeper-assess': true
|
||||
'pre-embed-provisioning-profile': true
|
||||
}
|
||||
});
|
||||
const usage = fs.readFileSync(path.join(__dirname, 'electron-osx-sign-usage.txt')).toString();
|
||||
|
|
2
entitlements/default.entitlements.mas.plist → entitlements/default.darwin.gpu.plist
Executable file → Normal file
2
entitlements/default.entitlements.mas.plist → entitlements/default.darwin.gpu.plist
Executable file → Normal file
|
@ -2,7 +2,7 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.audio-input</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.bluetooth</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.print</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.usb</key>
|
||||
<true/>
|
||||
<key>com.apple.security.personal-information.location</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -2,5 +2,9 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
|
||||
<true/>
|
||||
<key>com.apple.security.cs.disable-library-validation</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -2,5 +2,7 @@
|
|||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.cs.allow-jit</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>com.apple.security.app-sandbox</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.user-selected.read-write</key>
|
||||
<true/>
|
||||
<key>com.apple.security.files.bookmarks.app-scope</key>
|
||||
<true/>
|
||||
<key>com.apple.security.network.client</key>
|
||||
<true/>
|
||||
<key>com.apple.security.print</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.camera</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.microphone</key>
|
||||
<true/>
|
||||
<key>com.apple.security.device.usb</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,43 +0,0 @@
|
|||
declare module "electron-osx-sign" {
|
||||
interface BaseSignOptions {
|
||||
app: string;
|
||||
identity?: string;
|
||||
platform?: string;
|
||||
keychain?: string;
|
||||
}
|
||||
|
||||
interface SignOptions extends BaseSignOptions {
|
||||
binaries?: string[];
|
||||
entitlements?: string;
|
||||
'entitlements-inherit'?: string;
|
||||
'entitlements-loginhelper'?: string;
|
||||
'gatekeeper-assess'?: boolean;
|
||||
hardenedRuntime?: boolean;
|
||||
'identity-validation'?: boolean;
|
||||
ignore?: string | ((file: string) => boolean);
|
||||
'pre-auto-entitlements'?: boolean;
|
||||
'pre-embed-provisioning-profile'?: boolean;
|
||||
'provisioning-profile'?: string;
|
||||
'requirements'?: string;
|
||||
'signature-flags'?: string | ((file: string) => string[]);
|
||||
'signature-size'?: number;
|
||||
'type'?: string;
|
||||
version?: string;
|
||||
entitlementsForFile?: (file: string, codeSignArgs: string[]) => string | null;
|
||||
}
|
||||
|
||||
export function sign(opts: SignOptions, callback: (error: Error) => void): void;
|
||||
|
||||
export function signAsync(opts: SignOptions): Promise<any>;
|
||||
|
||||
interface FlatOptions extends BaseSignOptions {
|
||||
'identity-validation'?: boolean;
|
||||
install?: string;
|
||||
pkg?: string;
|
||||
scripts?: string;
|
||||
}
|
||||
|
||||
export function flat(opts: FlatOptions, callback: (error: Error) => void): void;
|
||||
|
||||
export function flatAsync(opts: FlatOptions): Promise<any>;
|
||||
}
|
|
@ -69,6 +69,6 @@
|
|||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=4.0.0"
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ export async function buildPkg (_opts: FlatOptions) {
|
|||
|
||||
if (validatedOptions.identity) {
|
||||
debugLog('`identity` passed in arguments.');
|
||||
if (validatedOptions['identity-validation'] === false) {
|
||||
if (validatedOptions.identityValidation === false) {
|
||||
// Do nothing
|
||||
} else {
|
||||
identities = await findIdentities(validatedOptions.keychain || null, validatedOptions.identity);
|
||||
|
|
437
src/sign.ts
437
src/sign.ts
|
@ -1,5 +1,7 @@
|
|||
import * as fs from 'fs-extra';
|
||||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as plist from 'plist';
|
||||
import compareVersion from 'compare-version';
|
||||
|
||||
import {
|
||||
|
@ -12,12 +14,9 @@ import {
|
|||
walkAsync
|
||||
} from './util';
|
||||
import { Identity, findIdentities } from './util-identities';
|
||||
import {
|
||||
preEmbedProvisioningProfile,
|
||||
getProvisioningProfile
|
||||
} from './util-provisioning-profiles';
|
||||
import { preEmbedProvisioningProfile, getProvisioningProfile } from './util-provisioning-profiles';
|
||||
import { preAutoEntitlements } from './util-entitlements';
|
||||
import { ElectronMacPlatform, SignOptions, ValidatedSignOptions } from './types';
|
||||
import { ElectronMacPlatform, PerFileSignOptions, SignOptions, ValidatedSignOptions } from './types';
|
||||
|
||||
const pkgVersion: string = require('../../package.json').version;
|
||||
|
||||
|
@ -41,85 +40,6 @@ function validateOptsIgnore (ignore: SignOptions['ignore']): ValidatedSignOption
|
|||
}
|
||||
}
|
||||
|
||||
function validateOptsEntitlements (opts: SignOptions, platform: ElectronMacPlatform) {
|
||||
const entitlementOptions = {
|
||||
entitlements: opts.entitlements,
|
||||
'entitlements-inherit': opts['entitlements-inherit']
|
||||
};
|
||||
|
||||
const entitlementsFolder = path.resolve(__dirname, '..', '..', 'entitlements');
|
||||
|
||||
if (platform === 'mas') {
|
||||
// To sign apps for Mac App Store, an entitlements file is required, especially for app sandboxing (as well some other services).
|
||||
// Fallback entitlements for sandboxing by default: Note this may cause troubles while running an signed app due to missing keys special to the project.
|
||||
// Further reading: https://developer.apple.com/library/mac/documentation/Miscellaneous/Reference/EntitlementKeyReference/Chapters/EnablingAppSandbox.html
|
||||
if (!entitlementOptions.entitlements) {
|
||||
const entitlementsPath = path.resolve(entitlementsFolder, 'default.entitlements.mas.plist');
|
||||
debugWarn(
|
||||
'No `entitlements` passed in arguments:',
|
||||
'\n',
|
||||
'* Sandbox entitlements are required for Mac App Store distribution, your codesign entitlements file is default to:',
|
||||
entitlementsPath
|
||||
);
|
||||
entitlementOptions.entitlements = entitlementsPath;
|
||||
}
|
||||
if (!entitlementOptions['entitlements-inherit']) {
|
||||
const entitlementsPath = path.join(
|
||||
entitlementsFolder,
|
||||
'default.entitlements.mas.inherit.plist'
|
||||
);
|
||||
debugWarn(
|
||||
'No `entitlements-inherit` passed in arguments:',
|
||||
'\n',
|
||||
'* Sandbox entitlements file for enclosed app files is default to:',
|
||||
entitlementsPath
|
||||
);
|
||||
entitlementOptions['entitlements-inherit'] = entitlementsPath;
|
||||
}
|
||||
} else {
|
||||
// Not necessary to have entitlements for non Mac App Store distribution
|
||||
if (!opts.entitlements) {
|
||||
debugWarn(
|
||||
'No `entitlements` passed in arguments:',
|
||||
'\n',
|
||||
'* Provide `entitlements` to specify entitlements file for codesign.'
|
||||
);
|
||||
} else {
|
||||
// If entitlements is provided as a boolean flag, fallback to default
|
||||
if ((entitlementOptions.entitlements as any) === true) {
|
||||
const entitlementsPath = path.join(entitlementsFolder, 'default.entitlements.darwin.plist');
|
||||
debugWarn(
|
||||
'`entitlements` not specified in arguments:',
|
||||
'\n',
|
||||
'* Provide `entitlements` to specify entitlements file for codesign.',
|
||||
'\n',
|
||||
'* Entitlements file is default to:',
|
||||
entitlementsPath
|
||||
);
|
||||
entitlementOptions.entitlements = entitlementsPath;
|
||||
}
|
||||
if (!opts['entitlements-inherit']) {
|
||||
const entitlementsPath = path.join(
|
||||
entitlementsFolder,
|
||||
'default.entitlements.darwin.inherit.plist'
|
||||
);
|
||||
debugWarn(
|
||||
'No `entitlements-inherit` passed in arguments:',
|
||||
'\n',
|
||||
'* Entitlements file for enclosed app files is default to:',
|
||||
entitlementsPath
|
||||
);
|
||||
entitlementOptions['entitlements-inherit'] = entitlementsPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return entitlementOptions as {
|
||||
entitlements: string;
|
||||
'entitlements-inherit': string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* This function returns a promise validating all options passed in opts.
|
||||
*/
|
||||
|
@ -127,7 +47,7 @@ async function validateSignOpts (opts: SignOptions): Promise<Readonly<ValidatedS
|
|||
await validateOptsBinaries(opts);
|
||||
await validateOptsApp(opts);
|
||||
|
||||
if (opts['provisioning-profile'] && typeof opts['provisioning-profile'] !== 'string') {
|
||||
if (opts.provisioningProfile && typeof opts.provisioningProfile !== 'string') {
|
||||
throw new Error('Path to provisioning profile should be a string.');
|
||||
}
|
||||
|
||||
|
@ -138,7 +58,6 @@ async function validateSignOpts (opts: SignOptions): Promise<Readonly<ValidatedS
|
|||
const platform = await validateOptsPlatform(opts);
|
||||
const cloned: ValidatedSignOptions = {
|
||||
...opts,
|
||||
...validateOptsEntitlements(opts, platform),
|
||||
ignore: validateOptsIgnore(opts.ignore),
|
||||
type: opts.type || 'distribution',
|
||||
platform
|
||||
|
@ -156,31 +75,90 @@ async function verifySignApplication (opts: ValidatedSignOptions) {
|
|||
await execFileAsync(
|
||||
'codesign',
|
||||
['--verify', '--deep'].concat(
|
||||
opts['strict-verify'] !== false && compareVersion(osRelease, '15.0.0') >= 0 // Strict flag since darwin 15.0.0 --> OS X 10.11.0 El Capitan
|
||||
opts.strictVerify !== false && compareVersion(osRelease, '15.0.0') >= 0 // Strict flag since darwin 15.0.0 --> OS X 10.11.0 El Capitan
|
||||
? [
|
||||
'--strict' +
|
||||
(opts['strict-verify']
|
||||
? '=' + opts['strict-verify'] // Array should be converted to a comma separated string
|
||||
(opts.strictVerify
|
||||
? '=' + opts.strictVerify // Array should be converted to a comma separated string
|
||||
: '')
|
||||
]
|
||||
: [],
|
||||
['--verbose=2', opts.app]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// Additionally test Gatekeeper acceptance for darwin platform
|
||||
if (opts.platform === 'darwin' && opts['gatekeeper-assess'] !== false) {
|
||||
debugLog('Verifying Gatekeeper acceptance for darwin platform...');
|
||||
await execFileAsync('spctl', [
|
||||
'--assess',
|
||||
'--type',
|
||||
'execute',
|
||||
'--verbose',
|
||||
'--ignore-cache',
|
||||
'--no-cache',
|
||||
opts.app
|
||||
]);
|
||||
function defaultOptionsForFile (filePath: string, platform: ElectronMacPlatform) {
|
||||
const entitlementsFolder = path.resolve(__dirname, '..', '..', 'entitlements');
|
||||
|
||||
let entitlementsFile: string;
|
||||
if (platform === 'darwin') {
|
||||
// Default Entitlements
|
||||
// c.f. https://source.chromium.org/chromium/chromium/src/+/main:chrome/app/app-entitlements.plist
|
||||
// Also include JIT for main process V8
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.darwin.plist');
|
||||
// Plugin helper
|
||||
// c.f. https://source.chromium.org/chromium/chromium/src/+/main:chrome/app/helper-plugin-entitlements.plist
|
||||
if (filePath.includes('(Plugin).app')) {
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.darwin.plugin.plist');
|
||||
// GPU Helper
|
||||
// c.f. https://source.chromium.org/chromium/chromium/src/+/main:chrome/app/helper-gpu-entitlements.plist
|
||||
} else if (filePath.includes('(GPU).app')) {
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.darwin.gpu.plist');
|
||||
// Renderer Helper
|
||||
// c.f. https://source.chromium.org/chromium/chromium/src/+/main:chrome/app/helper-renderer-entitlements.plist
|
||||
} else if (filePath.includes('(Renderer).app')) {
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.darwin.renderer.plist');
|
||||
}
|
||||
} else {
|
||||
// Default entitlements
|
||||
// TODO: Can these be more scoped like the non-mas variant?
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.mas.plist');
|
||||
|
||||
// If it is not the top level app bundle, we sign with inherit
|
||||
if (filePath.includes('.app/')) {
|
||||
entitlementsFile = path.resolve(entitlementsFolder, 'default.mas.child.plist');
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
entitlements: entitlementsFile,
|
||||
hardenedRuntime: true,
|
||||
requirements: undefined as string | undefined,
|
||||
signatureFlags: undefined as string | string[] | undefined,
|
||||
timestamp: undefined as string | undefined
|
||||
};
|
||||
}
|
||||
|
||||
async function mergeOptionsForFile (
|
||||
opts: PerFileSignOptions | null,
|
||||
defaults: ReturnType<typeof defaultOptionsForFile>
|
||||
) {
|
||||
const mergedPerFileOptions = { ...defaults };
|
||||
if (opts) {
|
||||
if (opts.entitlements !== undefined) {
|
||||
if (Array.isArray(opts.entitlements)) {
|
||||
const entitlements = opts.entitlements.reduce<Record<string, any>>((dict, entitlementKey) => ({
|
||||
...dict,
|
||||
[entitlementKey]: true
|
||||
}), {});
|
||||
const dir = await fs.mkdtemp(path.resolve(os.tmpdir(), 'tmp-entitlements-'));
|
||||
const entitlementsPath = path.join(dir, 'entitlements.plist');
|
||||
await fs.writeFile(entitlementsPath, plist.build(entitlements), 'utf8');
|
||||
opts.entitlements = entitlementsPath;
|
||||
}
|
||||
mergedPerFileOptions.entitlements = opts.entitlements;
|
||||
}
|
||||
if (opts.hardenedRuntime !== undefined) {
|
||||
mergedPerFileOptions.hardenedRuntime = opts.hardenedRuntime;
|
||||
}
|
||||
if (opts.requirements !== undefined) mergedPerFileOptions.requirements = opts.requirements;
|
||||
if (opts.signatureFlags !== undefined) {
|
||||
mergedPerFileOptions.signatureFlags = opts.signatureFlags;
|
||||
}
|
||||
if (opts.timestamp !== undefined) mergedPerFileOptions.timestamp = opts.timestamp;
|
||||
}
|
||||
return mergedPerFileOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -207,23 +185,6 @@ async function signApplication (opts: ValidatedSignOptions, identity: Identity)
|
|||
if (opts.keychain) {
|
||||
args.push('--keychain', opts.keychain);
|
||||
}
|
||||
if (opts.requirements) {
|
||||
args.push('--requirements', opts.requirements);
|
||||
}
|
||||
if (opts.timestamp) {
|
||||
args.push('--timestamp=' + opts.timestamp);
|
||||
} else {
|
||||
args.push('--timestamp');
|
||||
}
|
||||
if (opts['signature-size']) {
|
||||
if (Number.isInteger(opts['signature-size']) && opts['signature-size'] > 0) {
|
||||
args.push('--signature-size', `${opts['signature-size']}`);
|
||||
} else {
|
||||
debugWarn(
|
||||
`Invalid value provided for --signature-size (${opts['signature-size']}). Must be a positive integer.`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the child paths by how deep they are in the file tree. Some arcane apple
|
||||
|
@ -235,105 +196,90 @@ async function signApplication (opts: ValidatedSignOptions, identity: Identity)
|
|||
const bDepth = b.split(path.sep).length;
|
||||
return bDepth - aDepth;
|
||||
});
|
||||
if (opts.entitlements) {
|
||||
// Sign with entitlements
|
||||
// promise = Promise.mapSeries(childPaths, function (filePath) {
|
||||
for (const filePath of children) {
|
||||
if (shouldIgnoreFilePath(filePath)) {
|
||||
debugLog('Skipped... ' + filePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
debugLog('Signing... ' + filePath);
|
||||
|
||||
let optionsArguments: string[] = [];
|
||||
|
||||
if (opts['signature-flags']) {
|
||||
if (Array.isArray(opts['signature-flags'])) {
|
||||
optionsArguments.push(...opts['signature-flags']);
|
||||
} else if (typeof opts['signature-flags'] === 'function') {
|
||||
const flags = opts['signature-flags'](filePath);
|
||||
optionsArguments.push(...flags);
|
||||
} else {
|
||||
const flags = opts['signature-flags'].split(',').map(function (flag) {
|
||||
return flag.trim();
|
||||
});
|
||||
optionsArguments.push(...flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
opts.hardenedRuntime ||
|
||||
opts['hardened-runtime'] ||
|
||||
optionsArguments.includes('runtime')
|
||||
) {
|
||||
// Hardened runtime since darwin 17.7.0 --> macOS 10.13.6
|
||||
if (compareVersion(osRelease, '17.7.0') >= 0) {
|
||||
optionsArguments.push('runtime');
|
||||
} else {
|
||||
// Remove runtime if passed in with --signature-flags
|
||||
debugLog(
|
||||
'Not enabling hardened runtime, current macOS version too low, requires 10.13.6 and higher'
|
||||
);
|
||||
optionsArguments = optionsArguments.filter((arg) => {
|
||||
return arg !== 'runtime';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (opts.restrict) {
|
||||
optionsArguments.push('restrict');
|
||||
debugWarn(
|
||||
'This flag is to be deprecated, consider using --signature-flags=restrict instead'
|
||||
);
|
||||
}
|
||||
|
||||
if (optionsArguments.length) {
|
||||
args.push('--options', [...new Set(optionsArguments)].join(','));
|
||||
}
|
||||
|
||||
let entitlementsFile = opts['entitlements-inherit'];
|
||||
if (filePath.includes('Library/LoginItems')) {
|
||||
entitlementsFile = opts['entitlements-loginhelper']!;
|
||||
}
|
||||
|
||||
const clonedArgs = args.concat([]);
|
||||
if (opts.entitlementsForFile) {
|
||||
entitlementsFile = opts.entitlementsForFile(filePath, clonedArgs) || entitlementsFile;
|
||||
}
|
||||
|
||||
await execFileAsync(
|
||||
'codesign',
|
||||
clonedArgs.concat('--entitlements', entitlementsFile, filePath)
|
||||
);
|
||||
for (const filePath of [...children, opts.app]) {
|
||||
if (shouldIgnoreFilePath(filePath)) {
|
||||
debugLog('Skipped... ' + filePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sign the actual app now
|
||||
debugLog('Signing... ' + opts.app);
|
||||
const perFileOptions = await mergeOptionsForFile(
|
||||
opts.optionsForFile ? opts.optionsForFile(filePath) : null,
|
||||
defaultOptionsForFile(filePath, opts.platform)
|
||||
);
|
||||
|
||||
const clonedArgs = args.concat([]);
|
||||
let entitlementsFile = opts.entitlements;
|
||||
if (opts.entitlementsForFile) {
|
||||
entitlementsFile = opts.entitlementsForFile(opts.app, clonedArgs) || entitlementsFile;
|
||||
if (opts.preAutoEntitlements === false) {
|
||||
debugWarn('Pre-sign operation disabled for entitlements automation.');
|
||||
} else {
|
||||
debugLog(
|
||||
'Pre-sign operation enabled for entitlements automation with versions >= `1.1.1`:',
|
||||
'\n',
|
||||
'* Disable by setting `pre-auto-entitlements` to `false`.'
|
||||
);
|
||||
if (!opts.version || compareVersion(opts.version, '1.1.1') >= 0) {
|
||||
// Enable Mac App Store sandboxing without using temporary-exception, introduced in Electron v1.1.1. Relates to electron#5601
|
||||
const newEntitlements = await preAutoEntitlements(opts, perFileOptions, {
|
||||
identity,
|
||||
provisioningProfile: opts.provisioningProfile
|
||||
? await getProvisioningProfile(opts.provisioningProfile, opts.keychain)
|
||||
: undefined
|
||||
});
|
||||
|
||||
// preAutoEntitlements may provide us new entitlements, if so we update our options
|
||||
// and ensure that entitlements-loginhelper has a correct default value
|
||||
if (newEntitlements) {
|
||||
perFileOptions.entitlements = newEntitlements;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugLog('Signing... ' + filePath);
|
||||
|
||||
if (perFileOptions.requirements) {
|
||||
args.push('--requirements', perFileOptions.requirements);
|
||||
}
|
||||
if (perFileOptions.timestamp) {
|
||||
args.push('--timestamp=' + perFileOptions.timestamp);
|
||||
} else {
|
||||
args.push('--timestamp');
|
||||
}
|
||||
|
||||
let optionsArguments: string[] = [];
|
||||
|
||||
if (perFileOptions.signatureFlags) {
|
||||
if (Array.isArray(perFileOptions.signatureFlags)) {
|
||||
optionsArguments.push(...perFileOptions.signatureFlags);
|
||||
} else {
|
||||
const flags = perFileOptions.signatureFlags.split(',').map(function (flag) {
|
||||
return flag.trim();
|
||||
});
|
||||
optionsArguments.push(...flags);
|
||||
}
|
||||
}
|
||||
|
||||
if (perFileOptions.hardenedRuntime || optionsArguments.includes('runtime')) {
|
||||
// Hardened runtime since darwin 17.7.0 --> macOS 10.13.6
|
||||
if (compareVersion(osRelease, '17.7.0') >= 0) {
|
||||
optionsArguments.push('runtime');
|
||||
} else {
|
||||
// Remove runtime if passed in with --signature-flags
|
||||
debugLog(
|
||||
'Not enabling hardened runtime, current macOS version too low, requires 10.13.6 and higher'
|
||||
);
|
||||
optionsArguments = optionsArguments.filter((arg) => {
|
||||
return arg !== 'runtime';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (optionsArguments.length) {
|
||||
args.push('--options', [...new Set(optionsArguments)].join(','));
|
||||
}
|
||||
|
||||
await execFileAsync(
|
||||
'codesign',
|
||||
clonedArgs.concat('--entitlements', entitlementsFile, opts.app)
|
||||
args.concat('--entitlements', perFileOptions.entitlements, filePath)
|
||||
);
|
||||
} else {
|
||||
// Otherwise normally
|
||||
for (const filePath of children) {
|
||||
if (shouldIgnoreFilePath(filePath)) {
|
||||
debugLog('Skipped... ' + filePath);
|
||||
continue;
|
||||
}
|
||||
|
||||
await execFileAsync('codesign', args.concat(filePath));
|
||||
}
|
||||
|
||||
debugLog('Signing... ' + opts.app);
|
||||
await execFileAsync('codesign', args.concat(opts.app));
|
||||
}
|
||||
|
||||
// Verify code sign
|
||||
|
@ -342,17 +288,15 @@ async function signApplication (opts: ValidatedSignOptions, identity: Identity)
|
|||
debugLog('Verified.');
|
||||
|
||||
// Check entitlements if applicable
|
||||
if (opts.entitlements) {
|
||||
debugLog('Displaying entitlements...');
|
||||
const result = await execFileAsync('codesign', [
|
||||
'--display',
|
||||
'--entitlements',
|
||||
':-', // Write to standard output and strip off the blob header
|
||||
opts.app
|
||||
]);
|
||||
debugLog('Displaying entitlements...');
|
||||
const result = await execFileAsync('codesign', [
|
||||
'--display',
|
||||
'--entitlements',
|
||||
':-', // Write to standard output and strip off the blob header
|
||||
opts.app
|
||||
]);
|
||||
|
||||
debugLog('Entitlements:', '\n', result);
|
||||
}
|
||||
debugLog('Entitlements:', '\n', result);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -360,14 +304,14 @@ async function signApplication (opts: ValidatedSignOptions, identity: Identity)
|
|||
*/
|
||||
export async function signApp (_opts: SignOptions) {
|
||||
debugLog('electron-osx-sign@%s', pkgVersion);
|
||||
let validatedOpts = await validateSignOpts(_opts);
|
||||
const validatedOpts = await validateSignOpts(_opts);
|
||||
let identities: Identity[] = [];
|
||||
let identityInUse: Identity | null = null;
|
||||
|
||||
// Determine identity for signing
|
||||
if (validatedOpts.identity) {
|
||||
debugLog('`identity` passed in arguments.');
|
||||
if (validatedOpts['identity-validation'] === false) {
|
||||
if (validatedOpts.identityValidation === false) {
|
||||
identityInUse = new Identity(validatedOpts.identity);
|
||||
} else {
|
||||
identities = await findIdentities(validatedOpts.keychain || null, validatedOpts.identity);
|
||||
|
@ -416,7 +360,7 @@ export async function signApp (_opts: SignOptions) {
|
|||
}
|
||||
|
||||
// Pre-sign operations
|
||||
if (validatedOpts['pre-embed-provisioning-profile'] === false) {
|
||||
if (validatedOpts.preEmbedProvisioningProfile === false) {
|
||||
debugWarn(
|
||||
'Pre-sign operation disabled for provisioning profile embedding:',
|
||||
'\n',
|
||||
|
@ -430,50 +374,12 @@ export async function signApp (_opts: SignOptions) {
|
|||
);
|
||||
await preEmbedProvisioningProfile(
|
||||
validatedOpts,
|
||||
validatedOpts['provisioning-profile']
|
||||
? await getProvisioningProfile(
|
||||
validatedOpts['provisioning-profile'],
|
||||
validatedOpts.keychain
|
||||
)
|
||||
validatedOpts.provisioningProfile
|
||||
? await getProvisioningProfile(validatedOpts.provisioningProfile, validatedOpts.keychain)
|
||||
: null
|
||||
);
|
||||
}
|
||||
|
||||
if (validatedOpts['pre-auto-entitlements'] === false) {
|
||||
debugWarn('Pre-sign operation disabled for entitlements automation.');
|
||||
} else {
|
||||
debugLog(
|
||||
'Pre-sign operation enabled for entitlements automation with versions >= `1.1.1`:',
|
||||
'\n',
|
||||
'* Disable by setting `pre-auto-entitlements` to `false`.'
|
||||
);
|
||||
if (
|
||||
validatedOpts.entitlements &&
|
||||
(!validatedOpts.version || compareVersion(validatedOpts.version, '1.1.1') >= 0)
|
||||
) {
|
||||
// Enable Mac App Store sandboxing without using temporary-exception, introduced in Electron v1.1.1. Relates to electron#5601
|
||||
const newEntitlements = await preAutoEntitlements(validatedOpts, {
|
||||
identity: identityInUse,
|
||||
provisioningProfile: validatedOpts['provisioning-profile']
|
||||
? await getProvisioningProfile(
|
||||
validatedOpts['provisioning-profile'],
|
||||
validatedOpts.keychain
|
||||
)
|
||||
: undefined
|
||||
});
|
||||
|
||||
// preAutoEntitlements may provide us new entitlements, if so we update our options
|
||||
// and ensure that entitlements-loginhelper has a correct default value
|
||||
if (newEntitlements) {
|
||||
validatedOpts = {
|
||||
...validatedOpts,
|
||||
entitlements: newEntitlements,
|
||||
'entitlements-loginhelper': validatedOpts['entitlements-loginhelper'] || newEntitlements
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
debugLog(
|
||||
'Signing application...',
|
||||
'\n',
|
||||
|
@ -483,15 +389,6 @@ export async function signApp (_opts: SignOptions) {
|
|||
'> Platform:',
|
||||
validatedOpts.platform,
|
||||
'\n',
|
||||
'> Entitlements:',
|
||||
validatedOpts.entitlements,
|
||||
'\n',
|
||||
'> Child entitlements:',
|
||||
validatedOpts['entitlements-inherit'],
|
||||
'\n',
|
||||
'> Login helper entitlements:',
|
||||
validatedOpts['entitlements-loginhelper'],
|
||||
'\n',
|
||||
'> Additional binaries:',
|
||||
validatedOpts.binaries,
|
||||
'\n',
|
||||
|
|
56
src/types.ts
56
src/types.ts
|
@ -12,42 +12,56 @@ type OnlyValidatedBaseSignOptions = {
|
|||
platform: ElectronMacPlatform;
|
||||
};
|
||||
|
||||
type OnlySignOptions = {
|
||||
binaries?: string[];
|
||||
entitlements?: string;
|
||||
'entitlements-inherit'?: string;
|
||||
'entitlements-loginhelper'?: string;
|
||||
'gatekeeper-assess'?: boolean;
|
||||
/**
|
||||
* Any missing options will use the default values, providing a partial
|
||||
* structure will shallow merge with the default values.
|
||||
*/
|
||||
export type PerFileSignOptions = {
|
||||
/**
|
||||
* The entitlements file to use when signing this file
|
||||
*/
|
||||
entitlements?: string | string[];
|
||||
/**
|
||||
* Whether to enable hardened runtime for this file. Enabled by default.
|
||||
*/
|
||||
hardenedRuntime?: boolean;
|
||||
/**
|
||||
* @deprecated use hardenedRuntime instead
|
||||
* The designated requirements to embed when signing this file
|
||||
*/
|
||||
['hardened-runtime']?: boolean;
|
||||
'identity-validation'?: boolean;
|
||||
ignore?: string | string[] | ((file: string) => boolean);
|
||||
'pre-auto-entitlements'?: boolean;
|
||||
'pre-embed-provisioning-profile'?: boolean;
|
||||
'provisioning-profile'?: string;
|
||||
requirements?: string;
|
||||
restrict?: boolean;
|
||||
'signature-flags'?: string | ((file: string) => string[]);
|
||||
'signature-size'?: number;
|
||||
'strict-verify'?: boolean;
|
||||
/**
|
||||
* See --options of the "codesign" command.
|
||||
*
|
||||
* https://www.manpagez.com/man/1/codesign
|
||||
*/
|
||||
signatureFlags?: string | string[];
|
||||
/**
|
||||
* The timestamp server to use when signing, by default uses the Apple provided
|
||||
* timestamp server.
|
||||
*/
|
||||
timestamp?: string;
|
||||
}
|
||||
|
||||
type OnlySignOptions = {
|
||||
binaries?: string[];
|
||||
optionsForFile?: (filePath: string) => PerFileSignOptions;
|
||||
identityValidation?: boolean;
|
||||
ignore?: string | string[] | ((file: string) => boolean);
|
||||
preAutoEntitlements?: boolean;
|
||||
preEmbedProvisioningProfile?: boolean;
|
||||
provisioningProfile?: string;
|
||||
strictVerify?: boolean;
|
||||
type?: SigningDistributionType;
|
||||
version?: string;
|
||||
entitlementsForFile?: (file: string, codeSignArgs: string[]) => string | null;
|
||||
};
|
||||
|
||||
type OnlyValidatedSignOptions = {
|
||||
entitlements: string;
|
||||
'entitlements-inherit': string;
|
||||
ignore?: (string | ((file: string) => boolean))[];
|
||||
type: SigningDistributionType;
|
||||
};
|
||||
|
||||
type OnlyFlatOptions = {
|
||||
'identity-validation'?: boolean;
|
||||
identityValidation?: boolean;
|
||||
install?: string;
|
||||
pkg?: string;
|
||||
scripts?: string;
|
||||
|
|
|
@ -2,7 +2,7 @@ import * as fs from 'fs-extra';
|
|||
import * as os from 'os';
|
||||
import * as path from 'path';
|
||||
import * as plist from 'plist';
|
||||
import { ValidatedSignOptions } from './types';
|
||||
import { PerFileSignOptions, ValidatedSignOptions } from './types';
|
||||
import { debugLog, getAppContentsPath } from './util';
|
||||
import { Identity } from './util-identities';
|
||||
import { ProvisioningProfile } from './util-provisioning-profiles';
|
||||
|
@ -12,6 +12,8 @@ type ComputedOptions = {
|
|||
provisioningProfile?: ProvisioningProfile;
|
||||
};
|
||||
|
||||
const preAuthMemo = new Map<string, string>();
|
||||
|
||||
/**
|
||||
* This function returns a promise completing the entitlements automation: The
|
||||
* process includes checking in `Info.plist` for `ElectronTeamID` or setting
|
||||
|
@ -22,9 +24,13 @@ type ComputedOptions = {
|
|||
*/
|
||||
export async function preAutoEntitlements (
|
||||
opts: ValidatedSignOptions,
|
||||
perFileOpts: PerFileSignOptions,
|
||||
computed: ComputedOptions
|
||||
): Promise<void | string> {
|
||||
if (!opts.entitlements) return;
|
||||
if (!perFileOpts.entitlements) return;
|
||||
|
||||
const memoKey = [opts.app, perFileOpts.entitlements].join('---');
|
||||
if (preAuthMemo.has(memoKey)) return preAuthMemo.get(memoKey);
|
||||
|
||||
// If entitlements file not provided, default will be used. Fixes #41
|
||||
const appInfoPath = path.join(getAppContentsPath(opts), 'Info.plist');
|
||||
|
@ -34,12 +40,18 @@ export async function preAutoEntitlements (
|
|||
'\n',
|
||||
'> Info.plist:',
|
||||
appInfoPath,
|
||||
'\n',
|
||||
'> Entitlements:',
|
||||
opts.entitlements
|
||||
'\n'
|
||||
);
|
||||
const entitlementsContents = await fs.readFile(opts.entitlements, 'utf8');
|
||||
const entitlements = plist.parse(entitlementsContents) as Record<string, any>;
|
||||
let entitlements: Record<string, any>;
|
||||
if (typeof perFileOpts.entitlements === 'string') {
|
||||
const entitlementsContents = await fs.readFile(perFileOpts.entitlements, 'utf8');
|
||||
entitlements = plist.parse(entitlementsContents) as Record<string, any>;
|
||||
} else {
|
||||
entitlements = perFileOpts.entitlements.reduce<Record<string, any>>((dict, entitlementKey) => ({
|
||||
...dict,
|
||||
[entitlementKey]: true
|
||||
}), {});
|
||||
}
|
||||
if (!entitlements['com.apple.security.app-sandbox']) {
|
||||
// Only automate when app sandbox enabled by user
|
||||
return;
|
||||
|
@ -126,5 +138,6 @@ export async function preAutoEntitlements (
|
|||
await fs.writeFile(entitlementsPath, plist.build(entitlements), 'utf8');
|
||||
debugLog('Entitlements file updated:', '\n', '> Entitlements:', entitlementsPath);
|
||||
|
||||
preAuthMemo.set(memoKey, entitlementsPath);
|
||||
return entitlementsPath;
|
||||
}
|
||||
|
|
|
@ -11,8 +11,7 @@ function createDefaultsTest (release) {
|
|||
|
||||
const opts = {
|
||||
app: util.generateAppPath(release),
|
||||
identity: 'codesign.electronjs.org',
|
||||
'gatekeeper-assess': false
|
||||
identity: 'codesign.electronjs.org'
|
||||
}; // test with no other options for self discovery
|
||||
|
||||
waterfall(
|
||||
|
|
Загрузка…
Ссылка в новой задаче