@electron/notarize
Advanced tools
Comparing version 2.3.0 to 2.3.1
@@ -1,4 +0,7 @@ | ||
import { NotarizeOptions } from './types'; | ||
import { NotarizeOptions, NotarizeOptionsLegacy, NotarizeOptionsNotaryTool } from './types'; | ||
export { NotarizeOptions }; | ||
export { validateLegacyAuthorizationArgs as validateAuthorizationArgs } from './validate-args'; | ||
export declare function notarize({ appPath, ...otherOptions }: NotarizeOptions): Promise<void>; | ||
export { validateNotaryToolAuthorizationArgs as validateAuthorizationArgs } from './validate-args'; | ||
declare function notarize(args: NotarizeOptionsNotaryTool): Promise<void>; | ||
/** @deprecated */ | ||
declare function notarize(args: NotarizeOptionsLegacy): Promise<void>; | ||
export { notarize }; |
@@ -30,4 +30,2 @@ "use strict"; | ||
const check_signature_1 = require("./check-signature"); | ||
const helpers_1 = require("./helpers"); | ||
const legacy_1 = require("./legacy"); | ||
const notarytool_1 = require("./notarytool"); | ||
@@ -37,32 +35,15 @@ const staple_1 = require("./staple"); | ||
var validate_args_1 = require("./validate-args"); | ||
Object.defineProperty(exports, "validateAuthorizationArgs", { enumerable: true, get: function () { return validate_args_1.validateLegacyAuthorizationArgs; } }); | ||
Object.defineProperty(exports, "validateAuthorizationArgs", { enumerable: true, get: function () { return validate_args_1.validateNotaryToolAuthorizationArgs; } }); | ||
function notarize(_a) { | ||
var { appPath } = _a, otherOptions = __rest(_a, ["appPath"]); | ||
return __awaiter(this, void 0, void 0, function* () { | ||
yield (0, check_signature_1.checkSignatures)({ appPath }); | ||
if (otherOptions.tool === 'legacy') { | ||
console.warn('Notarizing using the legacy altool system. The altool system will be disabled on November 1 2023. Please switch to the notarytool system before then.'); | ||
console.warn('You can do this by setting "tool: notarytool" in your "@electron/notarize" options. Please note that the credentials options may be slightly different between tools.'); | ||
d('notarizing using the legacy notarization system, this will be slow'); | ||
const { uuid } = yield (0, legacy_1.startLegacyNotarize)(Object.assign({ appPath }, otherOptions)); | ||
/** | ||
* Wait for Apples API to initialize the status UUID | ||
* | ||
* If we start checking too quickly the UUID is not ready yet | ||
* and this step will fail. It takes Apple a number of minutes | ||
* to actually complete the job so an extra 10 second delay here | ||
* is not a big deal | ||
*/ | ||
d('notarization started, waiting for 10 seconds before pinging Apple for status'); | ||
yield (0, helpers_1.delay)(10000); | ||
d('starting to poll for notarization status'); | ||
yield (0, legacy_1.waitForLegacyNotarize)(Object.assign({ uuid }, otherOptions)); | ||
throw new Error('Notarization with the legacy altool system was decommisioned as of November 2023'); | ||
} | ||
else { | ||
d('notarizing using the new notarytool system'); | ||
if (!(yield (0, notarytool_1.isNotaryToolAvailable)())) { | ||
throw new Error('notarytool is not available, you must be on at least Xcode 13'); | ||
} | ||
yield (0, notarytool_1.notarizeAndWaitForNotaryTool)(Object.assign({ appPath }, otherOptions)); | ||
yield (0, check_signature_1.checkSignatures)({ appPath }); | ||
d('notarizing using notarytool'); | ||
if (!(yield (0, notarytool_1.isNotaryToolAvailable)())) { | ||
throw new Error('notarytool is not available, you must be on at least Xcode 13'); | ||
} | ||
yield (0, notarytool_1.notarizeAndWaitForNotaryTool)(Object.assign({ appPath }, otherOptions)); | ||
yield (0, promise_retry_1.default)(() => (0, staple_1.stapleApp)({ appPath }), { | ||
@@ -69,0 +50,0 @@ retries: 3, |
@@ -1,3 +0,5 @@ | ||
import { NotarizeResult, LegacyNotarizeStartOptions, LegacyNotarizeWaitOptions } from './types'; | ||
export declare function startLegacyNotarize(opts: LegacyNotarizeStartOptions): Promise<NotarizeResult>; | ||
export declare function waitForLegacyNotarize(opts: LegacyNotarizeWaitOptions): Promise<void>; | ||
import { LegacyNotarizeStartOptions, LegacyNotarizeWaitOptions } from './types'; | ||
/** @deprecated */ | ||
export declare function startLegacyNotarize(opts: LegacyNotarizeStartOptions): Promise<never>; | ||
/** @deprecated */ | ||
export declare function waitForLegacyNotarize(opts: LegacyNotarizeWaitOptions): Promise<never>; |
"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 __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -40,102 +17,15 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
const debug_1 = __importDefault(require("debug")); | ||
const path = __importStar(require("path")); | ||
const spawn_1 = require("./spawn"); | ||
const helpers_1 = require("./helpers"); | ||
const validate_args_1 = require("./validate-args"); | ||
const d = (0, debug_1.default)('electron-notarize:legacy'); | ||
function authorizationArgs(rawOpts) { | ||
const opts = (0, validate_args_1.validateLegacyAuthorizationArgs)(rawOpts); | ||
if ((0, validate_args_1.isLegacyPasswordCredentials)(opts)) { | ||
return ['-u', (0, helpers_1.makeSecret)(opts.appleId), '-p', (0, helpers_1.makeSecret)(opts.appleIdPassword)]; | ||
} | ||
else { | ||
return [ | ||
'--apiKey', | ||
(0, helpers_1.makeSecret)(opts.appleApiKey), | ||
'--apiIssuer', | ||
(0, helpers_1.makeSecret)(opts.appleApiIssuer), | ||
]; | ||
} | ||
} | ||
/** @deprecated */ | ||
function startLegacyNotarize(opts) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
d('starting notarize process for app:', opts.appPath); | ||
return yield (0, helpers_1.withTempDir)((dir) => __awaiter(this, void 0, void 0, function* () { | ||
const zipPath = path.resolve(dir, `${path.basename(opts.appPath, '.app')}.zip`); | ||
d('zipping application to:', zipPath); | ||
const zipResult = yield (0, spawn_1.spawn)('ditto', ['-c', '-k', '--sequesterRsrc', '--keepParent', path.basename(opts.appPath), zipPath], { | ||
cwd: path.dirname(opts.appPath), | ||
}); | ||
if (zipResult.code !== 0) { | ||
throw new Error(`Failed to zip application, exited with code: ${zipResult.code}\n\n${zipResult.output}`); | ||
} | ||
d('zip succeeded, attempting to upload to Apple'); | ||
const notarizeArgs = [ | ||
'altool', | ||
'--notarize-app', | ||
'-f', | ||
zipPath, | ||
'--primary-bundle-id', | ||
opts.appBundleId, | ||
...authorizationArgs(opts), | ||
]; | ||
if (opts.ascProvider) { | ||
notarizeArgs.push('-itc_provider', opts.ascProvider); | ||
} | ||
const result = yield (0, spawn_1.spawn)('xcrun', notarizeArgs); | ||
if (result.code !== 0) { | ||
throw new Error(`Failed to upload app to Apple's notarization servers\n\n${result.output}`); | ||
} | ||
d('upload success'); | ||
const uuidMatch = /\nRequestUUID = (.+?)\n/g.exec(result.output); | ||
if (!uuidMatch) { | ||
throw new Error(`Failed to find request UUID in output:\n\n${result.output}`); | ||
} | ||
d('found UUID:', uuidMatch[1]); | ||
return { | ||
uuid: uuidMatch[1], | ||
}; | ||
})); | ||
throw new Error('Cannot start notarization. Legacy notarization (altool) is no longer available'); | ||
}); | ||
} | ||
exports.startLegacyNotarize = startLegacyNotarize; | ||
/** @deprecated */ | ||
function waitForLegacyNotarize(opts) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
d('checking notarization status:', opts.uuid); | ||
const result = yield (0, spawn_1.spawn)('xcrun', [ | ||
'altool', | ||
'--notarization-info', | ||
opts.uuid, | ||
...authorizationArgs(opts), | ||
]); | ||
if (result.code !== 0) { | ||
// These checks could fail for all sorts of reasons, including: | ||
// * The status of a request isn't available as soon as the upload request returns, so | ||
// it may just not be ready yet. | ||
// * If using keychain password, user's mac went to sleep and keychain locked. | ||
// * Regular old connectivity failure. | ||
d(`Failed to check status of notarization request, retrying in 30 seconds: ${opts.uuid}\n\n${result.output}`); | ||
yield (0, helpers_1.delay)(30000); | ||
return waitForLegacyNotarize(opts); | ||
} | ||
const notarizationInfo = (0, helpers_1.parseNotarizationInfo)(result.output); | ||
if (notarizationInfo.status === 'in progress') { | ||
d('still in progress, waiting 30 seconds'); | ||
yield (0, helpers_1.delay)(30000); | ||
return waitForLegacyNotarize(opts); | ||
} | ||
d('notarzation done with info:', notarizationInfo); | ||
if (notarizationInfo.status === 'invalid') { | ||
d('notarization failed'); | ||
throw new Error(`Apple failed to notarize your application, check the logs for more info | ||
Status Code: ${notarizationInfo.statusCode || 'No Code'} | ||
Message: ${notarizationInfo.statusMessage || 'No Message'} | ||
Logs: ${notarizationInfo.logFileUrl}`); | ||
} | ||
if (notarizationInfo.status !== 'success') { | ||
throw new Error(`Unrecognized notarization status: "${notarizationInfo.status}"`); | ||
} | ||
d('notarization was successful'); | ||
return; | ||
throw new Error('Cannot wait for notarization. Legacy notarization (altool) is no longer available'); | ||
}); | ||
@@ -142,0 +32,0 @@ } |
@@ -0,1 +1,2 @@ | ||
/** @deprecated */ | ||
export interface LegacyNotarizePasswordCredentials { | ||
@@ -10,2 +11,3 @@ appleId: string; | ||
} | ||
/** @deprecated */ | ||
export interface LegacyNotarizeApiKeyCredentials { | ||
@@ -24,5 +26,7 @@ appleApiKey: string; | ||
} | ||
/** @deprecated */ | ||
export type LegacyNotarizeCredentials = LegacyNotarizePasswordCredentials | LegacyNotarizeApiKeyCredentials; | ||
export type NotaryToolCredentials = NotaryToolPasswordCredentials | NotaryToolApiKeyCredentials | NotaryToolKeychainCredentials; | ||
export type NotarizeCredentials = LegacyNotarizeCredentials | NotaryToolCredentials; | ||
/** @deprecated */ | ||
export interface LegacyNotarizeAppOptions { | ||
@@ -41,10 +45,15 @@ appPath: string; | ||
} | ||
/** @deprecated */ | ||
export type LegacyNotarizeStartOptions = LegacyNotarizeAppOptions & LegacyNotarizeCredentials & TransporterOptions; | ||
export type NotaryToolStartOptions = NotaryToolNotarizeAppOptions & NotaryToolCredentials; | ||
/** @deprecated */ | ||
export type LegacyNotarizeWaitOptions = NotarizeResult & LegacyNotarizeCredentials; | ||
export type NotarizeStapleOptions = Pick<LegacyNotarizeAppOptions, 'appPath'>; | ||
export type NotarizeOptions = ({ | ||
tool?: 'legacy'; | ||
} & LegacyNotarizeStartOptions) | ({ | ||
tool: 'notarytool'; | ||
} & NotaryToolStartOptions); | ||
/** @deprecated */ | ||
export type NotarizeOptionsLegacy = { | ||
tool: 'legacy'; | ||
} & LegacyNotarizeStartOptions; | ||
export type NotarizeOptionsNotaryTool = { | ||
tool?: 'notarytool'; | ||
} & NotaryToolStartOptions; | ||
export type NotarizeOptions = NotarizeOptionsLegacy | NotarizeOptionsNotaryTool; |
import { LegacyNotarizeApiKeyCredentials, LegacyNotarizeCredentials, LegacyNotarizePasswordCredentials, NotaryToolApiKeyCredentials, NotaryToolCredentials, NotaryToolKeychainCredentials, NotaryToolPasswordCredentials } from './types'; | ||
/** @deprecated */ | ||
export declare function isLegacyPasswordCredentials(opts: LegacyNotarizeCredentials): opts is LegacyNotarizePasswordCredentials; | ||
/** @deprecated */ | ||
export declare function isLegacyApiKeyCredentials(opts: LegacyNotarizeCredentials): opts is LegacyNotarizeApiKeyCredentials; | ||
/** @deprecated */ | ||
export declare function validateLegacyAuthorizationArgs(opts: LegacyNotarizeCredentials): LegacyNotarizeCredentials; | ||
@@ -5,0 +8,0 @@ export declare function isNotaryToolPasswordCredentials(opts: NotaryToolCredentials): opts is NotaryToolPasswordCredentials; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.validateNotaryToolAuthorizationArgs = exports.isNotaryToolKeychainCredentials = exports.isNotaryToolApiKeyCredentials = exports.isNotaryToolPasswordCredentials = exports.validateLegacyAuthorizationArgs = exports.isLegacyApiKeyCredentials = exports.isLegacyPasswordCredentials = void 0; | ||
/** @deprecated */ | ||
function isLegacyPasswordCredentials(opts) { | ||
@@ -9,2 +10,3 @@ const creds = opts; | ||
exports.isLegacyPasswordCredentials = isLegacyPasswordCredentials; | ||
/** @deprecated */ | ||
function isLegacyApiKeyCredentials(opts) { | ||
@@ -15,2 +17,3 @@ const creds = opts; | ||
exports.isLegacyApiKeyCredentials = isLegacyApiKeyCredentials; | ||
/** @deprecated */ | ||
function validateLegacyAuthorizationArgs(opts) { | ||
@@ -17,0 +20,0 @@ const isPassword = isLegacyPasswordCredentials(opts); |
{ | ||
"name": "@electron/notarize", | ||
"version": "2.3.0", | ||
"version": "2.3.1", | ||
"description": "Notarize your Electron app", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -33,3 +33,3 @@ Electron Notarize | ||
1. Xcode 10 or later installed on your Mac. | ||
1. Xcode 13 or later installed on your Mac. | ||
2. An [Apple Developer](https://developer.apple.com/) account. | ||
@@ -48,9 +48,9 @@ 3. [An app-specific password for your ADC account’s Apple ID](https://support.apple.com/HT204397). | ||
* `options` Object | ||
* `tool` String - The notarization tool to use, default is `notarytool`. Can be `legacy` or `notarytool`. `notarytool` is substantially (10x) faster and `legacy` is deprecated and will **stop working** on November 1st 2023. | ||
* `tool` String - The notarization tool to use, default is `notarytool`. Previously, the value `legacy` used `altool`, which [**stopped working** on November 1st 2023](https://developer.apple.com/news/?id=y5mjxqmn). | ||
* `appPath` String - The absolute path to your `.app` file | ||
* There are different options for each tool: Notarytool | ||
* There are three authentication methods available: user name with password: | ||
* `appleId` String - The username of your apple developer account | ||
* There are three authentication methods available: | ||
* user name with password: | ||
* `appleId` String - The username of your Apple Developer account | ||
* `appleIdPassword` String - The [app-specific password](https://support.apple.com/HT204397) (not your Apple ID password). | ||
* `teamId` String - The team ID you want to notarize under. | ||
* `teamId` String - The [team ID](https://developer.apple.com/help/account/manage-your-team/locate-your-team-id/) you want to notarize under. | ||
* ... or apiKey with apiIssuer: | ||
@@ -63,11 +63,2 @@ * `appleApiKey` String - Absolute path to the `.p8` file containing the key. Required for JWT authentication. See Note on JWT authentication below. | ||
* `keychainProfile` String - The name of the profile you provided when storing notarization credentials. | ||
* ... or Legacy | ||
* `appBundleId` String - The app bundle identifier your Electron app is using. E.g. `com.github.electron` | ||
* `ascProvider` String (optional) - Your [Team Short Name](#notes-on-your-team-short-name). | ||
* There are two authentication methods available: user name with password: | ||
* `appleId` String - The username of your apple developer account | ||
* `appleIdPassword` String - The [app-specific password](https://support.apple.com/HT204397) (not your Apple ID password). | ||
* ... or apiKey with apiIssuer: | ||
* `appleApiKey` String - Required for JWT authentication. See Note on JWT authentication below. | ||
* `appleApiIssuer` String - Issuer ID. Required if `appleApiKey` is specified. | ||
@@ -98,30 +89,7 @@ ## Safety when using `appleIdPassword` | ||
You can obtain an API key from [Appstore Connect](https://appstoreconnect.apple.com/access/api). Create a key with _App Manager_ access. Note down the Issuer ID and download the `.p8` file. This file is your API key and comes with the name of `AuthKey_<appleApiKeyId>.p8`. This is the string you have to supply when calling `notarize`. | ||
You can obtain an API key from [App Store Connect](https://appstoreconnect.apple.com/access/api). Create a _Team Key_ (not an _Individual Key_) with _App Manager_ access. Note down the Issuer ID and download the `.p8` file. This file is your API key and comes with the name of `AuthKey_<appleApiKeyId>.p8`. Provide the path to this file as the `appleApiKey` argument. | ||
Based on the `ApiKey`, the legacy `altool` will look in the following places for that file: | ||
* `./private_keys` | ||
* `~/private_keys` | ||
* `~/.private_keys` | ||
* `~/.appstoreconnect/private_keys` | ||
`notarytool` will not look for the key, and you must instead provide its path as the `appleApiKey` argument. | ||
## Notes on your Team Short Name | ||
If you are a member of multiple teams or organizations, you have to tell Apple on behalf of which organization you're uploading. To find your [team's short name](https://forums.developer.apple.com/thread/113798)), you can ask `iTMSTransporter`, which is part of the now deprecated `Application Loader` as well as the newer [`Transporter`](https://apps.apple.com/us/app/transporter/id1450874784?mt=12). | ||
With `Transporter` installed, run: | ||
```sh | ||
/Applications/Transporter.app/Contents/itms/bin/iTMSTransporter -m provider -u APPLE_DEV_ACCOUNT -p APP_PASSWORD | ||
``` | ||
Alternatively, with older versions of Xcode, run: | ||
```sh | ||
/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/bin/iTMSTransporter -m provider -u APPLE_DEV_ACCOUNT -p APP_PASSWORD | ||
``` | ||
## Notes on your teamId | ||
If you use the new Notary Tool method with `appleId`/`appleIdPassword` you will need to set the `teamId` option. To get this ID, go to your [Apple Developer Account](https://developer.apple.com/account), then click on "Membership details", and there you will find your Team ID. This link should get you there directly: https://developer.apple.com/account#MembershipDetailsCard | ||
To get your `teamId` value, go to your [Apple Developer Account](https://developer.apple.com/account), then click on "Membership details", and there you will find your Team ID. | ||
@@ -140,9 +108,8 @@ ## Debug | ||
await notarize({ | ||
appBundleId, | ||
appPath, | ||
appleId, | ||
appleIdPassword, | ||
ascProvider, // This parameter is optional | ||
teamId, | ||
}); | ||
} | ||
``` |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53585
703
111