UNPKG

11 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.NsisUpdater = void 0;
7
8function _builderUtilRuntime() {
9 const data = require("builder-util-runtime");
10
11 _builderUtilRuntime = function () {
12 return data;
13 };
14
15 return data;
16}
17
18function _child_process() {
19 const data = require("child_process");
20
21 _child_process = function () {
22 return data;
23 };
24
25 return data;
26}
27
28var path = _interopRequireWildcard(require("path"));
29
30function _BaseUpdater() {
31 const data = require("./BaseUpdater");
32
33 _BaseUpdater = function () {
34 return data;
35 };
36
37 return data;
38}
39
40function _FileWithEmbeddedBlockMapDifferentialDownloader() {
41 const data = require("./differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader");
42
43 _FileWithEmbeddedBlockMapDifferentialDownloader = function () {
44 return data;
45 };
46
47 return data;
48}
49
50function _GenericDifferentialDownloader() {
51 const data = require("./differentialDownloader/GenericDifferentialDownloader");
52
53 _GenericDifferentialDownloader = function () {
54 return data;
55 };
56
57 return data;
58}
59
60function _main() {
61 const data = require("./main");
62
63 _main = function () {
64 return data;
65 };
66
67 return data;
68}
69
70function _Provider() {
71 const data = require("./providers/Provider");
72
73 _Provider = function () {
74 return data;
75 };
76
77 return data;
78}
79
80function _fsExtra() {
81 const data = require("fs-extra");
82
83 _fsExtra = function () {
84 return data;
85 };
86
87 return data;
88}
89
90function _windowsExecutableCodeSignatureVerifier() {
91 const data = require("./windowsExecutableCodeSignatureVerifier");
92
93 _windowsExecutableCodeSignatureVerifier = function () {
94 return data;
95 };
96
97 return data;
98}
99
100function _url() {
101 const data = require("url");
102
103 _url = function () {
104 return data;
105 };
106
107 return data;
108}
109
110function _zlib() {
111 const data = require("zlib");
112
113 _zlib = function () {
114 return data;
115 };
116
117 return data;
118}
119
120function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
121
122function _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; }
123
124class NsisUpdater extends _BaseUpdater().BaseUpdater {
125 constructor(options, app) {
126 super(options, app);
127 }
128 /*** @private */
129
130
131 doDownloadUpdate(downloadUpdateOptions) {
132 const provider = downloadUpdateOptions.updateInfoAndProvider.provider;
133 const fileInfo = (0, _Provider().findFile)(provider.resolveFiles(downloadUpdateOptions.updateInfoAndProvider.info), "exe");
134 return this.executeDownload({
135 fileExtension: "exe",
136 downloadUpdateOptions,
137 fileInfo,
138 task: async (destinationFile, downloadOptions, packageFile, removeTempDirIfAny) => {
139 const packageInfo = fileInfo.packageInfo;
140 const isWebInstaller = packageInfo != null && packageFile != null;
141
142 if (isWebInstaller || (await this.differentialDownloadInstaller(fileInfo, downloadUpdateOptions, destinationFile, provider))) {
143 await this.httpExecutor.download(fileInfo.url, destinationFile, downloadOptions);
144 }
145
146 const signatureVerificationStatus = await this.verifySignature(destinationFile);
147
148 if (signatureVerificationStatus != null) {
149 await removeTempDirIfAny(); // noinspection ThrowInsideFinallyBlockJS
150
151 throw (0, _builderUtilRuntime().newError)(`New version ${downloadUpdateOptions.updateInfoAndProvider.info.version} is not signed by the application owner: ${signatureVerificationStatus}`, "ERR_UPDATER_INVALID_SIGNATURE");
152 }
153
154 if (isWebInstaller) {
155 if (await this.differentialDownloadWebPackage(packageInfo, packageFile, provider)) {
156 try {
157 await this.httpExecutor.download(new (_url().URL)(packageInfo.path), packageFile, {
158 headers: downloadUpdateOptions.requestHeaders,
159 cancellationToken: downloadUpdateOptions.cancellationToken,
160 sha512: packageInfo.sha512
161 });
162 } catch (e) {
163 try {
164 await (0, _fsExtra().unlink)(packageFile);
165 } catch (ignored) {// ignore
166 }
167
168 throw e;
169 }
170 }
171 }
172 }
173 });
174 } // $certificateInfo = (Get-AuthenticodeSignature 'xxx\yyy.exe'
175 // | where {$_.Status.Equals([System.Management.Automation.SignatureStatus]::Valid) -and $_.SignerCertificate.Subject.Contains("CN=siemens.com")})
176 // | Out-String ; if ($certificateInfo) { exit 0 } else { exit 1 }
177
178
179 async verifySignature(tempUpdateFile) {
180 let publisherName;
181
182 try {
183 publisherName = (await this.configOnDisk.value).publisherName;
184
185 if (publisherName == null) {
186 return null;
187 }
188 } catch (e) {
189 if (e.code === "ENOENT") {
190 // no app-update.yml
191 return null;
192 }
193
194 throw e;
195 }
196
197 return await (0, _windowsExecutableCodeSignatureVerifier().verifySignature)(Array.isArray(publisherName) ? publisherName : [publisherName], tempUpdateFile, this._logger);
198 }
199
200 doInstall(options) {
201 const args = ["--updated"];
202
203 if (options.isSilent) {
204 args.push("/S");
205 }
206
207 if (options.isForceRunAfter) {
208 args.push("--force-run");
209 }
210
211 const packagePath = this.downloadedUpdateHelper == null ? null : this.downloadedUpdateHelper.packageFile;
212
213 if (packagePath != null) {
214 // only = form is supported
215 args.push(`--package-file=${packagePath}`);
216 }
217
218 const callUsingElevation = () => {
219 _spawn(path.join(process.resourcesPath, "elevate.exe"), [options.installerPath].concat(args)).catch(e => this.dispatchError(e));
220 };
221
222 if (options.isAdminRightsRequired) {
223 this._logger.info("isAdminRightsRequired is set to true, run installer using elevate.exe");
224
225 callUsingElevation();
226 return true;
227 }
228
229 _spawn(options.installerPath, args).catch(e => {
230 // https://github.com/electron-userland/electron-builder/issues/1129
231 // Node 8 sends errors: https://nodejs.org/dist/latest-v8.x/docs/api/errors.html#errors_common_system_errors
232 const errorCode = e.code;
233
234 this._logger.info(`Cannot run installer: error code: ${errorCode}, error message: "${e.message}", will be executed again using elevate if EACCES"`);
235
236 if (errorCode === "UNKNOWN" || errorCode === "EACCES") {
237 callUsingElevation();
238 } else {
239 this.dispatchError(e);
240 }
241 });
242
243 return true;
244 }
245
246 async differentialDownloadInstaller(fileInfo, downloadUpdateOptions, installerPath, provider) {
247 try {
248 if (this._testOnlyOptions != null && !this._testOnlyOptions.isUseDifferentialDownload) {
249 return true;
250 }
251
252 const newBlockMapUrl = (0, _main().newUrlFromBase)(`${fileInfo.url.pathname}.blockmap`, fileInfo.url);
253 const oldBlockMapUrl = (0, _main().newUrlFromBase)(`${fileInfo.url.pathname.replace(new RegExp(downloadUpdateOptions.updateInfoAndProvider.info.version, "g"), this.app.version)}.blockmap`, fileInfo.url);
254
255 this._logger.info(`Download block maps (old: "${oldBlockMapUrl.href}", new: ${newBlockMapUrl.href})`);
256
257 const downloadBlockMap = async url => {
258 const data = await this.httpExecutor.downloadToBuffer(url, {
259 headers: downloadUpdateOptions.requestHeaders,
260 cancellationToken: downloadUpdateOptions.cancellationToken
261 });
262
263 if (data == null || data.length === 0) {
264 throw new Error(`Blockmap "${url.href}" is empty`);
265 }
266
267 try {
268 return JSON.parse((0, _zlib().gunzipSync)(data).toString());
269 } catch (e) {
270 throw new Error(`Cannot parse blockmap "${url.href}", error: ${e}, raw data: ${data}`);
271 }
272 };
273
274 const blockMapDataList = await Promise.all([downloadBlockMap(oldBlockMapUrl), downloadBlockMap(newBlockMapUrl)]);
275 await new (_GenericDifferentialDownloader().GenericDifferentialDownloader)(fileInfo.info, this.httpExecutor, {
276 newUrl: fileInfo.url,
277 oldFile: path.join(this.downloadedUpdateHelper.cacheDir, _builderUtilRuntime().CURRENT_APP_INSTALLER_FILE_NAME),
278 logger: this._logger,
279 newFile: installerPath,
280 isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest,
281 requestHeaders: downloadUpdateOptions.requestHeaders
282 }).download(blockMapDataList[0], blockMapDataList[1]);
283 return false;
284 } catch (e) {
285 this._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`);
286
287 if (this._testOnlyOptions != null) {
288 // test mode
289 throw e;
290 }
291
292 return true;
293 }
294 }
295
296 async differentialDownloadWebPackage(packageInfo, packagePath, provider) {
297 if (packageInfo.blockMapSize == null) {
298 return true;
299 }
300
301 try {
302 await new (_FileWithEmbeddedBlockMapDifferentialDownloader().FileWithEmbeddedBlockMapDifferentialDownloader)(packageInfo, this.httpExecutor, {
303 newUrl: new (_url().URL)(packageInfo.path),
304 oldFile: path.join(this.downloadedUpdateHelper.cacheDir, _builderUtilRuntime().CURRENT_APP_PACKAGE_FILE_NAME),
305 logger: this._logger,
306 newFile: packagePath,
307 requestHeaders: this.requestHeaders,
308 isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest
309 }).download();
310 } catch (e) {
311 this._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`); // during test (developer machine mac or linux) we must throw error
312
313
314 return process.platform === "win32";
315 }
316
317 return false;
318 }
319
320}
321/**
322 * This handles both node 8 and node 10 way of emitting error when spawning a process
323 * - node 8: Throws the error
324 * - node 10: Emit the error(Need to listen with on)
325 */
326
327
328exports.NsisUpdater = NsisUpdater;
329
330async function _spawn(exe, args) {
331 return new Promise((resolve, reject) => {
332 try {
333 const process = (0, _child_process().spawn)(exe, args, {
334 detached: true,
335 stdio: "ignore"
336 });
337 process.on("error", error => {
338 reject(error);
339 });
340 process.unref();
341
342 if (process.pid !== undefined) {
343 resolve(true);
344 }
345 } catch (error) {
346 reject(error);
347 }
348 });
349}
350// __ts-babel@6.0.4
351//# sourceMappingURL=NsisUpdater.js.map
\No newline at end of file