UNPKG

18.3 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.WinPackager = void 0;
7
8function _bluebirdLst() {
9 const data = _interopRequireWildcard(require("bluebird-lst"));
10
11 _bluebirdLst = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function _builderUtil() {
19 const data = require("builder-util");
20
21 _builderUtil = function () {
22 return data;
23 };
24
25 return data;
26}
27
28function _builderUtilRuntime() {
29 const data = require("builder-util-runtime");
30
31 _builderUtilRuntime = function () {
32 return data;
33 };
34
35 return data;
36}
37
38function _crypto() {
39 const data = require("crypto");
40
41 _crypto = function () {
42 return data;
43 };
44
45 return data;
46}
47
48var _debug2 = _interopRequireDefault(require("debug"));
49
50function _fsExtraP() {
51 const data = require("fs-extra-p");
52
53 _fsExtraP = function () {
54 return data;
55 };
56
57 return data;
58}
59
60function _isCi() {
61 const data = _interopRequireDefault(require("is-ci"));
62
63 _isCi = function () {
64 return data;
65 };
66
67 return data;
68}
69
70function _lazyVal() {
71 const data = require("lazy-val");
72
73 _lazyVal = function () {
74 return data;
75 };
76
77 return data;
78}
79
80var path = _interopRequireWildcard(require("path"));
81
82function _fs() {
83 const data = require("builder-util/out/fs");
84
85 _fs = function () {
86 return data;
87 };
88
89 return data;
90}
91
92function _promise() {
93 const data = require("builder-util/out/promise");
94
95 _promise = function () {
96 return data;
97 };
98
99 return data;
100}
101
102function _codeSign() {
103 const data = require("./codeSign");
104
105 _codeSign = function () {
106 return data;
107 };
108
109 return data;
110}
111
112function _core() {
113 const data = require("./core");
114
115 _core = function () {
116 return data;
117 };
118
119 return data;
120}
121
122function _platformPackager() {
123 const data = require("./platformPackager");
124
125 _platformPackager = function () {
126 return data;
127 };
128
129 return data;
130}
131
132function _NsisTarget() {
133 const data = require("./targets/nsis/NsisTarget");
134
135 _NsisTarget = function () {
136 return data;
137 };
138
139 return data;
140}
141
142function _nsisUtil() {
143 const data = require("./targets/nsis/nsisUtil");
144
145 _nsisUtil = function () {
146 return data;
147 };
148
149 return data;
150}
151
152function _WebInstallerTarget() {
153 const data = require("./targets/nsis/WebInstallerTarget");
154
155 _WebInstallerTarget = function () {
156 return data;
157 };
158
159 return data;
160}
161
162function _targetFactory() {
163 const data = require("./targets/targetFactory");
164
165 _targetFactory = function () {
166 return data;
167 };
168
169 return data;
170}
171
172function _cacheManager() {
173 const data = require("./util/cacheManager");
174
175 _cacheManager = function () {
176 return data;
177 };
178
179 return data;
180}
181
182function _flags() {
183 const data = require("./util/flags");
184
185 _flags = function () {
186 return data;
187 };
188
189 return data;
190}
191
192function _timer() {
193 const data = require("./util/timer");
194
195 _timer = function () {
196 return data;
197 };
198
199 return data;
200}
201
202function _vm() {
203 const data = require("./vm/vm");
204
205 _vm = function () {
206 return data;
207 };
208
209 return data;
210}
211
212function _windowsCodeSign() {
213 const data = require("./windowsCodeSign");
214
215 _windowsCodeSign = function () {
216 return data;
217 };
218
219 return data;
220}
221
222let extractCommonNameUsingOpenssl = (() => {
223 var _ref3 = (0, _bluebirdLst().coroutine)(function* (password, certPath) {
224 const result = yield (0, _builderUtil().exec)("openssl", ["pkcs12", "-nokeys", "-nodes", "-passin", `pass:${password}`, "-nomacver", "-clcerts", "-in", certPath], {
225 timeout: 30 * 1000
226 }, debugOpenssl.enabled);
227 const match = result.match(/^subject.*\/CN=([^\/\n]+)/m);
228
229 if (match == null || match[1] == null) {
230 throw new Error(`Cannot extract common name from p12: ${result}`);
231 } else {
232 return match[1];
233 }
234 });
235
236 return function extractCommonNameUsingOpenssl(_x, _x2) {
237 return _ref3.apply(this, arguments);
238 };
239})(); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
240
241function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = Object.defineProperty && Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : {}; if (desc.get || desc.set) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } } newObj.default = obj; return newObj; } }
242
243class WinPackager extends _platformPackager().PlatformPackager {
244 constructor(info) {
245 var _this;
246
247 _this = super(info, _core().Platform.WINDOWS);
248 this.cscInfo = new (_lazyVal().Lazy)(() => {
249 const platformSpecificBuildOptions = this.platformSpecificBuildOptions;
250
251 if (platformSpecificBuildOptions.certificateSubjectName != null || platformSpecificBuildOptions.certificateSha1 != null) {
252 return this.vm.value.then(vm => (0, _windowsCodeSign().getCertificateFromStoreInfo)(platformSpecificBuildOptions, vm)).catch(e => {
253 // https://github.com/electron-userland/electron-builder/pull/2397
254 if (platformSpecificBuildOptions.sign == null) {
255 throw e;
256 } else {
257 _builderUtil().log.debug({
258 error: e
259 }, "getCertificateFromStoreInfo error");
260
261 return null;
262 }
263 });
264 }
265
266 const certificateFile = platformSpecificBuildOptions.certificateFile;
267
268 if (certificateFile != null) {
269 const certificatePassword = this.getCscPassword();
270 return Promise.resolve({
271 file: certificateFile,
272 password: certificatePassword == null ? null : certificatePassword.trim()
273 });
274 }
275
276 const cscLink = this.getCscLink("WIN_CSC_LINK");
277
278 if (cscLink == null) {
279 return Promise.resolve(null);
280 }
281
282 return (0, _codeSign().downloadCertificate)(cscLink, this.info.tempDirManager, this.projectDir).then(path => {
283 return {
284 file: path,
285 password: this.getCscPassword()
286 };
287 });
288 });
289 this._iconPath = new (_lazyVal().Lazy)(() => this.getOrConvertIcon("ico"));
290 this.vm = new (_lazyVal().Lazy)(() => process.platform === "win32" ? Promise.resolve(new (_vm().VmManager)()) : (0, _vm().getWindowsVm)(this.debugLogger));
291 this.computedPublisherSubjectOnWindowsOnly = new (_lazyVal().Lazy)((0, _bluebirdLst().coroutine)(function* () {
292 const cscInfo = yield _this.cscInfo.value;
293
294 if (cscInfo == null) {
295 return null;
296 }
297
298 if ("subject" in cscInfo) {
299 return cscInfo.subject;
300 }
301
302 const vm = yield _this.vm.value;
303 const info = cscInfo;
304 const certFile = vm.toVmFile(info.file); // https://github.com/electron-userland/electron-builder/issues/1735
305
306 const args = info.password ? [`(Get-PfxData "${certFile}" -Password (ConvertTo-SecureString -String "${info.password}" -Force -AsPlainText)).EndEntityCertificates.Subject`] : [`(Get-PfxCertificate "${certFile}").Subject`];
307 return yield vm.exec("powershell.exe", ["-NoProfile", "-NonInteractive", "-Command"].concat(args), {
308 timeout: 30 * 1000
309 }).then(it => it.trim());
310 }));
311 this.computedPublisherName = new (_lazyVal().Lazy)((0, _bluebirdLst().coroutine)(function* () {
312 let publisherName = _this.platformSpecificBuildOptions.publisherName;
313
314 if (publisherName === null) {
315 return null;
316 }
317
318 const cscInfo = yield _this.cscInfo.value;
319
320 if (cscInfo == null) {
321 return null;
322 }
323
324 if ("subject" in cscInfo) {
325 return (0, _builderUtil().asArray)((0, _builderUtilRuntime().parseDn)(cscInfo.subject).get("CN"));
326 }
327
328 const cscFile = cscInfo.file;
329
330 if (publisherName == null && cscFile != null) {
331 try {
332 if (process.platform === "win32") {
333 const subject = yield _this.computedPublisherSubjectOnWindowsOnly.value;
334 const commonName = subject == null ? null : (0, _builderUtilRuntime().parseDn)(subject).get("CN");
335
336 if (commonName) {
337 return (0, _builderUtil().asArray)(commonName);
338 }
339 } else {
340 publisherName = yield extractCommonNameUsingOpenssl(cscInfo.password || "", cscFile);
341 }
342 } catch (e) {
343 throw new Error(`Cannot extract publisher name from code signing certificate, please file issue. As workaround, set win.publisherName: ${e.stack || e}`);
344 }
345 }
346
347 return publisherName == null ? null : (0, _builderUtil().asArray)(publisherName);
348 }));
349 }
350
351 get isForceCodeSigningVerification() {
352 return this.platformSpecificBuildOptions.verifyUpdateCodeSignature !== false;
353 }
354
355 get defaultTarget() {
356 return ["nsis"];
357 }
358
359 doGetCscPassword() {
360 return (0, _platformPackager().chooseNotNull)((0, _platformPackager().chooseNotNull)(this.platformSpecificBuildOptions.certificatePassword, process.env.WIN_CSC_KEY_PASSWORD), super.doGetCscPassword());
361 }
362
363 createTargets(targets, mapper) {
364 let copyElevateHelper;
365
366 const getCopyElevateHelper = () => {
367 if (copyElevateHelper == null) {
368 copyElevateHelper = new (_nsisUtil().CopyElevateHelper)();
369 }
370
371 return copyElevateHelper;
372 };
373
374 let helper;
375
376 const getHelper = () => {
377 if (helper == null) {
378 helper = new (_nsisUtil().AppPackageHelper)(getCopyElevateHelper());
379 }
380
381 return helper;
382 };
383
384 for (const name of targets) {
385 if (name === _core().DIR_TARGET) {
386 continue;
387 }
388
389 if (name === "nsis" || name === "portable") {
390 mapper(name, outDir => new (_NsisTarget().NsisTarget)(this, outDir, name, getHelper()));
391 } else if (name === "nsis-web") {
392 // package file format differs from nsis target
393 mapper(name, outDir => new (_WebInstallerTarget().WebInstallerTarget)(this, path.join(outDir, name), name, new (_nsisUtil().AppPackageHelper)(getCopyElevateHelper())));
394 } else {
395 const targetClass = (() => {
396 switch (name) {
397 case "squirrel":
398 try {
399 return require("electron-builder-squirrel-windows").default;
400 } catch (e) {
401 throw new (_builderUtil().InvalidConfigurationError)(`Module electron-builder-squirrel-windows must be installed in addition to build Squirrel.Windows: ${e.stack || e}`);
402 }
403
404 case "appx":
405 return require("./targets/AppxTarget").default;
406
407 case "msi":
408 return require("./targets/MsiTarget").default;
409
410 default:
411 return null;
412 }
413 })();
414
415 mapper(name, outDir => targetClass === null ? (0, _targetFactory().createCommonTarget)(name, outDir, this) : new targetClass(this, outDir, name));
416 }
417 }
418 }
419
420 getIconPath() {
421 return this._iconPath.value;
422 }
423
424 sign(file, logMessagePrefix) {
425 var _this2 = this;
426
427 return (0, _bluebirdLst().coroutine)(function* () {
428 const signOptions = {
429 path: file,
430 name: _this2.appInfo.productName,
431 site: yield _this2.appInfo.computePackageUrl(),
432 options: _this2.platformSpecificBuildOptions
433 };
434 const cscInfo = yield _this2.cscInfo.value;
435
436 if (cscInfo == null) {
437 if (_this2.platformSpecificBuildOptions.sign != null) {
438 yield (0, _windowsCodeSign().sign)(signOptions, _this2);
439 } else if (_this2.forceCodeSigning) {
440 throw new (_builderUtil().InvalidConfigurationError)(`App is not signed and "forceCodeSigning" is set to true, please ensure that code signing configuration is correct, please see https://electron.build/code-signing`);
441 }
442
443 return;
444 }
445
446 if (logMessagePrefix == null) {
447 logMessagePrefix = "signing";
448 }
449
450 if ("file" in cscInfo) {
451 _builderUtil().log.info({
452 file: _builderUtil().log.filePath(file),
453 certificateFile: cscInfo.file
454 }, logMessagePrefix);
455 } else {
456 const info = cscInfo;
457
458 _builderUtil().log.info({
459 file: _builderUtil().log.filePath(file),
460 subject: info.subject,
461 thumbprint: info.thumbprint,
462 store: info.store,
463 user: info.isLocalMachineStore ? "local machine" : "current user"
464 }, logMessagePrefix);
465 }
466
467 yield _this2.doSign(Object.assign({}, signOptions, {
468 cscInfo,
469 options: Object.assign({}, _this2.platformSpecificBuildOptions)
470 }));
471 })();
472 }
473
474 doSign(options) {
475 var _this3 = this;
476
477 return (0, _bluebirdLst().coroutine)(function* () {
478 for (let i = 0; i < 3; i++) {
479 try {
480 yield (0, _windowsCodeSign().sign)(options, _this3);
481 break;
482 } catch (e) {
483 // https://github.com/electron-userland/electron-builder/issues/1414
484 const message = e.message;
485
486 if (message != null && message.includes("Couldn't resolve host name")) {
487 _builderUtil().log.warn({
488 error: message,
489 attempt: i + 1
490 }, `cannot sign`);
491
492 continue;
493 }
494
495 throw e;
496 }
497 }
498 })();
499 }
500
501 signAndEditResources(file, arch, outDir, internalName, requestedExecutionLevel) {
502 var _this4 = this;
503
504 return (0, _bluebirdLst().coroutine)(function* () {
505 const appInfo = _this4.appInfo;
506 const files = [];
507 const args = [file, "--set-version-string", "FileDescription", appInfo.productName, "--set-version-string", "ProductName", appInfo.productName, "--set-version-string", "LegalCopyright", appInfo.copyright, "--set-file-version", appInfo.buildVersion, "--set-product-version", appInfo.versionInWeirdWindowsForm];
508
509 if (internalName != null) {
510 args.push("--set-version-string", "InternalName", internalName, "--set-version-string", "OriginalFilename", "");
511 }
512
513 if (requestedExecutionLevel != null && requestedExecutionLevel !== "asInvoker") {
514 args.push("--set-requested-execution-level", requestedExecutionLevel);
515 }
516
517 (0, _builderUtil().use)(appInfo.companyName, it => args.push("--set-version-string", "CompanyName", it));
518 (0, _builderUtil().use)(_this4.platformSpecificBuildOptions.legalTrademarks, it => args.push("--set-version-string", "LegalTrademarks", it));
519 const iconPath = yield _this4.getIconPath();
520 (0, _builderUtil().use)(iconPath, it => {
521 files.push(it);
522 args.push("--set-icon", it);
523 });
524 const config = _this4.config;
525 const cscInfoForCacheDigest = !(0, _flags().isBuildCacheEnabled)() || _isCi().default || config.electronDist != null ? null : yield _this4.cscInfo.value;
526 let buildCacheManager = null; // resources editing doesn't change executable for the same input and executed quickly - no need to complicate
527
528 if (cscInfoForCacheDigest != null) {
529 const cscFile = cscInfoForCacheDigest.file;
530
531 if (cscFile != null) {
532 files.push(cscFile);
533 }
534
535 const timer = (0, _timer().time)("executable cache");
536 const hash = (0, _crypto().createHash)("sha512");
537 hash.update(config.electronVersion || "no electronVersion");
538 hash.update(config.muonVersion || "no muonVersion");
539 hash.update(JSON.stringify(_this4.platformSpecificBuildOptions));
540 hash.update(JSON.stringify(args));
541 hash.update(_this4.platformSpecificBuildOptions.certificateSha1 || "no certificateSha1");
542 hash.update(_this4.platformSpecificBuildOptions.certificateSubjectName || "no subjectName");
543 buildCacheManager = new (_cacheManager().BuildCacheManager)(outDir, file, arch);
544
545 if (yield buildCacheManager.copyIfValid((yield (0, _cacheManager().digest)(hash, files)))) {
546 timer.end();
547 return;
548 }
549
550 timer.end();
551 }
552
553 const timer = (0, _timer().time)("wine&sign"); // wine supports only ia32
554
555 yield (0, _builderUtil().execWine)(path.join((yield (0, _windowsCodeSign().getSignVendorPath)()), `rcedit-${process.platform === "win32" ? process.arch : "ia32"}.exe`), args);
556 yield _this4.sign(file);
557 timer.end();
558
559 if (buildCacheManager != null) {
560 yield buildCacheManager.save();
561 }
562 })();
563 }
564
565 isSignDlls() {
566 return this.platformSpecificBuildOptions.signDlls === true;
567 }
568
569 createTransformerForExtraFiles(packContext) {
570 if (this.platformSpecificBuildOptions.signAndEditExecutable === false) {
571 return null;
572 }
573
574 return file => {
575 if (file.endsWith(".exe") || this.isSignDlls() && file.endsWith(".dll")) {
576 const parentDir = path.dirname(file);
577
578 if (parentDir !== packContext.appOutDir) {
579 return new (_fs().CopyFileTransformer)(file => this.sign(file));
580 }
581 }
582
583 return null;
584 };
585 }
586
587 signApp(packContext, isAsar) {
588 var _this5 = this;
589
590 return (0, _bluebirdLst().coroutine)(function* () {
591 const exeFileName = `${_this5.appInfo.productFilename}.exe`;
592
593 if (_this5.platformSpecificBuildOptions.signAndEditExecutable === false) {
594 return;
595 }
596
597 yield _bluebirdLst().default.map((0, _fsExtraP().readdir)(packContext.appOutDir), file => {
598 if (file === exeFileName) {
599 return _this5.signAndEditResources(path.join(packContext.appOutDir, exeFileName), packContext.arch, packContext.outDir, path.basename(exeFileName, ".exe"), _this5.platformSpecificBuildOptions.requestedExecutionLevel);
600 } else if (file.endsWith(".exe") || _this5.isSignDlls() && file.endsWith(".dll")) {
601 return _this5.sign(path.join(packContext.appOutDir, file));
602 }
603
604 return null;
605 });
606
607 if (!isAsar) {
608 return;
609 }
610
611 const outResourcesDir = path.join(packContext.appOutDir, "resources", "app.asar.unpacked");
612 yield _bluebirdLst().default.map((0, _promise().orIfFileNotExist)((0, _fsExtraP().readdir)(outResourcesDir), []), file => {
613 if (file.endsWith(".exe") || file.endsWith(".dll")) {
614 return _this5.sign(path.join(outResourcesDir, file));
615 } else {
616 return null;
617 }
618 });
619 })();
620 }
621
622}
623
624exports.WinPackager = WinPackager;
625const debugOpenssl = (0, _debug2.default)("electron-builder:openssl");
626//# sourceMappingURL=winPackager.js.map
\No newline at end of file