NsisUpdater.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.NsisUpdater = void 0;
  6. function _bluebirdLst() {
  7. const data = require("bluebird-lst");
  8. _bluebirdLst = function () {
  9. return data;
  10. };
  11. return data;
  12. }
  13. function _builderUtilRuntime() {
  14. const data = require("builder-util-runtime");
  15. _builderUtilRuntime = function () {
  16. return data;
  17. };
  18. return data;
  19. }
  20. function _child_process() {
  21. const data = require("child_process");
  22. _child_process = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. var path = _interopRequireWildcard(require("path"));
  28. require("source-map-support/register");
  29. function _BaseUpdater() {
  30. const data = require("./BaseUpdater");
  31. _BaseUpdater = function () {
  32. return data;
  33. };
  34. return data;
  35. }
  36. function _FileWithEmbeddedBlockMapDifferentialDownloader() {
  37. const data = require("./differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader");
  38. _FileWithEmbeddedBlockMapDifferentialDownloader = function () {
  39. return data;
  40. };
  41. return data;
  42. }
  43. function _GenericDifferentialDownloader() {
  44. const data = require("./differentialDownloader/GenericDifferentialDownloader");
  45. _GenericDifferentialDownloader = function () {
  46. return data;
  47. };
  48. return data;
  49. }
  50. function _main() {
  51. const data = require("./main");
  52. _main = function () {
  53. return data;
  54. };
  55. return data;
  56. }
  57. function _Provider() {
  58. const data = require("./providers/Provider");
  59. _Provider = function () {
  60. return data;
  61. };
  62. return data;
  63. }
  64. function _fsExtraP() {
  65. const data = require("fs-extra-p");
  66. _fsExtraP = function () {
  67. return data;
  68. };
  69. return data;
  70. }
  71. function _windowsExecutableCodeSignatureVerifier() {
  72. const data = require("./windowsExecutableCodeSignatureVerifier");
  73. _windowsExecutableCodeSignatureVerifier = function () {
  74. return data;
  75. };
  76. return data;
  77. }
  78. function _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; } }
  79. class NsisUpdater extends _BaseUpdater().BaseUpdater {
  80. constructor(options, app) {
  81. super(options, app);
  82. }
  83. /*** @private */
  84. doDownloadUpdate(downloadUpdateOptions) {
  85. var _this = this;
  86. return (0, _bluebirdLst().coroutine)(function* () {
  87. const provider = yield _this.provider;
  88. const fileInfo = (0, _Provider().findFile)(provider.resolveFiles(downloadUpdateOptions.updateInfo), "exe");
  89. return yield _this.executeDownload({
  90. fileExtension: "exe",
  91. downloadUpdateOptions,
  92. fileInfo,
  93. task: (() => {
  94. var _ref = (0, _bluebirdLst().coroutine)(function* (destinationFile, downloadOptions, packageFile, removeTempDirIfAny) {
  95. const packageInfo = fileInfo.packageInfo;
  96. const isWebInstaller = packageInfo != null && packageFile != null;
  97. if (isWebInstaller || (yield _this.differentialDownloadInstaller(fileInfo, downloadUpdateOptions, destinationFile, downloadUpdateOptions.requestHeaders, provider))) {
  98. yield _this.httpExecutor.download(fileInfo.url.href, destinationFile, downloadOptions);
  99. }
  100. const signatureVerificationStatus = yield _this.verifySignature(destinationFile);
  101. if (signatureVerificationStatus != null) {
  102. yield removeTempDirIfAny(); // noinspection ThrowInsideFinallyBlockJS
  103. throw (0, _builderUtilRuntime().newError)(`New version ${downloadUpdateOptions.updateInfo.version} is not signed by the application owner: ${signatureVerificationStatus}`, "ERR_UPDATER_INVALID_SIGNATURE");
  104. }
  105. if (isWebInstaller) {
  106. if (yield _this.differentialDownloadWebPackage(packageInfo, packageFile, provider)) {
  107. try {
  108. yield _this.httpExecutor.download(packageInfo.path, packageFile, {
  109. skipDirCreation: true,
  110. headers: downloadUpdateOptions.requestHeaders,
  111. cancellationToken: downloadUpdateOptions.cancellationToken,
  112. sha512: packageInfo.sha512
  113. });
  114. } catch (e) {
  115. try {
  116. yield (0, _fsExtraP().unlink)(packageFile);
  117. } catch (ignored) {// ignore
  118. }
  119. throw e;
  120. }
  121. }
  122. }
  123. });
  124. return function task(_x, _x2, _x3, _x4) {
  125. return _ref.apply(this, arguments);
  126. };
  127. })()
  128. });
  129. })();
  130. } // $certificateInfo = (Get-AuthenticodeSignature 'xxx\yyy.exe'
  131. // | where {$_.Status.Equals([System.Management.Automation.SignatureStatus]::Valid) -and $_.SignerCertificate.Subject.Contains("CN=siemens.com")})
  132. // | Out-String ; if ($certificateInfo) { exit 0 } else { exit 1 }
  133. verifySignature(tempUpdateFile) {
  134. var _this2 = this;
  135. return (0, _bluebirdLst().coroutine)(function* () {
  136. let publisherName;
  137. try {
  138. publisherName = (yield _this2.configOnDisk.value).publisherName;
  139. if (publisherName == null) {
  140. return null;
  141. }
  142. } catch (e) {
  143. if (e.code === "ENOENT") {
  144. // no app-update.yml
  145. return null;
  146. }
  147. throw e;
  148. }
  149. return yield (0, _windowsExecutableCodeSignatureVerifier().verifySignature)(Array.isArray(publisherName) ? publisherName : [publisherName], tempUpdateFile, _this2._logger);
  150. })();
  151. }
  152. doInstall(installerPath, isSilent, isForceRunAfter) {
  153. const args = ["--updated"];
  154. if (isSilent) {
  155. args.push("/S");
  156. }
  157. if (isForceRunAfter) {
  158. args.push("--force-run");
  159. }
  160. const packagePath = this.downloadedUpdateHelper.packageFile;
  161. if (packagePath != null) {
  162. // only = form is supported
  163. args.push(`--package-file="${packagePath}"`);
  164. }
  165. const spawnOptions = {
  166. detached: true,
  167. stdio: "ignore"
  168. };
  169. try {
  170. (0, _child_process().spawn)(installerPath, args, spawnOptions).unref();
  171. } catch (e) {
  172. // yes, such errors dispatched not as error event
  173. // https://github.com/electron-userland/electron-builder/issues/1129
  174. if (e.code === "UNKNOWN" || e.code === "EACCES") {
  175. // Node 8 sends errors: https://nodejs.org/dist/latest-v8.x/docs/api/errors.html#errors_common_system_errors
  176. this._logger.info("Access denied or UNKNOWN error code on spawn, will be executed again using elevate");
  177. try {
  178. (0, _child_process().spawn)(path.join(process.resourcesPath, "elevate.exe"), [installerPath].concat(args), spawnOptions).unref();
  179. } catch (e) {
  180. this.dispatchError(e);
  181. }
  182. } else {
  183. this.dispatchError(e);
  184. }
  185. }
  186. return true;
  187. } // private downloadBlockMap(provider: Provider<any>) {
  188. // await provider.getBytes(newBlockMapUrl, cancellationToken)
  189. // }
  190. differentialDownloadInstaller(fileInfo, downloadUpdateOptions, installerPath, requestHeaders, provider) {
  191. var _this3 = this;
  192. return (0, _bluebirdLst().coroutine)(function* () {
  193. try {
  194. const newBlockMapUrl = (0, _main().newUrlFromBase)(`${fileInfo.url.pathname}.blockmap`, fileInfo.url);
  195. const oldBlockMapUrl = (0, _main().newUrlFromBase)(`${fileInfo.url.pathname.replace(new RegExp(downloadUpdateOptions.updateInfo.version, "g"), _this3.currentVersion.version)}.blockmap`, fileInfo.url);
  196. _this3._logger.info(`Download block maps (old: "${oldBlockMapUrl.href}", new: ${newBlockMapUrl.href})`);
  197. const downloadBlockMap = (() => {
  198. var _ref2 = (0, _bluebirdLst().coroutine)(function* (url) {
  199. const requestOptions = (0, _Provider().configureRequestOptionsFromUrl)(url, {
  200. headers: downloadUpdateOptions.requestHeaders
  201. });
  202. requestOptions.gzip = true;
  203. const data = yield _this3.httpExecutor.request(requestOptions, downloadUpdateOptions.cancellationToken);
  204. if (data == null) {
  205. throw new Error(`Blockmap "${url.href}" is empty`);
  206. }
  207. try {
  208. return JSON.parse(data);
  209. } catch (e) {
  210. throw new Error(`Cannot parse blockmap "${url.href}", error: ${e}, raw data: ${data}`);
  211. }
  212. });
  213. return function downloadBlockMap(_x5) {
  214. return _ref2.apply(this, arguments);
  215. };
  216. })();
  217. const blockMapData = yield downloadBlockMap(newBlockMapUrl);
  218. const oldBlockMapData = yield downloadBlockMap(oldBlockMapUrl);
  219. yield new (_GenericDifferentialDownloader().GenericDifferentialDownloader)(fileInfo.info, _this3.httpExecutor, {
  220. newUrl: fileInfo.url.href,
  221. oldFile: path.join(_this3.app.getPath("userData"), _builderUtilRuntime().CURRENT_APP_INSTALLER_FILE_NAME),
  222. logger: _this3._logger,
  223. newFile: installerPath,
  224. useMultipleRangeRequest: provider.useMultipleRangeRequest,
  225. requestHeaders
  226. }).download(oldBlockMapData, blockMapData);
  227. } catch (e) {
  228. _this3._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`);
  229. return true;
  230. }
  231. return false;
  232. })();
  233. }
  234. differentialDownloadWebPackage(packageInfo, packagePath, provider) {
  235. var _this4 = this;
  236. return (0, _bluebirdLst().coroutine)(function* () {
  237. if (packageInfo.blockMapSize == null) {
  238. return true;
  239. }
  240. try {
  241. yield new (_FileWithEmbeddedBlockMapDifferentialDownloader().FileWithEmbeddedBlockMapDifferentialDownloader)(packageInfo, _this4.httpExecutor, {
  242. newUrl: packageInfo.path,
  243. oldFile: path.join(_this4.app.getPath("userData"), _builderUtilRuntime().CURRENT_APP_PACKAGE_FILE_NAME),
  244. logger: _this4._logger,
  245. newFile: packagePath,
  246. requestHeaders: _this4.requestHeaders,
  247. useMultipleRangeRequest: provider.useMultipleRangeRequest
  248. }).download();
  249. } catch (e) {
  250. _this4._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`); // during test (developer machine mac or linux) we must throw error
  251. return process.platform === "win32";
  252. }
  253. return false;
  254. })();
  255. }
  256. } exports.NsisUpdater = NsisUpdater;
  257. //# sourceMappingURL=NsisUpdater.js.map