1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | function _bluebirdLst() {
|
9 | const data = _interopRequireDefault(require("bluebird-lst"));
|
10 |
|
11 | _bluebirdLst = function () {
|
12 | return data;
|
13 | };
|
14 |
|
15 | return data;
|
16 | }
|
17 |
|
18 | function _builderUtil() {
|
19 | const data = require("builder-util");
|
20 |
|
21 | _builderUtil = function () {
|
22 | return data;
|
23 | };
|
24 |
|
25 | return data;
|
26 | }
|
27 |
|
28 | function _electronOsxSign() {
|
29 | const data = require("../electron-osx-sign");
|
30 |
|
31 | _electronOsxSign = function () {
|
32 | return data;
|
33 | };
|
34 |
|
35 | return data;
|
36 | }
|
37 |
|
38 | function _fsExtra() {
|
39 | const data = require("fs-extra");
|
40 |
|
41 | _fsExtra = function () {
|
42 | return data;
|
43 | };
|
44 |
|
45 | return data;
|
46 | }
|
47 |
|
48 | function _lazyVal() {
|
49 | const data = require("lazy-val");
|
50 |
|
51 | _lazyVal = function () {
|
52 | return data;
|
53 | };
|
54 |
|
55 | return data;
|
56 | }
|
57 |
|
58 | var path = _interopRequireWildcard(require("path"));
|
59 |
|
60 | function _fs() {
|
61 | const data = require("builder-util/out/fs");
|
62 |
|
63 | _fs = function () {
|
64 | return data;
|
65 | };
|
66 |
|
67 | return data;
|
68 | }
|
69 |
|
70 | function _promise() {
|
71 | const data = require("builder-util/out/promise");
|
72 |
|
73 | _promise = function () {
|
74 | return data;
|
75 | };
|
76 |
|
77 | return data;
|
78 | }
|
79 |
|
80 | function _appInfo() {
|
81 | const data = require("./appInfo");
|
82 |
|
83 | _appInfo = function () {
|
84 | return data;
|
85 | };
|
86 |
|
87 | return data;
|
88 | }
|
89 |
|
90 | function _macCodeSign() {
|
91 | const data = require("./codeSign/macCodeSign");
|
92 |
|
93 | _macCodeSign = function () {
|
94 | return data;
|
95 | };
|
96 |
|
97 | return data;
|
98 | }
|
99 |
|
100 | function _core() {
|
101 | const data = require("./core");
|
102 |
|
103 | _core = function () {
|
104 | return data;
|
105 | };
|
106 |
|
107 | return data;
|
108 | }
|
109 |
|
110 | function _platformPackager() {
|
111 | const data = require("./platformPackager");
|
112 |
|
113 | _platformPackager = function () {
|
114 | return data;
|
115 | };
|
116 |
|
117 | return data;
|
118 | }
|
119 |
|
120 | function _ArchiveTarget() {
|
121 | const data = require("./targets/ArchiveTarget");
|
122 |
|
123 | _ArchiveTarget = function () {
|
124 | return data;
|
125 | };
|
126 |
|
127 | return data;
|
128 | }
|
129 |
|
130 | function _pkg() {
|
131 | const data = require("./targets/pkg");
|
132 |
|
133 | _pkg = function () {
|
134 | return data;
|
135 | };
|
136 |
|
137 | return data;
|
138 | }
|
139 |
|
140 | function _targetFactory() {
|
141 | const data = require("./targets/targetFactory");
|
142 |
|
143 | _targetFactory = function () {
|
144 | return data;
|
145 | };
|
146 |
|
147 | return data;
|
148 | }
|
149 |
|
150 | function _macosVersion() {
|
151 | const data = require("./util/macosVersion");
|
152 |
|
153 | _macosVersion = function () {
|
154 | return data;
|
155 | };
|
156 |
|
157 | return data;
|
158 | }
|
159 |
|
160 | function _pathManager() {
|
161 | const data = require("./util/pathManager");
|
162 |
|
163 | _pathManager = function () {
|
164 | return data;
|
165 | };
|
166 |
|
167 | return data;
|
168 | }
|
169 |
|
170 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
171 |
|
172 | function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
173 |
|
174 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
175 |
|
176 | class MacPackager extends _platformPackager().PlatformPackager {
|
177 | constructor(info) {
|
178 | super(info, _core().Platform.MAC);
|
179 | this.codeSigningInfo = new (_lazyVal().Lazy)(() => {
|
180 | const cscLink = this.getCscLink();
|
181 |
|
182 | if (cscLink == null || process.platform !== "darwin") {
|
183 | return Promise.resolve({
|
184 | keychainFile: process.env.CSC_KEYCHAIN || null
|
185 | });
|
186 | }
|
187 |
|
188 | return (0, _macCodeSign().createKeychain)({
|
189 | tmpDir: this.info.tempDirManager,
|
190 | cscLink,
|
191 | cscKeyPassword: this.getCscPassword(),
|
192 | cscILink: (0, _platformPackager().chooseNotNull)(this.platformSpecificBuildOptions.cscInstallerLink, process.env.CSC_INSTALLER_LINK),
|
193 | cscIKeyPassword: (0, _platformPackager().chooseNotNull)(this.platformSpecificBuildOptions.cscInstallerKeyPassword, process.env.CSC_INSTALLER_KEY_PASSWORD),
|
194 | currentDir: this.projectDir
|
195 | }).then(result => {
|
196 | const keychainFile = result.keychainFile;
|
197 |
|
198 | if (keychainFile != null) {
|
199 | this.info.disposeOnBuildFinish(() => (0, _macCodeSign().removeKeychain)(keychainFile));
|
200 | }
|
201 |
|
202 | return result;
|
203 | });
|
204 | });
|
205 | this._iconPath = new (_lazyVal().Lazy)(() => this.getOrConvertIcon("icns"));
|
206 | }
|
207 |
|
208 | get defaultTarget() {
|
209 | return this.info.framework.macOsDefaultTargets;
|
210 | }
|
211 |
|
212 |
|
213 | prepareAppInfo(appInfo) {
|
214 | return new (_appInfo().AppInfo)(this.info, this.platformSpecificBuildOptions.bundleVersion, this.platformSpecificBuildOptions);
|
215 | }
|
216 |
|
217 | async getIconPath() {
|
218 | return this._iconPath.value;
|
219 | }
|
220 |
|
221 | createTargets(targets, mapper) {
|
222 | for (const name of targets) {
|
223 | switch (name) {
|
224 | case _core().DIR_TARGET:
|
225 | break;
|
226 |
|
227 | case "dmg":
|
228 | {
|
229 |
|
230 | const {
|
231 | DmgTarget
|
232 | } = require("dmg-builder");
|
233 |
|
234 | mapper(name, outDir => new DmgTarget(this, outDir));
|
235 | break;
|
236 | }
|
237 |
|
238 | case "zip":
|
239 |
|
240 | mapper(name, outDir => new (_ArchiveTarget().ArchiveTarget)(name, outDir, this, true));
|
241 | break;
|
242 |
|
243 | case "pkg":
|
244 | mapper(name, outDir => new (_pkg().PkgTarget)(this, outDir));
|
245 | break;
|
246 |
|
247 | default:
|
248 | mapper(name, outDir => name === "mas" || name === "mas-dev" ? new (_targetFactory().NoOpTarget)(name) : (0, _targetFactory().createCommonTarget)(name, outDir, this));
|
249 | break;
|
250 | }
|
251 | }
|
252 | }
|
253 |
|
254 | async pack(outDir, arch, targets, taskManager) {
|
255 | let nonMasPromise = null;
|
256 | const hasMas = targets.length !== 0 && targets.some(it => it.name === "mas" || it.name === "mas-dev");
|
257 | const prepackaged = this.packagerOptions.prepackaged;
|
258 |
|
259 | if (!hasMas || targets.length > 1) {
|
260 | const appPath = prepackaged == null ? path.join(this.computeAppOutDir(outDir, arch), `${this.appInfo.productFilename}.app`) : prepackaged;
|
261 | nonMasPromise = (prepackaged ? Promise.resolve() : this.doPack(outDir, path.dirname(appPath), this.platform.nodeName, arch, this.platformSpecificBuildOptions, targets)).then(() => this.packageInDistributableFormat(appPath, arch, targets, taskManager));
|
262 | }
|
263 |
|
264 | for (const target of targets) {
|
265 | const targetName = target.name;
|
266 |
|
267 | if (!(targetName === "mas" || targetName === "mas-dev")) {
|
268 | continue;
|
269 | }
|
270 |
|
271 | const masBuildOptions = (0, _builderUtil().deepAssign)({}, this.platformSpecificBuildOptions, this.config.mas);
|
272 |
|
273 | if (targetName === "mas-dev") {
|
274 | (0, _builderUtil().deepAssign)(masBuildOptions, this.config.masDev, {
|
275 | type: "development"
|
276 | });
|
277 | }
|
278 |
|
279 | const targetOutDir = path.join(outDir, targetName);
|
280 |
|
281 | if (prepackaged == null) {
|
282 | await this.doPack(outDir, targetOutDir, "mas", arch, masBuildOptions, [target]);
|
283 | await this.sign(path.join(targetOutDir, `${this.appInfo.productFilename}.app`), targetOutDir, masBuildOptions);
|
284 | } else {
|
285 | await this.sign(prepackaged, targetOutDir, masBuildOptions);
|
286 | }
|
287 | }
|
288 |
|
289 | if (nonMasPromise != null) {
|
290 | await nonMasPromise;
|
291 | }
|
292 | }
|
293 |
|
294 | async sign(appPath, outDir, masOptions) {
|
295 | if (!(0, _macCodeSign().isSignAllowed)()) {
|
296 | return;
|
297 | }
|
298 |
|
299 | const isMas = masOptions != null;
|
300 | const options = masOptions == null ? this.platformSpecificBuildOptions : masOptions;
|
301 | const qualifier = options.identity;
|
302 |
|
303 | if (!isMas && qualifier === null) {
|
304 | if (this.forceCodeSigning) {
|
305 | throw new (_builderUtil().InvalidConfigurationError)("identity explicitly is set to null, but forceCodeSigning is set to true");
|
306 | }
|
307 |
|
308 | _builderUtil().log.info({
|
309 | reason: "identity explicitly is set to null"
|
310 | }, "skipped macOS code signing");
|
311 |
|
312 | return;
|
313 | }
|
314 |
|
315 | const keychainFile = (await this.codeSigningInfo.value).keychainFile;
|
316 | const explicitType = options.type;
|
317 | const type = explicitType || "distribution";
|
318 | const isDevelopment = type === "development";
|
319 | const certificateType = getCertificateType(isMas, isDevelopment);
|
320 | let identity = await (0, _macCodeSign().findIdentity)(certificateType, qualifier, keychainFile);
|
321 |
|
322 | if (identity == null) {
|
323 | if (!isMas && !isDevelopment && explicitType !== "distribution") {
|
324 | identity = await (0, _macCodeSign().findIdentity)("Mac Developer", qualifier, keychainFile);
|
325 |
|
326 | if (identity != null) {
|
327 | _builderUtil().log.warn("Mac Developer is used to sign app — it is only for development and testing, not for production");
|
328 | }
|
329 | }
|
330 |
|
331 | if (identity == null) {
|
332 | await (0, _macCodeSign().reportError)(isMas, certificateType, qualifier, keychainFile, this.forceCodeSigning);
|
333 | return;
|
334 | }
|
335 | }
|
336 |
|
337 | if (!(0, _macosVersion().isMacOsHighSierra)()) {
|
338 | throw new (_builderUtil().InvalidConfigurationError)("macOS High Sierra 10.13.6 is required to sign");
|
339 | }
|
340 |
|
341 | let filter = options.signIgnore;
|
342 |
|
343 | if (Array.isArray(filter)) {
|
344 | if (filter.length == 0) {
|
345 | filter = null;
|
346 | }
|
347 | } else if (filter != null) {
|
348 | filter = filter.length === 0 ? null : [filter];
|
349 | }
|
350 |
|
351 | const filterRe = filter == null ? null : filter.map(it => new RegExp(it));
|
352 | const signOptions = {
|
353 | "identity-validation": false,
|
354 |
|
355 |
|
356 | ignore: file => {
|
357 | if (filterRe != null) {
|
358 | for (const regExp of filterRe) {
|
359 | if (regExp.test(file)) {
|
360 | return true;
|
361 | }
|
362 | }
|
363 | }
|
364 |
|
365 | return file.endsWith(".kext") || file.startsWith("/Contents/PlugIns", appPath.length) || file.includes("/node_modules/puppeteer/.local-chromium") || file.includes("/node_modules/playwright-firefox/.local-browsers") || file.includes("/node_modules/playwright/.local-browsers");
|
366 | |
367 |
|
368 |
|
369 |
|
370 | },
|
371 | identity: identity,
|
372 | type,
|
373 | platform: isMas ? "mas" : "darwin",
|
374 | version: this.config.electronVersion,
|
375 | app: appPath,
|
376 | keychain: keychainFile || undefined,
|
377 | binaries: options.binaries || undefined,
|
378 | requirements: isMas || this.platformSpecificBuildOptions.requirements == null ? undefined : await this.getResource(this.platformSpecificBuildOptions.requirements),
|
379 |
|
380 |
|
381 | "gatekeeper-assess": options.gatekeeperAssess === true,
|
382 |
|
383 | "strict-verify": options.strictVerify,
|
384 | hardenedRuntime: isMas ? masOptions && masOptions.hardenedRuntime === true : options.hardenedRuntime !== false
|
385 | };
|
386 | await this.adjustSignOptions(signOptions, masOptions);
|
387 |
|
388 | _builderUtil().log.info({
|
389 | file: _builderUtil().log.filePath(appPath),
|
390 | identityName: identity.name,
|
391 | identityHash: identity.hash,
|
392 | provisioningProfile: signOptions["provisioning-profile"] || "none"
|
393 | }, "signing");
|
394 |
|
395 | await this.doSign(signOptions);
|
396 |
|
397 | if (masOptions != null && !isDevelopment) {
|
398 | const certType = isDevelopment ? "Mac Developer" : "3rd Party Mac Developer Installer";
|
399 | const masInstallerIdentity = await (0, _macCodeSign().findIdentity)(certType, masOptions.identity, keychainFile);
|
400 |
|
401 | if (masInstallerIdentity == null) {
|
402 | throw new (_builderUtil().InvalidConfigurationError)(`Cannot find valid "${certType}" identity to sign MAS installer, please see https://electron.build/code-signing`);
|
403 | }
|
404 |
|
405 |
|
406 | const artifactName = this.expandArtifactNamePattern(masOptions, "pkg");
|
407 | const artifactPath = path.join(outDir, artifactName);
|
408 | await this.doFlat(appPath, artifactPath, masInstallerIdentity, keychainFile);
|
409 | await this.dispatchArtifactCreated(artifactPath, null, _builderUtil().Arch.x64, this.computeSafeArtifactName(artifactName, "pkg"));
|
410 | }
|
411 | }
|
412 |
|
413 | async adjustSignOptions(signOptions, masOptions) {
|
414 | const resourceList = await this.resourceList;
|
415 | const customSignOptions = masOptions || this.platformSpecificBuildOptions;
|
416 | const entitlementsSuffix = masOptions == null ? "mac" : "mas";
|
417 | let entitlements = customSignOptions.entitlements;
|
418 |
|
419 | if (entitlements == null) {
|
420 | const p = `entitlements.${entitlementsSuffix}.plist`;
|
421 |
|
422 | if (resourceList.includes(p)) {
|
423 | entitlements = path.join(this.info.buildResourcesDir, p);
|
424 | } else {
|
425 | entitlements = (0, _pathManager().getTemplatePath)("entitlements.mac.plist");
|
426 | }
|
427 | }
|
428 |
|
429 | signOptions.entitlements = entitlements;
|
430 | let entitlementsInherit = customSignOptions.entitlementsInherit;
|
431 |
|
432 | if (entitlementsInherit == null) {
|
433 | const p = `entitlements.${entitlementsSuffix}.inherit.plist`;
|
434 |
|
435 | if (resourceList.includes(p)) {
|
436 | entitlementsInherit = path.join(this.info.buildResourcesDir, p);
|
437 | } else {
|
438 | entitlementsInherit = (0, _pathManager().getTemplatePath)("entitlements.mac.plist");
|
439 | }
|
440 | }
|
441 |
|
442 | signOptions["entitlements-inherit"] = entitlementsInherit;
|
443 |
|
444 | if (customSignOptions.provisioningProfile != null) {
|
445 | signOptions["provisioning-profile"] = customSignOptions.provisioningProfile;
|
446 | }
|
447 |
|
448 | signOptions['entitlements-loginhelper'] = customSignOptions.entitlementsLoginHelper;
|
449 | }
|
450 |
|
451 |
|
452 | async doSign(opts) {
|
453 | return (0, _electronOsxSign().signAsync)(opts);
|
454 | }
|
455 |
|
456 |
|
457 | async doFlat(appPath, outFile, identity, keychain) {
|
458 |
|
459 | await (0, _fsExtra().mkdirs)(path.dirname(outFile));
|
460 | const args = (0, _pkg().prepareProductBuildArgs)(identity, keychain);
|
461 | args.push("--component", appPath, "/Applications");
|
462 | args.push(outFile);
|
463 | return await (0, _builderUtil().exec)("productbuild", args);
|
464 | }
|
465 |
|
466 | getElectronSrcDir(dist) {
|
467 | return path.resolve(this.projectDir, dist, this.info.framework.distMacOsAppName);
|
468 | }
|
469 |
|
470 | getElectronDestinationDir(appOutDir) {
|
471 | return path.join(appOutDir, this.info.framework.distMacOsAppName);
|
472 | }
|
473 |
|
474 |
|
475 | async applyCommonInfo(appPlist, contentsPath) {
|
476 | const appInfo = this.appInfo;
|
477 | const appFilename = appInfo.productFilename;
|
478 |
|
479 | appPlist.CFBundleExecutable = appFilename.endsWith(" Helper") ? appFilename.substring(0, appFilename.length - " Helper".length) : appFilename;
|
480 | const icon = await this.getIconPath();
|
481 |
|
482 | if (icon != null) {
|
483 | const oldIcon = appPlist.CFBundleIconFile;
|
484 | const resourcesPath = path.join(contentsPath, "Resources");
|
485 |
|
486 | if (oldIcon != null) {
|
487 | await (0, _fs().unlinkIfExists)(path.join(resourcesPath, oldIcon));
|
488 | }
|
489 |
|
490 | const iconFileName = `${appFilename}.icns`;
|
491 | appPlist.CFBundleIconFile = iconFileName;
|
492 | await (0, _fs().copyFile)(icon, path.join(resourcesPath, iconFileName));
|
493 | }
|
494 |
|
495 | appPlist.CFBundleName = appInfo.productName;
|
496 | appPlist.CFBundleDisplayName = appInfo.productName;
|
497 | const minimumSystemVersion = this.platformSpecificBuildOptions.minimumSystemVersion;
|
498 |
|
499 | if (minimumSystemVersion != null) {
|
500 | appPlist.LSMinimumSystemVersion = minimumSystemVersion;
|
501 | }
|
502 |
|
503 | appPlist.CFBundleIdentifier = appInfo.macBundleIdentifier;
|
504 | appPlist.CFBundleShortVersionString = this.platformSpecificBuildOptions.bundleShortVersion || appInfo.version;
|
505 | appPlist.CFBundleVersion = appInfo.buildVersion;
|
506 | (0, _builderUtil().use)(this.platformSpecificBuildOptions.category || this.config.category, it => appPlist.LSApplicationCategoryType = it);
|
507 | appPlist.NSHumanReadableCopyright = appInfo.copyright;
|
508 |
|
509 | if (this.platformSpecificBuildOptions.darkModeSupport) {
|
510 | appPlist.NSRequiresAquaSystemAppearance = false;
|
511 | }
|
512 |
|
513 | const extendInfo = this.platformSpecificBuildOptions.extendInfo;
|
514 |
|
515 | if (extendInfo != null) {
|
516 | Object.assign(appPlist, extendInfo);
|
517 | }
|
518 | }
|
519 |
|
520 | async signApp(packContext, isAsar) {
|
521 | const appFileName = `${this.appInfo.productFilename}.app`;
|
522 | await _bluebirdLst().default.map((0, _fsExtra().readdir)(packContext.appOutDir), file => {
|
523 | if (file === appFileName) {
|
524 | return this.sign(path.join(packContext.appOutDir, file), null, null);
|
525 | }
|
526 |
|
527 | return null;
|
528 | });
|
529 |
|
530 | if (!isAsar) {
|
531 | return;
|
532 | }
|
533 |
|
534 | const outResourcesDir = path.join(packContext.appOutDir, "resources", "app.asar.unpacked");
|
535 | await _bluebirdLst().default.map((0, _promise().orIfFileNotExist)((0, _fsExtra().readdir)(outResourcesDir), []), file => {
|
536 | if (file.endsWith(".app")) {
|
537 | return this.sign(path.join(outResourcesDir, file), null, null);
|
538 | } else {
|
539 | return null;
|
540 | }
|
541 | });
|
542 | }
|
543 |
|
544 | }
|
545 |
|
546 | exports.default = MacPackager;
|
547 |
|
548 | function getCertificateType(isMas, isDevelopment) {
|
549 | if (isDevelopment) {
|
550 | return "Mac Developer";
|
551 | }
|
552 |
|
553 | return isMas ? "3rd Party Mac Developer Application" : "Developer ID Application";
|
554 | }
|
555 |
|
556 |
|
\ | No newline at end of file |