Upload via GUI (7543 Dateien)
This commit is contained in:
+24
@@ -0,0 +1,24 @@
|
|||||||
|
Copyright (c) Electron contributors
|
||||||
|
Copyright (c) 2015-2016 Zhuo Lu, Jason Hinkle, et al.
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
this list of conditions and the following disclaimer in the documentation
|
||||||
|
and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
+282
@@ -0,0 +1,282 @@
|
|||||||
|
# @electron/osx-sign [![npm][npm_img]][npm_url] [![Test][gha_img]][gha_url]
|
||||||
|
|
||||||
|
Codesign Electron macOS apps
|
||||||
|
|
||||||
|
## About
|
||||||
|
|
||||||
|
[`@electron/osx-sign`][electron-osx-sign] minimizes the extra work needed to eventually prepare
|
||||||
|
your apps for shipping, providing options that work out of the box for most applications.
|
||||||
|
Additional configuration is available via its API.
|
||||||
|
|
||||||
|
There are two main functionalities exposed via this package:
|
||||||
|
* Signing macOS apps via `sign` functions. Under the hood, this uses the `codesign` utility.
|
||||||
|
* Creating `.pkg` installer packages via `flat` functions. Under the hood, this uses the `productbuild` utility.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
`@electron/osx-sign` is integrated into other Electron packaging tools, and can be configured accordingly:
|
||||||
|
* [Electron Packager](https://electron.github.io/packager/main/types/OsxSignOptions.html)
|
||||||
|
* [Electron Forge](https://www.electronforge.io/guides/code-signing/code-signing-macos)
|
||||||
|
|
||||||
|
You can also install `@electron/osx-sign` separately if your packaging pipeline does not involve those tools:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
npm install --save-dev @electron/osx-sign
|
||||||
|
```
|
||||||
|
|
||||||
|
## Code signing
|
||||||
|
|
||||||
|
The signing procedure implemented in this package is based on what described in Electron's [Code Signing Guide](https://github.com/electron/electron/blob/main/docs/tutorial/code-signing.md).
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
* You must be a registered member of the [Apple Developer Program](https://developer.apple.com/programs/).
|
||||||
|
Please note that you could be charged by Apple in order to get issued with the required certificates.
|
||||||
|
* You must have [Xcode](https://developer.apple.com/xcode/) installed from the
|
||||||
|
[Mac App Store](https://apps.apple.com/us/app/xcode/id497799835). It is not recommended to download your
|
||||||
|
copy from other 3rd party sources for security reasons.
|
||||||
|
* You must have Xcode Command Line Tools installed. To check whether it is available,
|
||||||
|
try `xcode-select --install` and follow the instructions.
|
||||||
|
* To distribute your app on the Mac App Store, You must create a Mac App on [App Store Connect](https://appstoreconnect.apple.com/).
|
||||||
|
* You must give your app a unique Bundle ID.
|
||||||
|
* You must give your app a version number.
|
||||||
|
|
||||||
|
### Certificates
|
||||||
|
|
||||||
|
In order to distribute your application either inside or outside the Mac App Store,
|
||||||
|
you will have to have the following certificates from Apple after becoming a registered developer.
|
||||||
|
|
||||||
|
Certificates can be created through the
|
||||||
|
[Certificates, Identities & Profiles](https://developer.apple.com/account/resources/certificates/add)
|
||||||
|
page in the Apple Developer website or via [Account Preferences in Xcode](https://help.apple.com/xcode/mac/current/#/dev3a05256b8).
|
||||||
|
|
||||||
|
For distribution inside the Mac App Store, you will need to create:
|
||||||
|
* Mac App Distribution: `3rd Party Mac Developer Application: * (*)`
|
||||||
|
* Mac Installer Distribution: `3rd Party Mac Developer Installer: * (*)`
|
||||||
|
|
||||||
|
For distribution outside the Mac App Store:
|
||||||
|
* Developer ID Application: `Developer ID Application: * (*)`
|
||||||
|
* Developer ID Installer: `Developer ID Installer: * (*)`
|
||||||
|
|
||||||
|
After you create the necessary certifications, download them and open each so that they are
|
||||||
|
installed in your keychain. We recommend installing them in your system default keychain so
|
||||||
|
that `@electron/osx-sign` can detect them automatically.
|
||||||
|
|
||||||
|
**Note:** They appear to come in pairs. It is preferred to have every one of them installed so not to
|
||||||
|
are about which is not yet installed for future works. However, if you may only want to distribute
|
||||||
|
outside the Mac App Store, there is no need to have the 3rd Party Mac Developer ones installed and vice versa.
|
||||||
|
|
||||||
|
### API
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { signAsync } = require('@electron/osx-sign')
|
||||||
|
const opts = {
|
||||||
|
app: 'path/to/my.app'
|
||||||
|
};
|
||||||
|
signAsync(opts)
|
||||||
|
.then(function () {
|
||||||
|
// Application signed
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
// Handle the error
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The only mandatory option for `signAsync` is a path to your `.app` package.
|
||||||
|
Configuration for most Electron apps should work out of the box.
|
||||||
|
For full configuration options, see the [API documentation].
|
||||||
|
|
||||||
|
### Usage examples
|
||||||
|
|
||||||
|
#### Signing for Mac App Store distribution
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { signAsync } = require('@electron/osx-sign')
|
||||||
|
const opts = {
|
||||||
|
app: 'path/to/my.app',
|
||||||
|
// optional parameters for additional customization
|
||||||
|
platform: "mas", // should be auto-detected if your app was packaged for MAS via Packager or Forge
|
||||||
|
type: "distribution", // defaults to "distribution" for submission to App Store Connect
|
||||||
|
provisioningProfile: 'path/to/my.provisionprofile', // defaults to the current working directory
|
||||||
|
keychain: 'my-keychain', // defaults to the system default login keychain
|
||||||
|
};
|
||||||
|
signAsync(opts)
|
||||||
|
.then(function () {
|
||||||
|
// Application signed
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
// Handle the error
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
Mac App Store apps require a [Provisioning Profile](https://www.electronjs.org/docs/latest/tutorial/mac-app-store-submission-guide#prepare-provisioning-profile)
|
||||||
|
for submission to App Store Connect. We recommend having the provisioning profile for distribution
|
||||||
|
placed in the current working directory and the signing identity installed in the default keychain.
|
||||||
|
|
||||||
|
The app is not expected to run after codesigning since there is no provisioned device, and it is
|
||||||
|
intended only for submission to App Store Connect. Since `@electron/osx-sign` adds the entry
|
||||||
|
`com.apple.developer.team-identifier` to a temporary copy of the specified entitlements file
|
||||||
|
(with the default option `preAutoEntitlements`), distribution builds can no longer be run directly.
|
||||||
|
|
||||||
|
To run an app codesigned for distribution locally after codesigning, you may manually add
|
||||||
|
`ElectronTeamID` in your `Info.plist` and `com.apple.security.application-groups` in the
|
||||||
|
entitlements file, and set `preAutoEntitlements: false` for `@electron/osx-sign` to avoid
|
||||||
|
this extra bit. Note that "certain features are only allowed across apps whose team-identifier value match"
|
||||||
|
([Technical Note TN2415](https://developer.apple.com/library/content/technotes/tn2415/_index.html#//apple_ref/doc/uid/DTS40016427-CH1-ENTITLEMENTSLIST)).
|
||||||
|
|
||||||
|
Alternatively, set the app's `type` to `development` to codesign a development version of your app,
|
||||||
|
which will allow it to be run on your development provisioned machine. Apps signed for development
|
||||||
|
will not be eligible for submission via App Store Connect.
|
||||||
|
|
||||||
|
#### Signing with `--deep`
|
||||||
|
|
||||||
|
Some subresources that you may include in your Electron app may need to be signed with `--deep`.
|
||||||
|
This is not typically safe to apply to the entire Electron app and therefore should be applied to _just_ your file.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
signAsync({
|
||||||
|
app: 'path/to/my.app',
|
||||||
|
optionsForFile: (filePath) => {
|
||||||
|
// For our one specific file we can pass extra options to be merged
|
||||||
|
// with the default options
|
||||||
|
if (path.basename(filePath) === 'myStrangeFile.jar') {
|
||||||
|
return {
|
||||||
|
additionalArguments: ['--deep'],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Just use the default options for everything else
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Signing legacy versions of Electron
|
||||||
|
|
||||||
|
`@electron/osx-sign` maintains backwards compatibility with older versions of Electron, but
|
||||||
|
generally assumes that you are on the latest stable version.
|
||||||
|
|
||||||
|
If you are running an older unsupported version of Electron, you should pass in the `version`
|
||||||
|
option as such:
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
signAsync({
|
||||||
|
app: 'path/to/my.app',
|
||||||
|
version: '0.34.0',
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Flat installer packaging
|
||||||
|
|
||||||
|
This module also handles the creation of flat installer packages (`.pkg` installers).
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> Modern `.pkg` installers are also named "flat" packages for historical purposes. Prior
|
||||||
|
> to Mac OS X Leopard (10.5), installation packages were organized in hierarchical
|
||||||
|
> directories. OS X Leopard introduced a new flat package format that is used for modern
|
||||||
|
> `.pkg` installers.
|
||||||
|
|
||||||
|
### API usage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const { flatAsync } = require('@electron/osx-sign')
|
||||||
|
flatAsync({
|
||||||
|
app: 'path/to/my.app'
|
||||||
|
})
|
||||||
|
.then(function () {
|
||||||
|
// Application flattened
|
||||||
|
})
|
||||||
|
.catch(function (err) {
|
||||||
|
// Handle the error
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
The only mandatory option for `flatAsync` is a path to your `.app` package.
|
||||||
|
For full configuration options, see the [API documentation].
|
||||||
|
|
||||||
|
## CLI
|
||||||
|
|
||||||
|
`@electron/osx-sign` also exposes a legacy command-line interface (CLI) for both signing
|
||||||
|
and installer generation. However, we recommend using the JavaScript API as it has a more
|
||||||
|
complete API surface (e.g. `optionsForFile` is only available via JS).
|
||||||
|
|
||||||
|
```sh
|
||||||
|
# install the package locally into devDependencies
|
||||||
|
npm install --save-dev @electron/osx-sign
|
||||||
|
|
||||||
|
# Sign a packaged .app bundle
|
||||||
|
npx electron-osx-sign path/to/my.app [options ...]
|
||||||
|
|
||||||
|
# Create a .pkg installer from a packaged .app bundle
|
||||||
|
npx electron-osx-flat path/to/my.app [options ...]
|
||||||
|
```
|
||||||
|
|
||||||
|
For full options, use the `--help` flag for either command.
|
||||||
|
|
||||||
|
|
||||||
|
## Debug
|
||||||
|
|
||||||
|
The [`debug`](https://www.npmjs.com/package/debug) module is used to display advanced logs and messages.
|
||||||
|
If you are having problems with signing your app with `@electron/osx-sign`, run your signing scripts with
|
||||||
|
the `DEBUG=electron-osx-sign*` environment variable.
|
||||||
|
|
||||||
|
## Test
|
||||||
|
|
||||||
|
The project's configured to run automated tests on CircleCI.
|
||||||
|
|
||||||
|
If you wish to manually test the module, first comment out `opts.identity` in `test/basic.js` to enable
|
||||||
|
auto discovery. Then run the command `npm test` from the dev directory.
|
||||||
|
|
||||||
|
When this command is run for the first time: `@electron/get` will download macOS Electron releases defined
|
||||||
|
in `test/config.json`, and save to `~/.electron/`, which might take up less than 1GB of disk space.
|
||||||
|
|
||||||
|
A successful testing should look something like:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ npm test
|
||||||
|
|
||||||
|
> electron-osx-sign@0.4.17 pretest electron-osx-sign
|
||||||
|
> rimraf test/work
|
||||||
|
|
||||||
|
> electron-osx-sign@0.4.17 test electron-osx-sign
|
||||||
|
> standard && tape test
|
||||||
|
|
||||||
|
Calling @electron/get before running tests...
|
||||||
|
Running tests...
|
||||||
|
TAP version 13
|
||||||
|
# setup
|
||||||
|
# defaults-test:v7.0.0-beta.3-darwin-x64
|
||||||
|
ok 1 app signed
|
||||||
|
# defaults-test:v7.0.0-beta.3-mas-x64
|
||||||
|
ok 2 app signed
|
||||||
|
# defaults-test:v6.0.3-darwin-x64
|
||||||
|
ok 3 app signed
|
||||||
|
# defaults-test:v6.0.3-mas-x64
|
||||||
|
ok 4 app signed
|
||||||
|
# defaults-test:v5.0.10-darwin-x64
|
||||||
|
ok 5 app signed
|
||||||
|
# defaults-test:v5.0.10-mas-x64
|
||||||
|
ok 6 app signed
|
||||||
|
# defaults-test:v4.2.9-darwin-x64
|
||||||
|
ok 7 app signed
|
||||||
|
# defaults-test:v4.2.9-mas-x64
|
||||||
|
ok 8 app signed
|
||||||
|
# defaults-test:v3.1.2-darwin-x64
|
||||||
|
ok 9 app signed
|
||||||
|
# defaults-test:v3.1.2-mas-x64
|
||||||
|
ok 10 app signed
|
||||||
|
# teardown
|
||||||
|
|
||||||
|
1..10
|
||||||
|
# tests 10
|
||||||
|
# pass 10
|
||||||
|
|
||||||
|
# ok
|
||||||
|
```
|
||||||
|
|
||||||
|
[Electron]: https://github.com/electron/electron
|
||||||
|
[electron-osx-sign]: https://github.com/electron/osx-sign
|
||||||
|
[npm_img]: https://img.shields.io/npm/v/@electron/osx-sign.svg
|
||||||
|
[npm_url]: https://npmjs.org/package/@electron/osx-sign
|
||||||
|
[gha_img]: https://github.com/electron/osx-sign/actions/workflows/test.yml/badge.svg
|
||||||
|
[gha_url]: https://github.com/electron/osx-sign/actions/workflows/test.yml
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
import { PerFileSignOptions, ValidatedSignOptions } from './types';
|
||||||
|
import { Identity } from './util-identities';
|
||||||
|
import { ProvisioningProfile } from './util-provisioning-profiles';
|
||||||
|
type ComputedOptions = {
|
||||||
|
identity: Identity;
|
||||||
|
provisioningProfile?: ProvisioningProfile;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* This function returns a promise completing the entitlements automation: The
|
||||||
|
* process includes checking in `Info.plist` for `ElectronTeamID` or setting
|
||||||
|
* parsed value from identity, and checking in entitlements file for
|
||||||
|
* `com.apple.security.application-groups` or inserting new into array. A
|
||||||
|
* temporary entitlements file may be created to replace the input for any
|
||||||
|
* changes introduced.
|
||||||
|
*/
|
||||||
|
export declare function preAutoEntitlements(opts: ValidatedSignOptions, perFileOpts: PerFileSignOptions, computed: ComputedOptions): Promise<void | string>;
|
||||||
|
export {};
|
||||||
+133
@@ -0,0 +1,133 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.preAutoEntitlements = void 0;
|
||||||
|
const fs = __importStar(require("fs-extra"));
|
||||||
|
const os = __importStar(require("os"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const plist = __importStar(require("plist"));
|
||||||
|
const util_1 = require("./util");
|
||||||
|
const preAuthMemo = new Map();
|
||||||
|
/**
|
||||||
|
* This function returns a promise completing the entitlements automation: The
|
||||||
|
* process includes checking in `Info.plist` for `ElectronTeamID` or setting
|
||||||
|
* parsed value from identity, and checking in entitlements file for
|
||||||
|
* `com.apple.security.application-groups` or inserting new into array. A
|
||||||
|
* temporary entitlements file may be created to replace the input for any
|
||||||
|
* changes introduced.
|
||||||
|
*/
|
||||||
|
async function preAutoEntitlements(opts, perFileOpts, computed) {
|
||||||
|
var _a;
|
||||||
|
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((0, util_1.getAppContentsPath)(opts), 'Info.plist');
|
||||||
|
(0, util_1.debugLog)('Automating entitlement app group...', '\n', '> Info.plist:', appInfoPath, '\n');
|
||||||
|
let entitlements;
|
||||||
|
if (typeof perFileOpts.entitlements === 'string') {
|
||||||
|
const entitlementsContents = await fs.readFile(perFileOpts.entitlements, 'utf8');
|
||||||
|
entitlements = plist.parse(entitlementsContents);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entitlements = perFileOpts.entitlements.reduce((dict, entitlementKey) => (Object.assign(Object.assign({}, dict), { [entitlementKey]: true })), {});
|
||||||
|
}
|
||||||
|
if (!entitlements['com.apple.security.app-sandbox']) {
|
||||||
|
// Only automate when app sandbox enabled by user
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const appInfoContents = await fs.readFile(appInfoPath, 'utf8');
|
||||||
|
const appInfo = plist.parse(appInfoContents);
|
||||||
|
// Use ElectronTeamID in Info.plist if already specified
|
||||||
|
if (appInfo.ElectronTeamID) {
|
||||||
|
(0, util_1.debugLog)('`ElectronTeamID` found in `Info.plist`: ' + appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The team identifier in signing identity should not be trusted
|
||||||
|
if (computed.provisioningProfile) {
|
||||||
|
appInfo.ElectronTeamID =
|
||||||
|
computed.provisioningProfile.message.Entitlements['com.apple.developer.team-identifier'];
|
||||||
|
(0, util_1.debugLog)('`ElectronTeamID` not found in `Info.plist`, use parsed from provisioning profile: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const teamID = (_a = /^.+\((.+?)\)$/g.exec(computed.identity.name)) === null || _a === void 0 ? void 0 : _a[1];
|
||||||
|
if (!teamID) {
|
||||||
|
throw new Error(`Could not automatically determine ElectronTeamID from identity: ${computed.identity.name}`);
|
||||||
|
}
|
||||||
|
appInfo.ElectronTeamID = teamID;
|
||||||
|
(0, util_1.debugLog)('`ElectronTeamID` not found in `Info.plist`, use parsed from signing identity: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
await fs.writeFile(appInfoPath, plist.build(appInfo), 'utf8');
|
||||||
|
(0, util_1.debugLog)('`Info.plist` updated:', '\n', '> Info.plist:', appInfoPath);
|
||||||
|
}
|
||||||
|
const appIdentifier = appInfo.ElectronTeamID + '.' + appInfo.CFBundleIdentifier;
|
||||||
|
// Insert application identifier if not exists
|
||||||
|
if (entitlements['com.apple.application-identifier']) {
|
||||||
|
(0, util_1.debugLog)('`com.apple.application-identifier` found in entitlements file: ' +
|
||||||
|
entitlements['com.apple.application-identifier']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, util_1.debugLog)('`com.apple.application-identifier` not found in entitlements file, new inserted: ' +
|
||||||
|
appIdentifier);
|
||||||
|
entitlements['com.apple.application-identifier'] = appIdentifier;
|
||||||
|
}
|
||||||
|
// Insert developer team identifier if not exists
|
||||||
|
if (entitlements['com.apple.developer.team-identifier']) {
|
||||||
|
(0, util_1.debugLog)('`com.apple.developer.team-identifier` found in entitlements file: ' +
|
||||||
|
entitlements['com.apple.developer.team-identifier']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, util_1.debugLog)('`com.apple.developer.team-identifier` not found in entitlements file, new inserted: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
entitlements['com.apple.developer.team-identifier'] = appInfo.ElectronTeamID;
|
||||||
|
}
|
||||||
|
// Init entitlements app group key to array if not exists
|
||||||
|
if (!entitlements['com.apple.security.application-groups']) {
|
||||||
|
entitlements['com.apple.security.application-groups'] = [];
|
||||||
|
}
|
||||||
|
// Insert app group if not exists
|
||||||
|
if (Array.isArray(entitlements['com.apple.security.application-groups']) &&
|
||||||
|
entitlements['com.apple.security.application-groups'].indexOf(appIdentifier) === -1) {
|
||||||
|
(0, util_1.debugLog)('`com.apple.security.application-groups` not found in entitlements file, new inserted: ' +
|
||||||
|
appIdentifier);
|
||||||
|
entitlements['com.apple.security.application-groups'].push(appIdentifier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, util_1.debugLog)('`com.apple.security.application-groups` found in entitlements file: ' + appIdentifier);
|
||||||
|
}
|
||||||
|
// Create temporary entitlements file
|
||||||
|
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');
|
||||||
|
(0, util_1.debugLog)('Entitlements file updated:', '\n', '> Entitlements:', entitlementsPath);
|
||||||
|
preAuthMemo.set(memoKey, entitlementsPath);
|
||||||
|
return entitlementsPath;
|
||||||
|
}
|
||||||
|
exports.preAutoEntitlements = preAutoEntitlements;
|
||||||
|
//# sourceMappingURL=util-entitlements.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-entitlements.js","sourceRoot":"","sources":["../../src/util-entitlements.ts"],"names":[],"mappings":"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"}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
export declare class Identity {
|
||||||
|
name: string;
|
||||||
|
hash?: string | undefined;
|
||||||
|
constructor(name: string, hash?: string | undefined);
|
||||||
|
}
|
||||||
|
export declare function findIdentities(keychain: string | null, identity: string): Promise<Identity[]>;
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
"use strict";
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.findIdentities = exports.Identity = void 0;
|
||||||
|
const util_1 = require("./util");
|
||||||
|
class Identity {
|
||||||
|
constructor(name, hash) {
|
||||||
|
this.name = name;
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.Identity = Identity;
|
||||||
|
async function findIdentities(keychain, identity) {
|
||||||
|
// Only to look for valid identities, excluding those flagged with
|
||||||
|
// CSSMERR_TP_CERT_EXPIRED or CSSMERR_TP_NOT_TRUSTED. Fixes #9
|
||||||
|
const args = [
|
||||||
|
'find-identity',
|
||||||
|
'-v'
|
||||||
|
];
|
||||||
|
if (keychain) {
|
||||||
|
args.push(keychain);
|
||||||
|
}
|
||||||
|
const result = await (0, util_1.execFileAsync)('security', args);
|
||||||
|
const identities = result.split('\n').map(function (line) {
|
||||||
|
if (line.indexOf(identity) >= 0) {
|
||||||
|
const identityFound = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'));
|
||||||
|
const identityHashFound = line.substring(line.indexOf(')') + 2, line.indexOf('"') - 1);
|
||||||
|
(0, util_1.debugLog)('Identity:', '\n', '> Name:', identityFound, '\n', '> Hash:', identityHashFound);
|
||||||
|
return new Identity(identityFound, identityHashFound);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return (0, util_1.compactFlattenedList)(identities);
|
||||||
|
}
|
||||||
|
exports.findIdentities = findIdentities;
|
||||||
|
//# sourceMappingURL=util-identities.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-identities.js","sourceRoot":"","sources":["../../src/util-identities.ts"],"names":[],"mappings":";;;AAAA,iCAAuE;AAEvE,MAAa,QAAQ;IACnB,YAAoB,IAAY,EAAS,IAAa;QAAlC,SAAI,GAAJ,IAAI,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAS;IAAG,CAAC;CAC3D;AAFD,4BAEC;AAEM,KAAK,UAAU,cAAc,CAAE,QAAuB,EAAE,QAAgB;IAC7E,kEAAkE;IAClE,8DAA8D;IAE9D,MAAM,IAAI,GAAG;QACX,eAAe;QACf,IAAI;KACL,CAAC;IACF,IAAI,QAAQ,EAAE;QACZ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KACrB;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAa,EAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI;QACtD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACnF,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,IAAA,eAAQ,EAAC,WAAW,EAAE,IAAI,EACxB,SAAS,EAAE,aAAa,EAAE,IAAI,EAC9B,SAAS,EAAE,iBAAiB,CAAC,CAAC;YAChC,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;SACvD;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,IAAA,2BAAoB,EAAC,UAAU,CAAC,CAAC;AAC1C,CAAC;AA3BD,wCA2BC"}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { ElectronMacPlatform, ValidatedSignOptions } from './types';
|
||||||
|
export declare class ProvisioningProfile {
|
||||||
|
filePath: string;
|
||||||
|
message: any;
|
||||||
|
constructor(filePath: string, message: any);
|
||||||
|
get name(): string;
|
||||||
|
get platforms(): ElectronMacPlatform[];
|
||||||
|
get type(): "development" | "distribution";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a ProvisioningProfile instance based on file.
|
||||||
|
* @function
|
||||||
|
* @param {string} filePath - Path to provisioning profile.
|
||||||
|
* @param {string} keychain - Keychain to use when unlocking provisioning profile.
|
||||||
|
* @returns {Promise} Promise.
|
||||||
|
*/
|
||||||
|
export declare function getProvisioningProfile(filePath: string, keychain?: string | null): Promise<ProvisioningProfile>;
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a list of suitable provisioning profile within the current working directory.
|
||||||
|
*/
|
||||||
|
export declare function findProvisioningProfiles(opts: ValidatedSignOptions): Promise<ProvisioningProfile[]>;
|
||||||
|
/**
|
||||||
|
* Returns a promise embedding the provisioning profile in the app Contents folder.
|
||||||
|
*/
|
||||||
|
export declare function preEmbedProvisioningProfile(opts: ValidatedSignOptions, profile: ProvisioningProfile | null): Promise<void>;
|
||||||
+148
@@ -0,0 +1,148 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.preEmbedProvisioningProfile = exports.findProvisioningProfiles = exports.getProvisioningProfile = exports.ProvisioningProfile = void 0;
|
||||||
|
const fs = __importStar(require("fs-extra"));
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const plist_1 = __importDefault(require("plist"));
|
||||||
|
const util_1 = require("./util");
|
||||||
|
class ProvisioningProfile {
|
||||||
|
constructor(filePath, message) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
get name() {
|
||||||
|
return this.message.Name;
|
||||||
|
}
|
||||||
|
get platforms() {
|
||||||
|
if ('ProvisionsAllDevices' in this.message)
|
||||||
|
return ['darwin'];
|
||||||
|
// Developer ID
|
||||||
|
else if (this.type === 'distribution')
|
||||||
|
return ['mas'];
|
||||||
|
// Mac App Store
|
||||||
|
else
|
||||||
|
return ['darwin', 'mas']; // Mac App Development
|
||||||
|
}
|
||||||
|
get type() {
|
||||||
|
if ('ProvisionedDevices' in this.message)
|
||||||
|
return 'development';
|
||||||
|
// Mac App Development
|
||||||
|
else
|
||||||
|
return 'distribution'; // Developer ID or Mac App Store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.ProvisioningProfile = ProvisioningProfile;
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a ProvisioningProfile instance based on file.
|
||||||
|
* @function
|
||||||
|
* @param {string} filePath - Path to provisioning profile.
|
||||||
|
* @param {string} keychain - Keychain to use when unlocking provisioning profile.
|
||||||
|
* @returns {Promise} Promise.
|
||||||
|
*/
|
||||||
|
async function getProvisioningProfile(filePath, keychain = null) {
|
||||||
|
const securityArgs = [
|
||||||
|
'cms',
|
||||||
|
'-D',
|
||||||
|
'-i',
|
||||||
|
filePath // Use infile as source of data
|
||||||
|
];
|
||||||
|
if (keychain) {
|
||||||
|
securityArgs.push('-k', keychain);
|
||||||
|
}
|
||||||
|
const result = await (0, util_1.execFileAsync)('security', securityArgs);
|
||||||
|
const provisioningProfile = new ProvisioningProfile(filePath, plist_1.default.parse(result));
|
||||||
|
(0, util_1.debugLog)('Provisioning profile:', '\n', '> Name:', provisioningProfile.name, '\n', '> Platforms:', provisioningProfile.platforms, '\n', '> Type:', provisioningProfile.type, '\n', '> Path:', provisioningProfile.filePath, '\n', '> Message:', provisioningProfile.message);
|
||||||
|
return provisioningProfile;
|
||||||
|
}
|
||||||
|
exports.getProvisioningProfile = getProvisioningProfile;
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a list of suitable provisioning profile within the current working directory.
|
||||||
|
*/
|
||||||
|
async function findProvisioningProfiles(opts) {
|
||||||
|
const cwd = process.cwd();
|
||||||
|
const children = await fs.readdir(cwd);
|
||||||
|
const foundProfiles = (0, util_1.compactFlattenedList)(await Promise.all(children.map(async (child) => {
|
||||||
|
const filePath = path.resolve(cwd, child);
|
||||||
|
const stat = await fs.stat(filePath);
|
||||||
|
if (stat.isFile() && path.extname(filePath) === '.provisionprofile') {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
return (0, util_1.compactFlattenedList)(await Promise.all(foundProfiles.map(async (filePath) => {
|
||||||
|
const profile = await getProvisioningProfile(filePath);
|
||||||
|
if (profile.platforms.indexOf(opts.platform) >= 0 && profile.type === opts.type) {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
(0, util_1.debugWarn)('Provisioning profile above ignored, not for ' + opts.platform + ' ' + opts.type + '.');
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
exports.findProvisioningProfiles = findProvisioningProfiles;
|
||||||
|
/**
|
||||||
|
* Returns a promise embedding the provisioning profile in the app Contents folder.
|
||||||
|
*/
|
||||||
|
async function preEmbedProvisioningProfile(opts, profile) {
|
||||||
|
async function embedProvisioningProfile(profile) {
|
||||||
|
(0, util_1.debugLog)('Looking for existing provisioning profile...');
|
||||||
|
const embeddedFilePath = path.join((0, util_1.getAppContentsPath)(opts), 'embedded.provisionprofile');
|
||||||
|
if (await fs.pathExists(embeddedFilePath)) {
|
||||||
|
(0, util_1.debugLog)('Found embedded provisioning profile:', '\n', '* Please manually remove the existing file if not wanted.', '\n', '* Current file at:', embeddedFilePath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, util_1.debugLog)('Embedding provisioning profile...');
|
||||||
|
await fs.copy(profile.filePath, embeddedFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (profile) {
|
||||||
|
// User input provisioning profile
|
||||||
|
return await embedProvisioningProfile(profile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Discover provisioning profile
|
||||||
|
(0, util_1.debugLog)('No `provisioning-profile` passed in arguments, will find in current working directory and in user library...');
|
||||||
|
const profiles = await findProvisioningProfiles(opts);
|
||||||
|
if (profiles.length > 0) {
|
||||||
|
// Provisioning profile(s) found
|
||||||
|
if (profiles.length > 1) {
|
||||||
|
(0, util_1.debugLog)('Multiple provisioning profiles found, will use the first discovered.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, util_1.debugLog)('Found 1 provisioning profile.');
|
||||||
|
}
|
||||||
|
await embedProvisioningProfile(profiles[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No provisioning profile found
|
||||||
|
(0, util_1.debugLog)('No provisioning profile found, will not embed profile in app contents.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.preEmbedProvisioningProfile = preEmbedProvisioningProfile;
|
||||||
|
//# sourceMappingURL=util-provisioning-profiles.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-provisioning-profiles.js","sourceRoot":"","sources":["../../src/util-provisioning-profiles.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,6CAA+B;AAC/B,2CAA6B;AAC7B,kDAA0B;AAG1B,iCAAsG;AAEtG,MAAa,mBAAmB;IAC9B,YAAoB,QAAgB,EAAS,OAAY;QAArC,aAAQ,GAAR,QAAQ,CAAQ;QAAS,YAAO,GAAP,OAAO,CAAK;IAAG,CAAC;IAE7D,IAAI,IAAI;QACN,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;IAED,IAAI,SAAS;QACX,IAAI,sBAAsB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC9D,eAAe;aACV,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC;QACtD,gBAAgB;;YACX,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC,sBAAsB;IACvD,CAAC;IAED,IAAI,IAAI;QACN,IAAI,oBAAoB,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO,aAAa,CAAC;QAC/D,sBAAsB;;YACjB,OAAO,cAAc,CAAC,CAAC,gCAAgC;IAC9D,CAAC;CACF;AApBD,kDAoBC;AAED;;;;;;GAMG;AACI,KAAK,UAAU,sBAAsB,CAAE,QAAgB,EAAE,WAA0B,IAAI;IAC5F,MAAM,YAAY,GAAG;QACnB,KAAK;QACL,IAAI;QACJ,IAAI;QACJ,QAAQ,CAAC,+BAA+B;KACzC,CAAC;IAEF,IAAI,QAAQ,EAAE;QACZ,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;KACnC;IAED,MAAM,MAAM,GAAG,MAAM,IAAA,oBAAa,EAAC,UAAU,EAAE,YAAY,CAAC,CAAC;IAC7D,MAAM,mBAAmB,GAAG,IAAI,mBAAmB,CAAC,QAAQ,EAAE,eAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IACnF,IAAA,eAAQ,EACN,uBAAuB,EACvB,IAAI,EACJ,SAAS,EACT,mBAAmB,CAAC,IAAI,EACxB,IAAI,EACJ,cAAc,EACd,mBAAmB,CAAC,SAAS,EAC7B,IAAI,EACJ,SAAS,EACT,mBAAmB,CAAC,IAAI,EACxB,IAAI,EACJ,SAAS,EACT,mBAAmB,CAAC,QAAQ,EAC5B,IAAI,EACJ,YAAY,EACZ,mBAAmB,CAAC,OAAO,CAC5B,CAAC;IACF,OAAO,mBAAmB,CAAC;AAC7B,CAAC;AAjCD,wDAiCC;AAED;;GAEG;AACI,KAAK,UAAU,wBAAwB,CAAE,IAA0B;IACxE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,aAAa,GAAG,IAAA,2BAAoB,EACxC,MAAM,OAAO,CAAC,GAAG,CACf,QAAQ,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC1C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,IAAI,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,mBAAmB,EAAE;YACnE,OAAO,QAAQ,CAAC;SACjB;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CACH,CACF,CAAC;IAEF,OAAO,IAAA,2BAAoB,EACzB,MAAM,OAAO,CAAC,GAAG,CACf,aAAa,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QACnC,MAAM,OAAO,GAAG,MAAM,sBAAsB,CAAC,QAAQ,CAAC,CAAC;QACvD,IAAI,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,CAAC,IAAI,EAAE;YAAE,OAAO,OAAO,CAAC;SAAE;QACpG,IAAA,gBAAS,EACP,8CAA8C,GAAG,IAAI,CAAC,QAAQ,GAAG,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,GAAG,CACvF,CAAC;QACF,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CACH,CACF,CAAC;AACJ,CAAC;AA5BD,4DA4BC;AAED;;GAEG;AACI,KAAK,UAAU,2BAA2B,CAAE,IAA0B,EAAE,OAAmC;IAChH,KAAK,UAAU,wBAAwB,CAAE,OAA4B;QACnE,IAAA,eAAQ,EAAC,8CAA8C,CAAC,CAAC;QACzD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,IAAA,yBAAkB,EAAC,IAAI,CAAC,EAAE,2BAA2B,CAAC,CAAC;QAE1F,IAAI,MAAM,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;YACzC,IAAA,eAAQ,EACN,sCAAsC,EACtC,IAAI,EACJ,2DAA2D,EAC3D,IAAI,EACJ,oBAAoB,EACpB,gBAAgB,CACjB,CAAC;SACH;aAAM;YACL,IAAA,eAAQ,EAAC,mCAAmC,CAAC,CAAC;YAC9C,MAAM,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;SACnD;IACH,CAAC;IAED,IAAI,OAAO,EAAE;QACX,kCAAkC;QAClC,OAAO,MAAM,wBAAwB,CAAC,OAAO,CAAC,CAAC;KAChD;SAAM;QACL,gCAAgC;QAChC,IAAA,eAAQ,EACN,8GAA8G,CAC/G,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,wBAAwB,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;YACvB,gCAAgC;YAChC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE;gBACvB,IAAA,eAAQ,EAAC,sEAAsE,CAAC,CAAC;aAClF;iBAAM;gBACL,IAAA,eAAQ,EAAC,+BAA+B,CAAC,CAAC;aAC3C;YACD,MAAM,wBAAwB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;SAC7C;aAAM;YACL,gCAAgC;YAChC,IAAA,eAAQ,EAAC,wEAAwE,CAAC,CAAC;SACpF;KACF;AACH,CAAC;AA1CD,kEA0CC"}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/// <reference types="node" />
|
||||||
|
import * as child from 'child_process';
|
||||||
|
import debug from 'debug';
|
||||||
|
import { BaseSignOptions, ElectronMacPlatform } from './types';
|
||||||
|
export declare const debugLog: debug.Debugger;
|
||||||
|
export declare const debugWarn: debug.Debugger;
|
||||||
|
export declare function execFileAsync(file: string, args: string[], options?: child.ExecFileOptions): Promise<string>;
|
||||||
|
type DeepListItem<T> = null | T | DeepListItem<T>[];
|
||||||
|
type DeepList<T> = DeepListItem<T>[];
|
||||||
|
export declare function compactFlattenedList<T>(list: DeepList<T>): T[];
|
||||||
|
/**
|
||||||
|
* Returns the path to the "Contents" folder inside the application bundle
|
||||||
|
*/
|
||||||
|
export declare function getAppContentsPath(opts: BaseSignOptions): string;
|
||||||
|
/**
|
||||||
|
* Returns the path to app "Frameworks" within contents.
|
||||||
|
*/
|
||||||
|
export declare function getAppFrameworksPath(opts: BaseSignOptions): string;
|
||||||
|
export declare function detectElectronPlatform(opts: BaseSignOptions): Promise<ElectronMacPlatform>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.app, the application to be signed or flattened.
|
||||||
|
*/
|
||||||
|
export declare function validateOptsApp(opts: BaseSignOptions): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.platform, the platform of Electron build. It allows auto-discovery if no opts.platform is specified.
|
||||||
|
*/
|
||||||
|
export declare function validateOptsPlatform(opts: BaseSignOptions): Promise<ElectronMacPlatform>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving all child paths within the directory specified.
|
||||||
|
* @function
|
||||||
|
* @param {string} dirPath - Path to directory.
|
||||||
|
* @returns {Promise} Promise resolving child paths needing signing in order.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export declare function walkAsync(dirPath: string): Promise<string[]>;
|
||||||
|
export {};
|
||||||
+183
@@ -0,0 +1,183 @@
|
|||||||
|
"use strict";
|
||||||
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||||
|
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||||
|
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||||
|
}
|
||||||
|
Object.defineProperty(o, k2, desc);
|
||||||
|
}) : (function(o, m, k, k2) {
|
||||||
|
if (k2 === undefined) k2 = k;
|
||||||
|
o[k2] = m[k];
|
||||||
|
}));
|
||||||
|
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||||
|
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||||
|
}) : function(o, v) {
|
||||||
|
o["default"] = v;
|
||||||
|
});
|
||||||
|
var __importStar = (this && this.__importStar) || function (mod) {
|
||||||
|
if (mod && mod.__esModule) return mod;
|
||||||
|
var result = {};
|
||||||
|
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||||
|
__setModuleDefault(result, mod);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||||
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||||
|
};
|
||||||
|
Object.defineProperty(exports, "__esModule", { value: true });
|
||||||
|
exports.walkAsync = exports.validateOptsPlatform = exports.validateOptsApp = exports.detectElectronPlatform = exports.getAppFrameworksPath = exports.getAppContentsPath = exports.compactFlattenedList = exports.execFileAsync = exports.debugWarn = exports.debugLog = void 0;
|
||||||
|
const child = __importStar(require("child_process"));
|
||||||
|
const fs = __importStar(require("fs-extra"));
|
||||||
|
const isbinaryfile_1 = require("isbinaryfile");
|
||||||
|
const path = __importStar(require("path"));
|
||||||
|
const debug_1 = __importDefault(require("debug"));
|
||||||
|
exports.debugLog = (0, debug_1.default)('electron-osx-sign');
|
||||||
|
exports.debugLog.log = console.log.bind(console);
|
||||||
|
exports.debugWarn = (0, debug_1.default)('electron-osx-sign:warn');
|
||||||
|
exports.debugWarn.log = console.warn.bind(console);
|
||||||
|
const removePassword = function (input) {
|
||||||
|
return input.replace(/(-P |pass:|\/p|-pass )([^ ]+)/, function (_, p1) {
|
||||||
|
return `${p1}***`;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
async function execFileAsync(file, args, options = {}) {
|
||||||
|
if (exports.debugLog.enabled) {
|
||||||
|
(0, exports.debugLog)('Executing...', file, args && Array.isArray(args) ? removePassword(args.join(' ')) : '');
|
||||||
|
}
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
child.execFile(file, args, options, function (err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
(0, exports.debugLog)('Error executing file:', '\n', '> Stdout:', stdout, '\n', '> Stderr:', stderr);
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(stdout);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
exports.execFileAsync = execFileAsync;
|
||||||
|
function compactFlattenedList(list) {
|
||||||
|
const result = [];
|
||||||
|
function populateResult(list) {
|
||||||
|
if (!Array.isArray(list)) {
|
||||||
|
if (list)
|
||||||
|
result.push(list);
|
||||||
|
}
|
||||||
|
else if (list.length > 0) {
|
||||||
|
for (const item of list)
|
||||||
|
if (item)
|
||||||
|
populateResult(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
populateResult(list);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
exports.compactFlattenedList = compactFlattenedList;
|
||||||
|
/**
|
||||||
|
* Returns the path to the "Contents" folder inside the application bundle
|
||||||
|
*/
|
||||||
|
function getAppContentsPath(opts) {
|
||||||
|
return path.join(opts.app, 'Contents');
|
||||||
|
}
|
||||||
|
exports.getAppContentsPath = getAppContentsPath;
|
||||||
|
/**
|
||||||
|
* Returns the path to app "Frameworks" within contents.
|
||||||
|
*/
|
||||||
|
function getAppFrameworksPath(opts) {
|
||||||
|
return path.join(getAppContentsPath(opts), 'Frameworks');
|
||||||
|
}
|
||||||
|
exports.getAppFrameworksPath = getAppFrameworksPath;
|
||||||
|
async function detectElectronPlatform(opts) {
|
||||||
|
const appFrameworksPath = getAppFrameworksPath(opts);
|
||||||
|
if (await fs.pathExists(path.resolve(appFrameworksPath, 'Squirrel.framework'))) {
|
||||||
|
return 'darwin';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'mas';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.detectElectronPlatform = detectElectronPlatform;
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving the file path if file binary.
|
||||||
|
*/
|
||||||
|
async function getFilePathIfBinary(filePath) {
|
||||||
|
if (await (0, isbinaryfile_1.isBinaryFile)(filePath)) {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.app, the application to be signed or flattened.
|
||||||
|
*/
|
||||||
|
async function validateOptsApp(opts) {
|
||||||
|
if (!opts.app) {
|
||||||
|
throw new Error('Path to application must be specified.');
|
||||||
|
}
|
||||||
|
if (path.extname(opts.app) !== '.app') {
|
||||||
|
throw new Error('Extension of application must be `.app`.');
|
||||||
|
}
|
||||||
|
if (!(await fs.pathExists(opts.app))) {
|
||||||
|
throw new Error(`Application at path "${opts.app}" could not be found`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
exports.validateOptsApp = validateOptsApp;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.platform, the platform of Electron build. It allows auto-discovery if no opts.platform is specified.
|
||||||
|
*/
|
||||||
|
async function validateOptsPlatform(opts) {
|
||||||
|
if (opts.platform) {
|
||||||
|
if (opts.platform === 'mas' || opts.platform === 'darwin') {
|
||||||
|
return opts.platform;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, exports.debugWarn)('`platform` passed in arguments not supported, checking Electron platform...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(0, exports.debugWarn)('No `platform` passed in arguments, checking Electron platform...');
|
||||||
|
}
|
||||||
|
return await detectElectronPlatform(opts);
|
||||||
|
}
|
||||||
|
exports.validateOptsPlatform = validateOptsPlatform;
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving all child paths within the directory specified.
|
||||||
|
* @function
|
||||||
|
* @param {string} dirPath - Path to directory.
|
||||||
|
* @returns {Promise} Promise resolving child paths needing signing in order.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
async function walkAsync(dirPath) {
|
||||||
|
(0, exports.debugLog)('Walking... ' + dirPath);
|
||||||
|
async function _walkAsync(dirPath) {
|
||||||
|
const children = await fs.readdir(dirPath);
|
||||||
|
return await Promise.all(children.map(async (child) => {
|
||||||
|
const filePath = path.resolve(dirPath, child);
|
||||||
|
const stat = await fs.stat(filePath);
|
||||||
|
if (stat.isFile()) {
|
||||||
|
switch (path.extname(filePath)) {
|
||||||
|
case '.cstemp': // Temporary file generated from past codesign
|
||||||
|
(0, exports.debugLog)('Removing... ' + filePath);
|
||||||
|
await fs.remove(filePath);
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
return await getFilePathIfBinary(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
||||||
|
const walkResult = await _walkAsync(filePath);
|
||||||
|
switch (path.extname(filePath)) {
|
||||||
|
case '.app': // Application
|
||||||
|
case '.framework': // Framework
|
||||||
|
walkResult.push(filePath);
|
||||||
|
}
|
||||||
|
return walkResult;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const allPaths = await _walkAsync(dirPath);
|
||||||
|
return compactFlattenedList(allPaths);
|
||||||
|
}
|
||||||
|
exports.walkAsync = walkAsync;
|
||||||
|
//# sourceMappingURL=util.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
import { FlatOptions } from './types';
|
||||||
|
/**
|
||||||
|
* Generates a flat `.pkg` installer for a packaged Electron `.app` bundle.
|
||||||
|
* @returns A void Promise once the flattening operation is complete.
|
||||||
|
*
|
||||||
|
* @category Flat
|
||||||
|
*/
|
||||||
|
export declare function buildPkg(_opts: FlatOptions): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This function is exported with normal callback implementation.
|
||||||
|
*
|
||||||
|
* @deprecated Please use the Promise-based {@link flatAsync} method instead.
|
||||||
|
* @category Flat
|
||||||
|
*/
|
||||||
|
export declare const flat: (opts: FlatOptions, cb?: ((error?: Error) => void) | undefined) => void;
|
||||||
+151
@@ -0,0 +1,151 @@
|
|||||||
|
import * as path from 'path';
|
||||||
|
import { debugLog, debugWarn, execFileAsync, validateOptsApp, validateOptsPlatform } from './util';
|
||||||
|
import { findIdentities } from './util-identities';
|
||||||
|
const pkgVersion = require('../../package.json').version;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating all options passed in opts.
|
||||||
|
* @function
|
||||||
|
* @param {Object} opts - Options.
|
||||||
|
* @returns {Promise} Promise.
|
||||||
|
*/
|
||||||
|
async function validateFlatOpts(opts) {
|
||||||
|
await validateOptsApp(opts);
|
||||||
|
let pkg = opts.pkg;
|
||||||
|
if (pkg) {
|
||||||
|
if (typeof pkg !== 'string')
|
||||||
|
throw new Error('`pkg` must be a string.');
|
||||||
|
if (path.extname(pkg) !== '.pkg') {
|
||||||
|
throw new Error('Extension of output package must be `.pkg`.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('No `pkg` passed in arguments, will fallback to default inferred from the given application.');
|
||||||
|
pkg = path.join(path.dirname(opts.app), path.basename(opts.app, '.app') + '.pkg');
|
||||||
|
}
|
||||||
|
let install = opts.install;
|
||||||
|
if (install) {
|
||||||
|
if (typeof install !== 'string') {
|
||||||
|
return Promise.reject(new Error('`install` must be a string.'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('No `install` passed in arguments, will fallback to default `/Applications`.');
|
||||||
|
install = '/Applications';
|
||||||
|
}
|
||||||
|
if (typeof opts.scripts === 'string' && opts.platform === 'mas') {
|
||||||
|
debugWarn('Mac App Store packages cannot have `scripts`, ignoring option.');
|
||||||
|
}
|
||||||
|
return Object.assign(Object.assign({}, opts), { pkg,
|
||||||
|
install, platform: await validateOptsPlatform(opts) });
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise flattening the application.
|
||||||
|
* @param opts - Options for building the .pkg archive
|
||||||
|
*/
|
||||||
|
async function buildApplicationPkg(opts, identity) {
|
||||||
|
if (opts.platform === 'mas') {
|
||||||
|
const args = ['--component', opts.app, opts.install, '--sign', identity.name, opts.pkg];
|
||||||
|
if (opts.keychain) {
|
||||||
|
args.unshift('--keychain', opts.keychain);
|
||||||
|
}
|
||||||
|
debugLog('Flattening Mac App Store package... ' + opts.app);
|
||||||
|
await execFileAsync('productbuild', args);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const componentPkgPath = path.join(path.dirname(opts.app), path.basename(opts.app, '.app') + '-component.pkg');
|
||||||
|
const pkgbuildArgs = [
|
||||||
|
'--install-location',
|
||||||
|
opts.install,
|
||||||
|
'--component',
|
||||||
|
opts.app,
|
||||||
|
componentPkgPath
|
||||||
|
];
|
||||||
|
if (opts.scripts) {
|
||||||
|
pkgbuildArgs.unshift('--scripts', opts.scripts);
|
||||||
|
}
|
||||||
|
debugLog('Building component package... ' + opts.app);
|
||||||
|
await execFileAsync('pkgbuild', pkgbuildArgs);
|
||||||
|
const args = ['--package', componentPkgPath, opts.install, '--sign', identity.name, opts.pkg];
|
||||||
|
if (opts.keychain) {
|
||||||
|
args.unshift('--keychain', opts.keychain);
|
||||||
|
}
|
||||||
|
debugLog('Flattening OS X Installer package... ' + opts.app);
|
||||||
|
await execFileAsync('productbuild', args);
|
||||||
|
await execFileAsync('rm', [componentPkgPath]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generates a flat `.pkg` installer for a packaged Electron `.app` bundle.
|
||||||
|
* @returns A void Promise once the flattening operation is complete.
|
||||||
|
*
|
||||||
|
* @category Flat
|
||||||
|
*/
|
||||||
|
export async function buildPkg(_opts) {
|
||||||
|
debugLog('@electron/osx-sign@%s', pkgVersion);
|
||||||
|
const validatedOptions = await validateFlatOpts(_opts);
|
||||||
|
let identities = [];
|
||||||
|
let identityInUse = null;
|
||||||
|
if (validatedOptions.identity) {
|
||||||
|
debugLog('`identity` passed in arguments.');
|
||||||
|
if (validatedOptions.identityValidation === false) {
|
||||||
|
// Do nothing
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
identities = await findIdentities(validatedOptions.keychain || null, validatedOptions.identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('No `identity` passed in arguments...');
|
||||||
|
if (validatedOptions.platform === 'mas') {
|
||||||
|
debugLog('Finding `3rd Party Mac Developer Installer` certificate for flattening app distribution in the Mac App Store...');
|
||||||
|
identities = await findIdentities(validatedOptions.keychain || null, '3rd Party Mac Developer Installer:');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Finding `Developer ID Application` certificate for distribution outside the Mac App Store...');
|
||||||
|
identities = await findIdentities(validatedOptions.keychain || null, 'Developer ID Installer:');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (identities.length > 0) {
|
||||||
|
// Provisioning profile(s) found
|
||||||
|
if (identities.length > 1) {
|
||||||
|
debugWarn('Multiple identities found, will use the first discovered.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Found 1 identity.');
|
||||||
|
}
|
||||||
|
identityInUse = identities[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No identity found
|
||||||
|
throw new Error('No identity found for signing.');
|
||||||
|
}
|
||||||
|
debugLog('Flattening application...', '\n', '> Application:', validatedOptions.app, '\n', '> Package output:', validatedOptions.pkg, '\n', '> Install path:', validatedOptions.install, '\n', '> Identity:', validatedOptions.identity, '\n', '> Scripts:', validatedOptions.scripts);
|
||||||
|
await buildApplicationPkg(validatedOptions, identityInUse);
|
||||||
|
debugLog('Application flattened.');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function is exported with normal callback implementation.
|
||||||
|
*
|
||||||
|
* @deprecated Please use the Promise-based {@link flatAsync} method instead.
|
||||||
|
* @category Flat
|
||||||
|
*/
|
||||||
|
export const flat = (opts, cb) => {
|
||||||
|
buildPkg(opts)
|
||||||
|
.then(() => {
|
||||||
|
debugLog('Application flattened, saved to: ' + opts.app);
|
||||||
|
if (cb)
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
debugLog('Flat failed:');
|
||||||
|
if (err.message)
|
||||||
|
debugLog(err.message);
|
||||||
|
else if (err.stack)
|
||||||
|
debugLog(err.stack);
|
||||||
|
else
|
||||||
|
debugLog(err);
|
||||||
|
if (cb)
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//# sourceMappingURL=flat.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"flat.js","sourceRoot":"","sources":["../../src/flat.ts"],"names":[],"mappings":"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"}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
import { sign, signApp } from './sign';
|
||||||
|
import { flat, buildPkg } from './flat';
|
||||||
|
import { walkAsync } from './util';
|
||||||
|
export { sign, flat, signApp as signAsync, signApp, buildPkg as flatAsync, buildPkg, walkAsync };
|
||||||
|
export * from './types';
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
import { sign, signApp } from './sign';
|
||||||
|
import { flat, buildPkg } from './flat';
|
||||||
|
import { walkAsync } from './util';
|
||||||
|
// TODO: Remove and leave only proper named exports, but for non-breaking change reasons
|
||||||
|
// we need to keep this weirdness for now
|
||||||
|
module.exports = sign;
|
||||||
|
module.exports.sign = sign;
|
||||||
|
module.exports.signAsync = signApp;
|
||||||
|
module.exports.signApp = signApp;
|
||||||
|
module.exports.flat = flat;
|
||||||
|
module.exports.flatAsync = buildPkg;
|
||||||
|
module.exports.buildPkg = buildPkg;
|
||||||
|
module.exports.walkAsync = walkAsync;
|
||||||
|
export { sign, flat, signApp as signAsync, signApp, buildPkg as flatAsync, buildPkg, walkAsync };
|
||||||
|
export * from './types';
|
||||||
|
//# sourceMappingURL=index.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAEnC,wFAAwF;AACxF,yCAAyC;AACzC,MAAM,CAAC,OAAO,GAAG,IAAI,CAAC;AACtB,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AAC3B,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,OAAO,CAAC;AACnC,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,OAAO,CAAC;AACjC,MAAM,CAAC,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;AAC3B,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,QAAQ,CAAC;AACpC,MAAM,CAAC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;AACnC,MAAM,CAAC,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC;AAErC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,IAAI,SAAS,EAAE,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjG,cAAc,SAAS,CAAC"}
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
import { SignOptions } from './types';
|
||||||
|
/**
|
||||||
|
* Signs a macOS application.
|
||||||
|
* @returns A void Promise once the signing operation is complete.
|
||||||
|
*
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export declare function signApp(_opts: SignOptions): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This function is a legacy callback implementation.
|
||||||
|
*
|
||||||
|
* @deprecated Please use the Promise-based {@link signAsync} method instead.
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export declare const sign: (opts: SignOptions, cb?: ((error?: Error) => void) | undefined) => void;
|
||||||
+346
@@ -0,0 +1,346 @@
|
|||||||
|
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 { debugLog, debugWarn, getAppContentsPath, execFileAsync, validateOptsApp, validateOptsPlatform, walkAsync } from './util';
|
||||||
|
import { Identity, findIdentities } from './util-identities';
|
||||||
|
import { preEmbedProvisioningProfile, getProvisioningProfile } from './util-provisioning-profiles';
|
||||||
|
import { preAutoEntitlements } from './util-entitlements';
|
||||||
|
const pkgVersion = require('../../package.json').version;
|
||||||
|
const osRelease = os.release();
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.binaries, the additional binaries to be signed along with the discovered enclosed components.
|
||||||
|
*/
|
||||||
|
async function validateOptsBinaries(opts) {
|
||||||
|
if (opts.binaries) {
|
||||||
|
if (!Array.isArray(opts.binaries)) {
|
||||||
|
throw new Error('Additional binaries should be an Array.');
|
||||||
|
}
|
||||||
|
// TODO: Presence check for binary files, reject if any does not exist
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function validateOptsIgnore(ignore) {
|
||||||
|
if (ignore && !(ignore instanceof Array)) {
|
||||||
|
return [ignore];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating all options passed in opts.
|
||||||
|
*/
|
||||||
|
async function validateSignOpts(opts) {
|
||||||
|
await validateOptsBinaries(opts);
|
||||||
|
await validateOptsApp(opts);
|
||||||
|
if (opts.provisioningProfile && typeof opts.provisioningProfile !== 'string') {
|
||||||
|
throw new Error('Path to provisioning profile should be a string.');
|
||||||
|
}
|
||||||
|
if (opts.type && opts.type !== 'development' && opts.type !== 'distribution') {
|
||||||
|
throw new Error('Type must be either `development` or `distribution`.');
|
||||||
|
}
|
||||||
|
const platform = await validateOptsPlatform(opts);
|
||||||
|
const cloned = Object.assign(Object.assign({}, opts), { ignore: validateOptsIgnore(opts.ignore), type: opts.type || 'distribution', platform });
|
||||||
|
return cloned;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise verifying the code sign of application bundle.
|
||||||
|
*/
|
||||||
|
async function verifySignApplication(opts) {
|
||||||
|
// Verify with codesign
|
||||||
|
debugLog('Verifying application bundle with codesign...');
|
||||||
|
const strictVerify = opts.strictVerify !== undefined ? opts.strictVerify : true;
|
||||||
|
await execFileAsync('codesign', ['--verify', '--deep'].concat(strictVerify !== false && compareVersion(osRelease, '15.0.0') >= 0 // Strict flag since darwin 15.0.0 --> OS X 10.11.0 El Capitan
|
||||||
|
? [
|
||||||
|
'--strict' +
|
||||||
|
(strictVerify !== true ? '=' + strictVerify : '')
|
||||||
|
]
|
||||||
|
: [], ['--verbose=2', opts.app]));
|
||||||
|
}
|
||||||
|
function defaultOptionsForFile(filePath, platform) {
|
||||||
|
const entitlementsFolder = path.resolve(__dirname, '..', '..', 'entitlements');
|
||||||
|
let entitlementsFile;
|
||||||
|
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,
|
||||||
|
signatureFlags: undefined,
|
||||||
|
timestamp: undefined,
|
||||||
|
additionalArguments: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
async function mergeOptionsForFile(opts, defaults) {
|
||||||
|
const mergedPerFileOptions = Object.assign({}, defaults);
|
||||||
|
if (opts) {
|
||||||
|
if (opts.entitlements !== undefined) {
|
||||||
|
if (Array.isArray(opts.entitlements)) {
|
||||||
|
const entitlements = opts.entitlements.reduce((dict, entitlementKey) => (Object.assign(Object.assign({}, 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;
|
||||||
|
if (opts.additionalArguments !== undefined)
|
||||||
|
mergedPerFileOptions.additionalArguments = opts.additionalArguments;
|
||||||
|
}
|
||||||
|
return mergedPerFileOptions;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise codesigning only.
|
||||||
|
*/
|
||||||
|
async function signApplication(opts, identity) {
|
||||||
|
function shouldIgnoreFilePath(filePath) {
|
||||||
|
if (opts.ignore) {
|
||||||
|
return opts.ignore.some(function (ignore) {
|
||||||
|
if (typeof ignore === 'function') {
|
||||||
|
return ignore(filePath);
|
||||||
|
}
|
||||||
|
return filePath.match(ignore);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const children = await walkAsync(getAppContentsPath(opts));
|
||||||
|
if (opts.binaries)
|
||||||
|
children.push(...opts.binaries);
|
||||||
|
const args = ['--sign', identity.hash || identity.name, '--force'];
|
||||||
|
if (opts.keychain) {
|
||||||
|
args.push('--keychain', opts.keychain);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sort the child paths by how deep they are in the file tree. Some arcane apple
|
||||||
|
* logic expects the deeper files to be signed first otherwise strange errors get
|
||||||
|
* thrown our way
|
||||||
|
*/
|
||||||
|
children.sort((a, b) => {
|
||||||
|
const aDepth = a.split(path.sep).length;
|
||||||
|
const bDepth = b.split(path.sep).length;
|
||||||
|
return bDepth - aDepth;
|
||||||
|
});
|
||||||
|
for (const filePath of [...children, opts.app]) {
|
||||||
|
if (shouldIgnoreFilePath(filePath)) {
|
||||||
|
debugLog('Skipped... ' + filePath);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const perFileOptions = await mergeOptionsForFile(opts.optionsForFile ? opts.optionsForFile(filePath) : null, defaultOptionsForFile(filePath, opts.platform));
|
||||||
|
// preAutoEntitlements should only be applied to the top level app bundle.
|
||||||
|
// Applying it other files will cause the app to crash and be rejected by Apple.
|
||||||
|
if (!filePath.includes('.app/')) {
|
||||||
|
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);
|
||||||
|
const perFileArgs = [...args];
|
||||||
|
if (perFileOptions.requirements) {
|
||||||
|
if (perFileOptions.requirements.charAt(0) === '=') {
|
||||||
|
perFileArgs.push(`-r${perFileOptions.requirements}`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
perFileArgs.push('--requirements', perFileOptions.requirements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (perFileOptions.timestamp) {
|
||||||
|
perFileArgs.push('--timestamp=' + perFileOptions.timestamp);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
perFileArgs.push('--timestamp');
|
||||||
|
}
|
||||||
|
let optionsArguments = [];
|
||||||
|
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) {
|
||||||
|
perFileArgs.push('--options', [...new Set(optionsArguments)].join(','));
|
||||||
|
}
|
||||||
|
if (perFileOptions.additionalArguments) {
|
||||||
|
perFileArgs.push(...perFileOptions.additionalArguments);
|
||||||
|
}
|
||||||
|
await execFileAsync('codesign', perFileArgs.concat('--entitlements', perFileOptions.entitlements, filePath));
|
||||||
|
}
|
||||||
|
// Verify code sign
|
||||||
|
debugLog('Verifying...');
|
||||||
|
await verifySignApplication(opts);
|
||||||
|
debugLog('Verified.');
|
||||||
|
// Check entitlements if applicable
|
||||||
|
debugLog('Displaying entitlements...');
|
||||||
|
const result = await execFileAsync('codesign', [
|
||||||
|
'--display',
|
||||||
|
'--entitlements',
|
||||||
|
':-',
|
||||||
|
opts.app
|
||||||
|
]);
|
||||||
|
debugLog('Entitlements:', '\n', result);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Signs a macOS application.
|
||||||
|
* @returns A void Promise once the signing operation is complete.
|
||||||
|
*
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export async function signApp(_opts) {
|
||||||
|
debugLog('electron-osx-sign@%s', pkgVersion);
|
||||||
|
const validatedOpts = await validateSignOpts(_opts);
|
||||||
|
let identities = [];
|
||||||
|
let identityInUse = null;
|
||||||
|
// Determine identity for signing
|
||||||
|
if (validatedOpts.identity) {
|
||||||
|
debugLog('`identity` passed in arguments.');
|
||||||
|
if (validatedOpts.identityValidation === false) {
|
||||||
|
identityInUse = new Identity(validatedOpts.identity);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
identities = await findIdentities(validatedOpts.keychain || null, validatedOpts.identity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('No `identity` passed in arguments...');
|
||||||
|
if (validatedOpts.platform === 'mas') {
|
||||||
|
if (validatedOpts.type === 'distribution') {
|
||||||
|
debugLog('Finding `3rd Party Mac Developer Application` certificate for signing app distribution in the Mac App Store...');
|
||||||
|
identities = await findIdentities(validatedOpts.keychain || null, '3rd Party Mac Developer Application:');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Finding `Mac Developer` certificate for signing app in development for the Mac App Store signing...');
|
||||||
|
identities = await findIdentities(validatedOpts.keychain || null, 'Mac Developer:');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Finding `Developer ID Application` certificate for distribution outside the Mac App Store...');
|
||||||
|
identities = await findIdentities(validatedOpts.keychain || null, 'Developer ID Application:');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!identityInUse) {
|
||||||
|
if (identities.length > 0) {
|
||||||
|
// Identity(/ies) found
|
||||||
|
if (identities.length > 1) {
|
||||||
|
debugWarn('Multiple identities found, will use the first discovered.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Found 1 identity.');
|
||||||
|
}
|
||||||
|
identityInUse = identities[0];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No identity found
|
||||||
|
throw new Error('No identity found for signing.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Pre-sign operations
|
||||||
|
if (validatedOpts.preEmbedProvisioningProfile === false) {
|
||||||
|
debugWarn('Pre-sign operation disabled for provisioning profile embedding:', '\n', '* Enable by setting `pre-embed-provisioning-profile` to `true`.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Pre-sign operation enabled for provisioning profile:', '\n', '* Disable by setting `pre-embed-provisioning-profile` to `false`.');
|
||||||
|
await preEmbedProvisioningProfile(validatedOpts, validatedOpts.provisioningProfile
|
||||||
|
? await getProvisioningProfile(validatedOpts.provisioningProfile, validatedOpts.keychain)
|
||||||
|
: null);
|
||||||
|
}
|
||||||
|
debugLog('Signing application...', '\n', '> Application:', validatedOpts.app, '\n', '> Platform:', validatedOpts.platform, '\n', '> Additional binaries:', validatedOpts.binaries, '\n', '> Identity:', validatedOpts.identity);
|
||||||
|
await signApplication(validatedOpts, identityInUse);
|
||||||
|
// Post-sign operations
|
||||||
|
debugLog('Application signed.');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function is a legacy callback implementation.
|
||||||
|
*
|
||||||
|
* @deprecated Please use the Promise-based {@link signAsync} method instead.
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export const sign = (opts, cb) => {
|
||||||
|
signApp(opts)
|
||||||
|
.then(() => {
|
||||||
|
debugLog('Application signed: ' + opts.app);
|
||||||
|
if (cb)
|
||||||
|
cb();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
if (err.message)
|
||||||
|
debugLog(err.message);
|
||||||
|
else if (err.stack)
|
||||||
|
debugLog(err.stack);
|
||||||
|
else
|
||||||
|
debugLog(err);
|
||||||
|
if (cb)
|
||||||
|
cb(err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
//# sourceMappingURL=sign.js.map
|
||||||
+1
File diff suppressed because one or more lines are too long
+258
@@ -0,0 +1,258 @@
|
|||||||
|
/**
|
||||||
|
* macOS applications can be distributed via the Mac App Store (MAS) or directly
|
||||||
|
* downloaded from the developer's website. @electron/osx-sign distinguishes between
|
||||||
|
* MAS apps (`mas`) or non-MAS apps (`darwin`).
|
||||||
|
* @category Utility
|
||||||
|
*/
|
||||||
|
export type ElectronMacPlatform = 'darwin' | 'mas';
|
||||||
|
/**
|
||||||
|
* MAS apps can be signed using Development or Distribution certificates.
|
||||||
|
|
||||||
|
* See [Apple Documentation](https://developer.apple.com/help/account/create-certificates/certificates-overview/) for more info.
|
||||||
|
* @category Utility
|
||||||
|
*/
|
||||||
|
export type SigningDistributionType = 'development' | 'distribution';
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export type BaseSignOptions = Readonly<{
|
||||||
|
/**
|
||||||
|
* Path to the application package.
|
||||||
|
* Needs to end with the file extension `.app`.
|
||||||
|
*/
|
||||||
|
app: string;
|
||||||
|
/**
|
||||||
|
* The keychain name.
|
||||||
|
*
|
||||||
|
* @defaultValue `login`
|
||||||
|
*/
|
||||||
|
keychain?: string;
|
||||||
|
/**
|
||||||
|
* Build platform of your Electron app.
|
||||||
|
* Allowed values: `darwin` (Direct Download App), `mas` (Mac App Store).
|
||||||
|
*
|
||||||
|
* @defaultValue Determined by presence of `Squirrel.framework` within the application bundle,
|
||||||
|
* which is used for non-MAS apps.
|
||||||
|
*/
|
||||||
|
platform?: ElectronMacPlatform;
|
||||||
|
/**
|
||||||
|
* Name of the certificate to use when signing.
|
||||||
|
*
|
||||||
|
* @defaultValue Selected with respect to {@link SignOptions.provisioningProfile | provisioningProfile}
|
||||||
|
* and {@link SignOptions.platform | platform} from the selected {@link SignOptions.keychain | keychain}.
|
||||||
|
* * `mas` will look for `3rd Party Mac Developer Application: * (*)`
|
||||||
|
* * `darwin` will look for `Developer ID Application: * (*)` by default.
|
||||||
|
*/
|
||||||
|
identity?: string;
|
||||||
|
}>;
|
||||||
|
type OnlyValidatedBaseSignOptions = {
|
||||||
|
platform: ElectronMacPlatform;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* A set of signing options that can be overriden on a per-file basis.
|
||||||
|
* Any missing options will use the default values, and providing a partial structure
|
||||||
|
* will shallow merge with the default values.
|
||||||
|
* @interface
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export type PerFileSignOptions = {
|
||||||
|
/**
|
||||||
|
* String specifying the path to an `entitlements.plist` file.
|
||||||
|
* Can also be an array of entitlement keys that osx-sign will write to an entitlements file for you.
|
||||||
|
*
|
||||||
|
* @defaultValue `@electron/osx-sign`'s built-in entitlements files.
|
||||||
|
*/
|
||||||
|
entitlements?: string | string[];
|
||||||
|
/**
|
||||||
|
* Whether to enable [Hardened Runtime](https://developer.apple.com/documentation/security/hardened_runtime)
|
||||||
|
* for this file.
|
||||||
|
*
|
||||||
|
* Note: Hardened Runtime is a pre-requisite for notarization, which is mandatory for apps running on macOS 10.15 and above.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
hardenedRuntime?: boolean;
|
||||||
|
/**
|
||||||
|
* Either a string beginning with `=` which specifies in plain text the
|
||||||
|
* [signing 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, or a string specifying a path to a text or
|
||||||
|
* properly encoded `.rqset` file which contains those requirements.
|
||||||
|
*/
|
||||||
|
requirements?: string;
|
||||||
|
/**
|
||||||
|
* When signing, a set of option flags can be specified to change the behavior of the system when using the signed code.
|
||||||
|
* Accepts an array of strings or a comma-separated string.
|
||||||
|
*
|
||||||
|
* See --options of the `codesign` command.
|
||||||
|
*
|
||||||
|
* https://keith.github.io/xcode-man-pages/codesign.1.html#OPTION_FLAGS
|
||||||
|
*/
|
||||||
|
signatureFlags?: string | string[];
|
||||||
|
/**
|
||||||
|
* String specifying the URL of the timestamp authority server.
|
||||||
|
* Please note that this default server may not support signatures not furnished by Apple.
|
||||||
|
* Disable the timestamp service with `none`.
|
||||||
|
*
|
||||||
|
* @defaultValue Uses the Apple-provided timestamp server.
|
||||||
|
*/
|
||||||
|
timestamp?: string;
|
||||||
|
/**
|
||||||
|
* Additional raw arguments to pass to the `codesign` command.
|
||||||
|
*
|
||||||
|
* These can be things like `--deep` for instance when code signing specific resources that may
|
||||||
|
* require such arguments.
|
||||||
|
*
|
||||||
|
* https://keith.github.io/xcode-man-pages/codesign.1.html#OPTIONS
|
||||||
|
*/
|
||||||
|
additionalArguments?: string[];
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @interface
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export type OnlySignOptions = {
|
||||||
|
/**
|
||||||
|
* Array of paths to additional binaries that will be signed along with built-ins of Electron.
|
||||||
|
*
|
||||||
|
* @defaultValue `undefined`
|
||||||
|
*/
|
||||||
|
binaries?: string[];
|
||||||
|
/**
|
||||||
|
* 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. Any properties that are returned **override** the default
|
||||||
|
* values that `@electron/osx-sign` generates. Any properties not returned use the default value.
|
||||||
|
*
|
||||||
|
* @param filePath Path to file
|
||||||
|
* @returns Override signing options
|
||||||
|
*/
|
||||||
|
optionsForFile?: (filePath: string) => PerFileSignOptions;
|
||||||
|
/**
|
||||||
|
* Flag to enable/disable validation for the signing identity.
|
||||||
|
* If enabled, the {@link SignOptions.identity | identity} provided
|
||||||
|
* will be validated in the {@link BaseSignOptions.keychain | keychain} specified.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
identityValidation?: boolean;
|
||||||
|
/**
|
||||||
|
* Defines files that will be skipped during the code signing process.
|
||||||
|
* This property accepts a regex, function or an array of regexes and functions.
|
||||||
|
* Elements of other types are treated as `RegExp`.
|
||||||
|
*
|
||||||
|
* File paths matching a regex or returning a `true` value from a function will be ignored.
|
||||||
|
*
|
||||||
|
* @defaultValue `undefined`
|
||||||
|
*/
|
||||||
|
ignore?: string | string[] | ((file: string) => boolean);
|
||||||
|
/**
|
||||||
|
* Flag to enable/disable entitlements automation tasks necessary for code signing most Electron apps.
|
||||||
|
* * Adds [`com.apple.security.application-groups`](https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_security_application-groups) to the entitlements file
|
||||||
|
* * Fills in the `ElectronTeamID` property in `Info.plist` with the provisioning profile's Team Identifier or by parsing the identity name.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
preAutoEntitlements?: boolean;
|
||||||
|
/**
|
||||||
|
* Flag to enable/disable the embedding of a provisioning profile into the app's `Contents` folder.
|
||||||
|
* Will use the profile from {@link OnlySignOptions.provisioningProfile} if provided. Otherwise, it
|
||||||
|
* searches for a `.provisionprofile` file in the current working directory.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
preEmbedProvisioningProfile?: boolean;
|
||||||
|
/**
|
||||||
|
* Path to a provisioning profile, which can be used to grant restricted entitlements to your app.
|
||||||
|
*
|
||||||
|
* See [Apple Documentation](https://developer.apple.com/documentation/technotes/tn3125-inside-code-signing-provisioning-profiles) for more details.
|
||||||
|
*/
|
||||||
|
provisioningProfile?: string;
|
||||||
|
/**
|
||||||
|
* Flag to enable/disable the `--strict` flag when verifying the signed application bundle.
|
||||||
|
* Also supports string values to specify which strict restrictions to use, see codesign man page for supported values.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
strictVerify?: boolean | string;
|
||||||
|
/**
|
||||||
|
* Type of certificate to use when signing a MAS app.
|
||||||
|
* @defaultValue `"distribution"`
|
||||||
|
*/
|
||||||
|
type?: SigningDistributionType;
|
||||||
|
/**
|
||||||
|
* Build version of Electron. Values may be like: `1.1.1`, `1.2.0`. For use for signing legacy versions
|
||||||
|
* of Electron to ensure backwards compatibility.
|
||||||
|
*/
|
||||||
|
version?: string;
|
||||||
|
};
|
||||||
|
type OnlyValidatedSignOptions = {
|
||||||
|
ignore?: (string | ((file: string) => boolean))[];
|
||||||
|
type: SigningDistributionType;
|
||||||
|
};
|
||||||
|
type OnlyFlatOptions = {
|
||||||
|
/**
|
||||||
|
* Flag to enable/disable validation for the signing identity.
|
||||||
|
* If enabled, the {@link BaseSignOptions.identity | identity} provided
|
||||||
|
* will be validated in the {@link BaseSignOptions.keychain | keychain} specified.
|
||||||
|
*
|
||||||
|
* @defaultValue `true`
|
||||||
|
*/
|
||||||
|
identityValidation?: boolean;
|
||||||
|
/**
|
||||||
|
* Path to install the bundle.
|
||||||
|
* @defaultValue `"/Applications"`
|
||||||
|
*/
|
||||||
|
install?: string;
|
||||||
|
/**
|
||||||
|
* Output path for the flattened installer package.
|
||||||
|
* Needs file extension `.pkg`.
|
||||||
|
*
|
||||||
|
* @defaultValue Inferred from the app name passed into `opts.app`.
|
||||||
|
*/
|
||||||
|
pkg?: string;
|
||||||
|
/**
|
||||||
|
* Path to a directory containing `preinstall.sh` or `postinstall.sh` scripts.
|
||||||
|
* These must be executable and will run on pre/postinstall depending on the file
|
||||||
|
* name.
|
||||||
|
*
|
||||||
|
* This option is only valid if {@link FlatOptions.platform} is set to `darwin`.
|
||||||
|
*/
|
||||||
|
scripts?: string;
|
||||||
|
};
|
||||||
|
type OnlyValidatedFlatOptions = {
|
||||||
|
install: string;
|
||||||
|
pkg: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Utility type that represents an `UnValidated` type after validation,
|
||||||
|
* replacing any properties in the unvalidated type that also exist in the
|
||||||
|
* `Validated` type with the validated versions.
|
||||||
|
*
|
||||||
|
* @template UnValidated - The type representing the unvalidated form.
|
||||||
|
* @template Validated - The type representing the validated form.
|
||||||
|
*/
|
||||||
|
type ValidatedForm<UnValidated, Validated> = Omit<UnValidated, keyof Validated> & Validated;
|
||||||
|
type ValidatedBaseSignOptions = Readonly<ValidatedForm<BaseSignOptions, OnlyValidatedBaseSignOptions>>;
|
||||||
|
type _SignOptions = Readonly<OnlySignOptions & BaseSignOptions>;
|
||||||
|
/**
|
||||||
|
* Options for codesigning a packaged `.app` bundle.
|
||||||
|
* @category Codesign
|
||||||
|
*/
|
||||||
|
export interface SignOptions extends _SignOptions {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export type ValidatedSignOptions = Readonly<ValidatedForm<OnlySignOptions, OnlyValidatedSignOptions> & ValidatedBaseSignOptions>;
|
||||||
|
type _FlatOptions = Readonly<OnlyFlatOptions & BaseSignOptions>;
|
||||||
|
/**
|
||||||
|
* Options for creating a flat `.pkg` installer.
|
||||||
|
* @category Flat
|
||||||
|
*/
|
||||||
|
export interface FlatOptions extends _FlatOptions {
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export type ValidatedFlatOptions = Readonly<ValidatedForm<OnlyFlatOptions, OnlyValidatedFlatOptions> & ValidatedBaseSignOptions>;
|
||||||
|
export {};
|
||||||
+2
@@ -0,0 +1,2 @@
|
|||||||
|
export {};
|
||||||
|
//# sourceMappingURL=types.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
import { PerFileSignOptions, ValidatedSignOptions } from './types';
|
||||||
|
import { Identity } from './util-identities';
|
||||||
|
import { ProvisioningProfile } from './util-provisioning-profiles';
|
||||||
|
type ComputedOptions = {
|
||||||
|
identity: Identity;
|
||||||
|
provisioningProfile?: ProvisioningProfile;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* This function returns a promise completing the entitlements automation: The
|
||||||
|
* process includes checking in `Info.plist` for `ElectronTeamID` or setting
|
||||||
|
* parsed value from identity, and checking in entitlements file for
|
||||||
|
* `com.apple.security.application-groups` or inserting new into array. A
|
||||||
|
* temporary entitlements file may be created to replace the input for any
|
||||||
|
* changes introduced.
|
||||||
|
*/
|
||||||
|
export declare function preAutoEntitlements(opts: ValidatedSignOptions, perFileOpts: PerFileSignOptions, computed: ComputedOptions): Promise<void | string>;
|
||||||
|
export {};
|
||||||
+106
@@ -0,0 +1,106 @@
|
|||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as os from 'os';
|
||||||
|
import * as path from 'path';
|
||||||
|
import * as plist from 'plist';
|
||||||
|
import { debugLog, getAppContentsPath } from './util';
|
||||||
|
const preAuthMemo = new Map();
|
||||||
|
/**
|
||||||
|
* This function returns a promise completing the entitlements automation: The
|
||||||
|
* process includes checking in `Info.plist` for `ElectronTeamID` or setting
|
||||||
|
* parsed value from identity, and checking in entitlements file for
|
||||||
|
* `com.apple.security.application-groups` or inserting new into array. A
|
||||||
|
* temporary entitlements file may be created to replace the input for any
|
||||||
|
* changes introduced.
|
||||||
|
*/
|
||||||
|
export async function preAutoEntitlements(opts, perFileOpts, computed) {
|
||||||
|
var _a;
|
||||||
|
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');
|
||||||
|
debugLog('Automating entitlement app group...', '\n', '> Info.plist:', appInfoPath, '\n');
|
||||||
|
let entitlements;
|
||||||
|
if (typeof perFileOpts.entitlements === 'string') {
|
||||||
|
const entitlementsContents = await fs.readFile(perFileOpts.entitlements, 'utf8');
|
||||||
|
entitlements = plist.parse(entitlementsContents);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
entitlements = perFileOpts.entitlements.reduce((dict, entitlementKey) => (Object.assign(Object.assign({}, dict), { [entitlementKey]: true })), {});
|
||||||
|
}
|
||||||
|
if (!entitlements['com.apple.security.app-sandbox']) {
|
||||||
|
// Only automate when app sandbox enabled by user
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const appInfoContents = await fs.readFile(appInfoPath, 'utf8');
|
||||||
|
const appInfo = plist.parse(appInfoContents);
|
||||||
|
// Use ElectronTeamID in Info.plist if already specified
|
||||||
|
if (appInfo.ElectronTeamID) {
|
||||||
|
debugLog('`ElectronTeamID` found in `Info.plist`: ' + appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// The team identifier in signing identity should not be trusted
|
||||||
|
if (computed.provisioningProfile) {
|
||||||
|
appInfo.ElectronTeamID =
|
||||||
|
computed.provisioningProfile.message.Entitlements['com.apple.developer.team-identifier'];
|
||||||
|
debugLog('`ElectronTeamID` not found in `Info.plist`, use parsed from provisioning profile: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const teamID = (_a = /^.+\((.+?)\)$/g.exec(computed.identity.name)) === null || _a === void 0 ? void 0 : _a[1];
|
||||||
|
if (!teamID) {
|
||||||
|
throw new Error(`Could not automatically determine ElectronTeamID from identity: ${computed.identity.name}`);
|
||||||
|
}
|
||||||
|
appInfo.ElectronTeamID = teamID;
|
||||||
|
debugLog('`ElectronTeamID` not found in `Info.plist`, use parsed from signing identity: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
}
|
||||||
|
await fs.writeFile(appInfoPath, plist.build(appInfo), 'utf8');
|
||||||
|
debugLog('`Info.plist` updated:', '\n', '> Info.plist:', appInfoPath);
|
||||||
|
}
|
||||||
|
const appIdentifier = appInfo.ElectronTeamID + '.' + appInfo.CFBundleIdentifier;
|
||||||
|
// Insert application identifier if not exists
|
||||||
|
if (entitlements['com.apple.application-identifier']) {
|
||||||
|
debugLog('`com.apple.application-identifier` found in entitlements file: ' +
|
||||||
|
entitlements['com.apple.application-identifier']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('`com.apple.application-identifier` not found in entitlements file, new inserted: ' +
|
||||||
|
appIdentifier);
|
||||||
|
entitlements['com.apple.application-identifier'] = appIdentifier;
|
||||||
|
}
|
||||||
|
// Insert developer team identifier if not exists
|
||||||
|
if (entitlements['com.apple.developer.team-identifier']) {
|
||||||
|
debugLog('`com.apple.developer.team-identifier` found in entitlements file: ' +
|
||||||
|
entitlements['com.apple.developer.team-identifier']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('`com.apple.developer.team-identifier` not found in entitlements file, new inserted: ' +
|
||||||
|
appInfo.ElectronTeamID);
|
||||||
|
entitlements['com.apple.developer.team-identifier'] = appInfo.ElectronTeamID;
|
||||||
|
}
|
||||||
|
// Init entitlements app group key to array if not exists
|
||||||
|
if (!entitlements['com.apple.security.application-groups']) {
|
||||||
|
entitlements['com.apple.security.application-groups'] = [];
|
||||||
|
}
|
||||||
|
// Insert app group if not exists
|
||||||
|
if (Array.isArray(entitlements['com.apple.security.application-groups']) &&
|
||||||
|
entitlements['com.apple.security.application-groups'].indexOf(appIdentifier) === -1) {
|
||||||
|
debugLog('`com.apple.security.application-groups` not found in entitlements file, new inserted: ' +
|
||||||
|
appIdentifier);
|
||||||
|
entitlements['com.apple.security.application-groups'].push(appIdentifier);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('`com.apple.security.application-groups` found in entitlements file: ' + appIdentifier);
|
||||||
|
}
|
||||||
|
// Create temporary entitlements file
|
||||||
|
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');
|
||||||
|
debugLog('Entitlements file updated:', '\n', '> Entitlements:', entitlementsPath);
|
||||||
|
preAuthMemo.set(memoKey, entitlementsPath);
|
||||||
|
return entitlementsPath;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=util-entitlements.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-entitlements.js","sourceRoot":"","sources":["../../src/util-entitlements.ts"],"names":[],"mappings":"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"}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
export declare class Identity {
|
||||||
|
name: string;
|
||||||
|
hash?: string | undefined;
|
||||||
|
constructor(name: string, hash?: string | undefined);
|
||||||
|
}
|
||||||
|
export declare function findIdentities(keychain: string | null, identity: string): Promise<Identity[]>;
|
||||||
+30
@@ -0,0 +1,30 @@
|
|||||||
|
import { debugLog, compactFlattenedList, execFileAsync } from './util';
|
||||||
|
export class Identity {
|
||||||
|
constructor(name, hash) {
|
||||||
|
this.name = name;
|
||||||
|
this.hash = hash;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export async function findIdentities(keychain, identity) {
|
||||||
|
// Only to look for valid identities, excluding those flagged with
|
||||||
|
// CSSMERR_TP_CERT_EXPIRED or CSSMERR_TP_NOT_TRUSTED. Fixes #9
|
||||||
|
const args = [
|
||||||
|
'find-identity',
|
||||||
|
'-v'
|
||||||
|
];
|
||||||
|
if (keychain) {
|
||||||
|
args.push(keychain);
|
||||||
|
}
|
||||||
|
const result = await execFileAsync('security', args);
|
||||||
|
const identities = result.split('\n').map(function (line) {
|
||||||
|
if (line.indexOf(identity) >= 0) {
|
||||||
|
const identityFound = line.substring(line.indexOf('"') + 1, line.lastIndexOf('"'));
|
||||||
|
const identityHashFound = line.substring(line.indexOf(')') + 2, line.indexOf('"') - 1);
|
||||||
|
debugLog('Identity:', '\n', '> Name:', identityFound, '\n', '> Hash:', identityHashFound);
|
||||||
|
return new Identity(identityFound, identityHashFound);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
return compactFlattenedList(identities);
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=util-identities.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-identities.js","sourceRoot":"","sources":["../../src/util-identities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvE,MAAM,OAAO,QAAQ;IACnB,YAAoB,IAAY,EAAS,IAAa;QAAlC,SAAI,GAAJ,IAAI,CAAQ;QAAS,SAAI,GAAJ,IAAI,CAAS;IAAG,CAAC;CAC3D;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAE,QAAuB,EAAE,QAAgB;IAC7E,kEAAkE;IAClE,8DAA8D;IAE9D,MAAM,IAAI,GAAG;QACX,eAAe;QACf,IAAI;KACL,CAAC;IACF,IAAI,QAAQ,EAAE;QACZ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;KACrB;IAED,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IACrD,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,IAAI;QACtD,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE;YAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACnF,MAAM,iBAAiB,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACvF,QAAQ,CAAC,WAAW,EAAE,IAAI,EACxB,SAAS,EAAE,aAAa,EAAE,IAAI,EAC9B,SAAS,EAAE,iBAAiB,CAAC,CAAC;YAChC,OAAO,IAAI,QAAQ,CAAC,aAAa,EAAE,iBAAiB,CAAC,CAAC;SACvD;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;IAEH,OAAO,oBAAoB,CAAC,UAAU,CAAC,CAAC;AAC1C,CAAC"}
|
||||||
+25
@@ -0,0 +1,25 @@
|
|||||||
|
import { ElectronMacPlatform, ValidatedSignOptions } from './types';
|
||||||
|
export declare class ProvisioningProfile {
|
||||||
|
filePath: string;
|
||||||
|
message: any;
|
||||||
|
constructor(filePath: string, message: any);
|
||||||
|
get name(): string;
|
||||||
|
get platforms(): ElectronMacPlatform[];
|
||||||
|
get type(): "development" | "distribution";
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a ProvisioningProfile instance based on file.
|
||||||
|
* @function
|
||||||
|
* @param {string} filePath - Path to provisioning profile.
|
||||||
|
* @param {string} keychain - Keychain to use when unlocking provisioning profile.
|
||||||
|
* @returns {Promise} Promise.
|
||||||
|
*/
|
||||||
|
export declare function getProvisioningProfile(filePath: string, keychain?: string | null): Promise<ProvisioningProfile>;
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a list of suitable provisioning profile within the current working directory.
|
||||||
|
*/
|
||||||
|
export declare function findProvisioningProfiles(opts: ValidatedSignOptions): Promise<ProvisioningProfile[]>;
|
||||||
|
/**
|
||||||
|
* Returns a promise embedding the provisioning profile in the app Contents folder.
|
||||||
|
*/
|
||||||
|
export declare function preEmbedProvisioningProfile(opts: ValidatedSignOptions, profile: ProvisioningProfile | null): Promise<void>;
|
||||||
+115
@@ -0,0 +1,115 @@
|
|||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import * as path from 'path';
|
||||||
|
import plist from 'plist';
|
||||||
|
import { debugLog, debugWarn, getAppContentsPath, compactFlattenedList, execFileAsync } from './util';
|
||||||
|
export class ProvisioningProfile {
|
||||||
|
constructor(filePath, message) {
|
||||||
|
this.filePath = filePath;
|
||||||
|
this.message = message;
|
||||||
|
}
|
||||||
|
get name() {
|
||||||
|
return this.message.Name;
|
||||||
|
}
|
||||||
|
get platforms() {
|
||||||
|
if ('ProvisionsAllDevices' in this.message)
|
||||||
|
return ['darwin'];
|
||||||
|
// Developer ID
|
||||||
|
else if (this.type === 'distribution')
|
||||||
|
return ['mas'];
|
||||||
|
// Mac App Store
|
||||||
|
else
|
||||||
|
return ['darwin', 'mas']; // Mac App Development
|
||||||
|
}
|
||||||
|
get type() {
|
||||||
|
if ('ProvisionedDevices' in this.message)
|
||||||
|
return 'development';
|
||||||
|
// Mac App Development
|
||||||
|
else
|
||||||
|
return 'distribution'; // Developer ID or Mac App Store
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a ProvisioningProfile instance based on file.
|
||||||
|
* @function
|
||||||
|
* @param {string} filePath - Path to provisioning profile.
|
||||||
|
* @param {string} keychain - Keychain to use when unlocking provisioning profile.
|
||||||
|
* @returns {Promise} Promise.
|
||||||
|
*/
|
||||||
|
export async function getProvisioningProfile(filePath, keychain = null) {
|
||||||
|
const securityArgs = [
|
||||||
|
'cms',
|
||||||
|
'-D',
|
||||||
|
'-i',
|
||||||
|
filePath // Use infile as source of data
|
||||||
|
];
|
||||||
|
if (keychain) {
|
||||||
|
securityArgs.push('-k', keychain);
|
||||||
|
}
|
||||||
|
const result = await execFileAsync('security', securityArgs);
|
||||||
|
const provisioningProfile = new ProvisioningProfile(filePath, plist.parse(result));
|
||||||
|
debugLog('Provisioning profile:', '\n', '> Name:', provisioningProfile.name, '\n', '> Platforms:', provisioningProfile.platforms, '\n', '> Type:', provisioningProfile.type, '\n', '> Path:', provisioningProfile.filePath, '\n', '> Message:', provisioningProfile.message);
|
||||||
|
return provisioningProfile;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a promise resolving to a list of suitable provisioning profile within the current working directory.
|
||||||
|
*/
|
||||||
|
export async function findProvisioningProfiles(opts) {
|
||||||
|
const cwd = process.cwd();
|
||||||
|
const children = await fs.readdir(cwd);
|
||||||
|
const foundProfiles = compactFlattenedList(await Promise.all(children.map(async (child) => {
|
||||||
|
const filePath = path.resolve(cwd, child);
|
||||||
|
const stat = await fs.stat(filePath);
|
||||||
|
if (stat.isFile() && path.extname(filePath) === '.provisionprofile') {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
return compactFlattenedList(await Promise.all(foundProfiles.map(async (filePath) => {
|
||||||
|
const profile = await getProvisioningProfile(filePath);
|
||||||
|
if (profile.platforms.indexOf(opts.platform) >= 0 && profile.type === opts.type) {
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
debugWarn('Provisioning profile above ignored, not for ' + opts.platform + ' ' + opts.type + '.');
|
||||||
|
return null;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns a promise embedding the provisioning profile in the app Contents folder.
|
||||||
|
*/
|
||||||
|
export async function preEmbedProvisioningProfile(opts, profile) {
|
||||||
|
async function embedProvisioningProfile(profile) {
|
||||||
|
debugLog('Looking for existing provisioning profile...');
|
||||||
|
const embeddedFilePath = path.join(getAppContentsPath(opts), 'embedded.provisionprofile');
|
||||||
|
if (await fs.pathExists(embeddedFilePath)) {
|
||||||
|
debugLog('Found embedded provisioning profile:', '\n', '* Please manually remove the existing file if not wanted.', '\n', '* Current file at:', embeddedFilePath);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Embedding provisioning profile...');
|
||||||
|
await fs.copy(profile.filePath, embeddedFilePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (profile) {
|
||||||
|
// User input provisioning profile
|
||||||
|
return await embedProvisioningProfile(profile);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Discover provisioning profile
|
||||||
|
debugLog('No `provisioning-profile` passed in arguments, will find in current working directory and in user library...');
|
||||||
|
const profiles = await findProvisioningProfiles(opts);
|
||||||
|
if (profiles.length > 0) {
|
||||||
|
// Provisioning profile(s) found
|
||||||
|
if (profiles.length > 1) {
|
||||||
|
debugLog('Multiple provisioning profiles found, will use the first discovered.');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugLog('Found 1 provisioning profile.');
|
||||||
|
}
|
||||||
|
await embedProvisioningProfile(profiles[0]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No provisioning profile found
|
||||||
|
debugLog('No provisioning profile found, will not embed profile in app contents.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=util-provisioning-profiles.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util-provisioning-profiles.js","sourceRoot":"","sources":["../../src/util-provisioning-profiles.ts"],"names":[],"mappings":"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"}
|
||||||
+36
@@ -0,0 +1,36 @@
|
|||||||
|
/// <reference types="node" />
|
||||||
|
import * as child from 'child_process';
|
||||||
|
import debug from 'debug';
|
||||||
|
import { BaseSignOptions, ElectronMacPlatform } from './types';
|
||||||
|
export declare const debugLog: debug.Debugger;
|
||||||
|
export declare const debugWarn: debug.Debugger;
|
||||||
|
export declare function execFileAsync(file: string, args: string[], options?: child.ExecFileOptions): Promise<string>;
|
||||||
|
type DeepListItem<T> = null | T | DeepListItem<T>[];
|
||||||
|
type DeepList<T> = DeepListItem<T>[];
|
||||||
|
export declare function compactFlattenedList<T>(list: DeepList<T>): T[];
|
||||||
|
/**
|
||||||
|
* Returns the path to the "Contents" folder inside the application bundle
|
||||||
|
*/
|
||||||
|
export declare function getAppContentsPath(opts: BaseSignOptions): string;
|
||||||
|
/**
|
||||||
|
* Returns the path to app "Frameworks" within contents.
|
||||||
|
*/
|
||||||
|
export declare function getAppFrameworksPath(opts: BaseSignOptions): string;
|
||||||
|
export declare function detectElectronPlatform(opts: BaseSignOptions): Promise<ElectronMacPlatform>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.app, the application to be signed or flattened.
|
||||||
|
*/
|
||||||
|
export declare function validateOptsApp(opts: BaseSignOptions): Promise<void>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.platform, the platform of Electron build. It allows auto-discovery if no opts.platform is specified.
|
||||||
|
*/
|
||||||
|
export declare function validateOptsPlatform(opts: BaseSignOptions): Promise<ElectronMacPlatform>;
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving all child paths within the directory specified.
|
||||||
|
* @function
|
||||||
|
* @param {string} dirPath - Path to directory.
|
||||||
|
* @returns {Promise} Promise resolving child paths needing signing in order.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export declare function walkAsync(dirPath: string): Promise<string[]>;
|
||||||
|
export {};
|
||||||
+146
@@ -0,0 +1,146 @@
|
|||||||
|
import * as child from 'child_process';
|
||||||
|
import * as fs from 'fs-extra';
|
||||||
|
import { isBinaryFile } from 'isbinaryfile';
|
||||||
|
import * as path from 'path';
|
||||||
|
import debug from 'debug';
|
||||||
|
export const debugLog = debug('electron-osx-sign');
|
||||||
|
debugLog.log = console.log.bind(console);
|
||||||
|
export const debugWarn = debug('electron-osx-sign:warn');
|
||||||
|
debugWarn.log = console.warn.bind(console);
|
||||||
|
const removePassword = function (input) {
|
||||||
|
return input.replace(/(-P |pass:|\/p|-pass )([^ ]+)/, function (_, p1) {
|
||||||
|
return `${p1}***`;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
export async function execFileAsync(file, args, options = {}) {
|
||||||
|
if (debugLog.enabled) {
|
||||||
|
debugLog('Executing...', file, args && Array.isArray(args) ? removePassword(args.join(' ')) : '');
|
||||||
|
}
|
||||||
|
return new Promise(function (resolve, reject) {
|
||||||
|
child.execFile(file, args, options, function (err, stdout, stderr) {
|
||||||
|
if (err) {
|
||||||
|
debugLog('Error executing file:', '\n', '> Stdout:', stdout, '\n', '> Stderr:', stderr);
|
||||||
|
reject(err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
resolve(stdout);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
export function compactFlattenedList(list) {
|
||||||
|
const result = [];
|
||||||
|
function populateResult(list) {
|
||||||
|
if (!Array.isArray(list)) {
|
||||||
|
if (list)
|
||||||
|
result.push(list);
|
||||||
|
}
|
||||||
|
else if (list.length > 0) {
|
||||||
|
for (const item of list)
|
||||||
|
if (item)
|
||||||
|
populateResult(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
populateResult(list);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the path to the "Contents" folder inside the application bundle
|
||||||
|
*/
|
||||||
|
export function getAppContentsPath(opts) {
|
||||||
|
return path.join(opts.app, 'Contents');
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Returns the path to app "Frameworks" within contents.
|
||||||
|
*/
|
||||||
|
export function getAppFrameworksPath(opts) {
|
||||||
|
return path.join(getAppContentsPath(opts), 'Frameworks');
|
||||||
|
}
|
||||||
|
export async function detectElectronPlatform(opts) {
|
||||||
|
const appFrameworksPath = getAppFrameworksPath(opts);
|
||||||
|
if (await fs.pathExists(path.resolve(appFrameworksPath, 'Squirrel.framework'))) {
|
||||||
|
return 'darwin';
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 'mas';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving the file path if file binary.
|
||||||
|
*/
|
||||||
|
async function getFilePathIfBinary(filePath) {
|
||||||
|
if (await isBinaryFile(filePath)) {
|
||||||
|
return filePath;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.app, the application to be signed or flattened.
|
||||||
|
*/
|
||||||
|
export async function validateOptsApp(opts) {
|
||||||
|
if (!opts.app) {
|
||||||
|
throw new Error('Path to application must be specified.');
|
||||||
|
}
|
||||||
|
if (path.extname(opts.app) !== '.app') {
|
||||||
|
throw new Error('Extension of application must be `.app`.');
|
||||||
|
}
|
||||||
|
if (!(await fs.pathExists(opts.app))) {
|
||||||
|
throw new Error(`Application at path "${opts.app}" could not be found`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise validating opts.platform, the platform of Electron build. It allows auto-discovery if no opts.platform is specified.
|
||||||
|
*/
|
||||||
|
export async function validateOptsPlatform(opts) {
|
||||||
|
if (opts.platform) {
|
||||||
|
if (opts.platform === 'mas' || opts.platform === 'darwin') {
|
||||||
|
return opts.platform;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('`platform` passed in arguments not supported, checking Electron platform...');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
debugWarn('No `platform` passed in arguments, checking Electron platform...');
|
||||||
|
}
|
||||||
|
return await detectElectronPlatform(opts);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* This function returns a promise resolving all child paths within the directory specified.
|
||||||
|
* @function
|
||||||
|
* @param {string} dirPath - Path to directory.
|
||||||
|
* @returns {Promise} Promise resolving child paths needing signing in order.
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
export async function walkAsync(dirPath) {
|
||||||
|
debugLog('Walking... ' + dirPath);
|
||||||
|
async function _walkAsync(dirPath) {
|
||||||
|
const children = await fs.readdir(dirPath);
|
||||||
|
return await Promise.all(children.map(async (child) => {
|
||||||
|
const filePath = path.resolve(dirPath, child);
|
||||||
|
const stat = await fs.stat(filePath);
|
||||||
|
if (stat.isFile()) {
|
||||||
|
switch (path.extname(filePath)) {
|
||||||
|
case '.cstemp': // Temporary file generated from past codesign
|
||||||
|
debugLog('Removing... ' + filePath);
|
||||||
|
await fs.remove(filePath);
|
||||||
|
return null;
|
||||||
|
default:
|
||||||
|
return await getFilePathIfBinary(filePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (stat.isDirectory() && !stat.isSymbolicLink()) {
|
||||||
|
const walkResult = await _walkAsync(filePath);
|
||||||
|
switch (path.extname(filePath)) {
|
||||||
|
case '.app': // Application
|
||||||
|
case '.framework': // Framework
|
||||||
|
walkResult.push(filePath);
|
||||||
|
}
|
||||||
|
return walkResult;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
const allPaths = await _walkAsync(dirPath);
|
||||||
|
return compactFlattenedList(allPaths);
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=util.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/util.ts"],"names":[],"mappings":"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"}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?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/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
+20
@@ -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>
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<?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-unsigned-executable-memory</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.cs.disable-library-validation</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
<?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/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
<?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.inherit</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
+22
@@ -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>
|
||||||
+80
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"name": "@electron/osx-sign",
|
||||||
|
"version": "1.3.3",
|
||||||
|
"description": "Codesign Electron macOS apps",
|
||||||
|
"main": "dist/cjs/index.js",
|
||||||
|
"module": "dist/esm/index.js",
|
||||||
|
"files": [
|
||||||
|
"dist",
|
||||||
|
"entitlements",
|
||||||
|
"README.md",
|
||||||
|
"LICENSE",
|
||||||
|
"bin"
|
||||||
|
],
|
||||||
|
"bin": {
|
||||||
|
"electron-osx-flat": "bin/electron-osx-flat.js",
|
||||||
|
"electron-osx-sign": "bin/electron-osx-sign.js"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/electron/osx-sign.git"
|
||||||
|
},
|
||||||
|
"author": "electron",
|
||||||
|
"license": "BSD-2-Clause",
|
||||||
|
"publishConfig": {
|
||||||
|
"provenance": true
|
||||||
|
},
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/electron/osx-sign/issues"
|
||||||
|
},
|
||||||
|
"homepage": "https://github.com/electron/osx-sign",
|
||||||
|
"dependencies": {
|
||||||
|
"compare-version": "^0.1.2",
|
||||||
|
"debug": "^4.3.4",
|
||||||
|
"fs-extra": "^10.0.0",
|
||||||
|
"isbinaryfile": "^4.0.8",
|
||||||
|
"minimist": "^1.2.6",
|
||||||
|
"plist": "^3.0.5"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@electron/get": "^2.0.2",
|
||||||
|
"@types/compare-version": "^0.1.31",
|
||||||
|
"@types/debug": "^4.1.7",
|
||||||
|
"@types/fs-extra": "^9.0.13",
|
||||||
|
"@types/node": "^16.11.6",
|
||||||
|
"@types/plist": "^3.0.2",
|
||||||
|
"@typescript-eslint/eslint-plugin": "^5.45.0",
|
||||||
|
"@typescript-eslint/parser": "^5.45.0",
|
||||||
|
"eslint": "^8.29.0",
|
||||||
|
"eslint-config-eslint": "^7.0.0",
|
||||||
|
"eslint-config-standard": "^17.0.0",
|
||||||
|
"eslint-plugin-import": "^2.26.0",
|
||||||
|
"eslint-plugin-node": "^11.1.0",
|
||||||
|
"eslint-plugin-promise": "^6.1.1",
|
||||||
|
"extract-zip": "^2.0.1",
|
||||||
|
"mkdirp": "^1.0.4",
|
||||||
|
"rimraf": "^3.0.2",
|
||||||
|
"run-series": "^1.1.9",
|
||||||
|
"run-waterfall": "^1.1.7",
|
||||||
|
"standard": "^17.0.0",
|
||||||
|
"tape": "^4.7.1",
|
||||||
|
"typedoc": "~0.25.13",
|
||||||
|
"typescript": "^4.9.3"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc && tsc -p tsconfig.esm.json",
|
||||||
|
"docs:build": "npx typedoc",
|
||||||
|
"lint": "eslint --ext .ts,.js src bin test",
|
||||||
|
"pretest": "rimraf test/work",
|
||||||
|
"test": "yarn lint && tape test",
|
||||||
|
"prepublishOnly": "yarn build"
|
||||||
|
},
|
||||||
|
"standard": {
|
||||||
|
"ignore": [
|
||||||
|
"test/work"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=12.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
+16
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Runs the `uname` command and returns the trimmed output.
|
||||||
|
*
|
||||||
|
* Copied from `@electron/get`.
|
||||||
|
*/
|
||||||
|
export declare function uname(): string;
|
||||||
|
export type ConfigVariables = {
|
||||||
|
arm_version?: string;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* Generates an architecture name that would be used in an Electron or Node.js
|
||||||
|
* download file name.
|
||||||
|
*
|
||||||
|
* Copied from `@electron/get`.
|
||||||
|
*/
|
||||||
|
export declare function getNodeArch(arch: string, configVariables: ConfigVariables): string;
|
||||||
+29
@@ -0,0 +1,29 @@
|
|||||||
|
import { execSync } from 'node:child_process';
|
||||||
|
/**
|
||||||
|
* Runs the `uname` command and returns the trimmed output.
|
||||||
|
*
|
||||||
|
* Copied from `@electron/get`.
|
||||||
|
*/
|
||||||
|
export function uname() {
|
||||||
|
return execSync('uname -m').toString().trim();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Generates an architecture name that would be used in an Electron or Node.js
|
||||||
|
* download file name.
|
||||||
|
*
|
||||||
|
* Copied from `@electron/get`.
|
||||||
|
*/
|
||||||
|
export function getNodeArch(arch, configVariables) {
|
||||||
|
if (arch === 'arm') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
switch (configVariables.arm_version) {
|
||||||
|
case '6':
|
||||||
|
return uname();
|
||||||
|
case '7':
|
||||||
|
default:
|
||||||
|
return 'armv7l';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return arch;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=arch.js.map
|
||||||
+1
@@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"arch.js","sourceRoot":"","sources":["../src/arch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAE9C;;;;GAIG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC;AAChD,CAAC;AAMD;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,IAAY,EAAE,eAAgC;IACxE,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;QACnB,8DAA8D;QAC9D,QAAQ,eAAe,CAAC,WAAW,EAAE,CAAC;YACpC,KAAK,GAAG;gBACN,OAAO,KAAK,EAAE,CAAC;YACjB,KAAK,GAAG,CAAC;YACT;gBACE,OAAO,QAAQ,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
|
||||||
+14
@@ -0,0 +1,14 @@
|
|||||||
|
type CacheOptions = {
|
||||||
|
ABI: string;
|
||||||
|
arch: string;
|
||||||
|
platform: string;
|
||||||
|
debug: boolean;
|
||||||
|
electronVersion: string;
|
||||||
|
headerURL: string;
|
||||||
|
modulePath: string;
|
||||||
|
};
|
||||||
|
export declare const cacheModuleState: (dir: string, cachePath: string, key: string) => Promise<void>;
|
||||||
|
type ApplyDiffFunction = (dir: string) => Promise<void>;
|
||||||
|
export declare const lookupModuleState: (cachePath: string, key: string) => Promise<ApplyDiffFunction | boolean>;
|
||||||
|
export declare function generateCacheKey(opts: CacheOptions): Promise<string>;
|
||||||
|
export {};
|
||||||
+153
@@ -0,0 +1,153 @@
|
|||||||
|
import crypto from 'node:crypto';
|
||||||
|
import debug from 'debug';
|
||||||
|
import fs from 'node:fs';
|
||||||
|
import path from 'node:path';
|
||||||
|
import zlib from 'node:zlib';
|
||||||
|
const d = debug('electron-rebuild');
|
||||||
|
// Update this number if you change the caching logic to ensure no bad cache hits
|
||||||
|
const ELECTRON_REBUILD_CACHE_ID = 1;
|
||||||
|
class Snap {
|
||||||
|
hash;
|
||||||
|
data;
|
||||||
|
constructor(hash, data) {
|
||||||
|
this.hash = hash;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const takeSnapshot = async (dir, relativeTo = dir) => {
|
||||||
|
const snap = {};
|
||||||
|
await Promise.all((await fs.promises.readdir(dir)).map(async (child) => {
|
||||||
|
if (child === 'node_modules')
|
||||||
|
return;
|
||||||
|
const childPath = path.resolve(dir, child);
|
||||||
|
const relative = path.relative(relativeTo, childPath);
|
||||||
|
if ((await fs.promises.stat(childPath)).isDirectory()) {
|
||||||
|
snap[relative] = await takeSnapshot(childPath, relativeTo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const data = await fs.promises.readFile(childPath);
|
||||||
|
snap[relative] = new Snap(crypto.createHash('SHA256').update(data).digest('hex'), data);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return snap;
|
||||||
|
};
|
||||||
|
const writeSnapshot = async (diff, dir) => {
|
||||||
|
for (const key in diff) {
|
||||||
|
if (diff[key] instanceof Snap) {
|
||||||
|
await fs.promises.mkdir(path.dirname(path.resolve(dir, key)), { recursive: true });
|
||||||
|
await fs.promises.writeFile(path.resolve(dir, key), diff[key].data);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
await fs.promises.mkdir(path.resolve(dir, key), { recursive: true });
|
||||||
|
await writeSnapshot(diff[key], dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const serialize = (snap) => {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const jsonReady = {};
|
||||||
|
for (const key in snap) {
|
||||||
|
if (snap[key] instanceof Snap) {
|
||||||
|
const s = snap[key];
|
||||||
|
jsonReady[key] = {
|
||||||
|
__isSnap: true,
|
||||||
|
hash: s.hash,
|
||||||
|
data: s.data.toString('base64'),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
jsonReady[key] = serialize(snap[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return jsonReady;
|
||||||
|
};
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const unserialize = (jsonReady) => {
|
||||||
|
const snap = {};
|
||||||
|
for (const key in jsonReady) {
|
||||||
|
if (jsonReady[key].__isSnap) {
|
||||||
|
snap[key] = new Snap(jsonReady[key].hash, Buffer.from(jsonReady[key].data, 'base64'));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
snap[key] = unserialize(jsonReady[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return snap;
|
||||||
|
};
|
||||||
|
export const cacheModuleState = async (dir, cachePath, key) => {
|
||||||
|
const snap = await takeSnapshot(dir);
|
||||||
|
const moduleBuffer = Buffer.from(JSON.stringify(serialize(snap)));
|
||||||
|
const zipped = await new Promise((resolve) => zlib.gzip(moduleBuffer, (_, result) => resolve(result)));
|
||||||
|
await fs.promises.mkdir(cachePath, { recursive: true });
|
||||||
|
await fs.promises.writeFile(path.resolve(cachePath, key), zipped);
|
||||||
|
};
|
||||||
|
export const lookupModuleState = async (cachePath, key) => {
|
||||||
|
if (fs.existsSync(path.resolve(cachePath, key))) {
|
||||||
|
return async function applyDiff(dir) {
|
||||||
|
const zipped = await fs.promises.readFile(path.resolve(cachePath, key));
|
||||||
|
const unzipped = await new Promise((resolve) => {
|
||||||
|
zlib.gunzip(zipped, (_, result) => resolve(result));
|
||||||
|
});
|
||||||
|
const diff = unserialize(JSON.parse(unzipped.toString()));
|
||||||
|
await writeSnapshot(diff, dir);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
function dHashTree(tree, hash) {
|
||||||
|
for (const key of Object.keys(tree).sort()) {
|
||||||
|
hash.update(key);
|
||||||
|
if (typeof tree[key] === 'string') {
|
||||||
|
hash.update(tree[key]);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dHashTree(tree[key], hash);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
async function hashDirectory(dir, relativeTo) {
|
||||||
|
relativeTo ??= dir;
|
||||||
|
d('hashing dir', dir);
|
||||||
|
const dirTree = {};
|
||||||
|
await Promise.all((await fs.promises.readdir(dir)).map(async (child) => {
|
||||||
|
d('found child', child, 'in dir', dir);
|
||||||
|
// Ignore output directories
|
||||||
|
if (dir === relativeTo && (child === 'build' || child === 'bin'))
|
||||||
|
return;
|
||||||
|
// Don't hash nested node_modules
|
||||||
|
if (child === 'node_modules')
|
||||||
|
return;
|
||||||
|
const childPath = path.resolve(dir, child);
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
|
const relative = path.relative(relativeTo, childPath);
|
||||||
|
if ((await fs.promises.stat(childPath)).isDirectory()) {
|
||||||
|
dirTree[relative] = await hashDirectory(childPath, relativeTo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dirTree[relative] = crypto
|
||||||
|
.createHash('SHA256')
|
||||||
|
.update(await fs.promises.readFile(childPath))
|
||||||
|
.digest('hex');
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
return dirTree;
|
||||||
|
}
|
||||||
|
export async function generateCacheKey(opts) {
|
||||||
|
const tree = await hashDirectory(opts.modulePath);
|
||||||
|
const hasher = crypto
|
||||||
|
.createHash('SHA256')
|
||||||
|
.update(`${ELECTRON_REBUILD_CACHE_ID}`)
|
||||||
|
.update(path.basename(opts.modulePath))
|
||||||
|
.update(opts.ABI)
|
||||||
|
.update(opts.arch)
|
||||||
|
.update(opts.platform)
|
||||||
|
.update(opts.debug ? 'debug' : 'not debug')
|
||||||
|
.update(opts.headerURL)
|
||||||
|
.update(opts.electronVersion);
|
||||||
|
dHashTree(tree, hasher);
|
||||||
|
const hash = hasher.digest('hex');
|
||||||
|
d('calculated hash of', opts.modulePath, 'to be', hash);
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=cache.js.map
|
||||||
Reference in New Issue
Block a user