MacUpdater.js 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", {
  3. value: true
  4. });
  5. exports.MacUpdater = 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 _http() {
  21. const data = require("http");
  22. _http = function () {
  23. return data;
  24. };
  25. return data;
  26. }
  27. function _AppUpdater() {
  28. const data = require("./AppUpdater");
  29. _AppUpdater = function () {
  30. return data;
  31. };
  32. return data;
  33. }
  34. function _main() {
  35. const data = require("./main");
  36. _main = function () {
  37. return data;
  38. };
  39. return data;
  40. }
  41. function _Provider() {
  42. const data = require("./providers/Provider");
  43. _Provider = function () {
  44. return data;
  45. };
  46. return data;
  47. }
  48. function _fsExtraP() {
  49. const data = require("fs-extra-p");
  50. _fsExtraP = function () {
  51. return data;
  52. };
  53. return data;
  54. }
  55. class MacUpdater extends _AppUpdater().AppUpdater {
  56. constructor(options) {
  57. super(options);
  58. this.nativeUpdater = require("electron").autoUpdater;
  59. this.nativeUpdater.on("error", it => {
  60. this._logger.warn(it);
  61. this.emit("error", it);
  62. });
  63. }
  64. doDownloadUpdate(downloadUpdateOptions) {
  65. var _this = this;
  66. return (0, _bluebirdLst().coroutine)(function* () {
  67. const files = (yield _this.provider).resolveFiles(downloadUpdateOptions.updateInfo);
  68. const zipFileInfo = (0, _Provider().findFile)(files, "zip", ["pkg", "dmg"]);
  69. if (zipFileInfo == null) {
  70. throw (0, _builderUtilRuntime().newError)(`ZIP file not provided: ${(0, _builderUtilRuntime().safeStringifyJson)(files)}`, "ERR_UPDATER_ZIP_FILE_NOT_FOUND");
  71. }
  72. const server = (0, _http().createServer)();
  73. server.on("close", () => {
  74. _this._logger.info(`Proxy server for native Squirrel.Mac is closed (was started to download ${zipFileInfo.url.href})`);
  75. });
  76. function getServerUrl() {
  77. const address = server.address();
  78. return `http://${address.address}:${address.port}`;
  79. }
  80. return yield _this.executeDownload({
  81. fileExtension: "zip",
  82. fileInfo: zipFileInfo,
  83. downloadUpdateOptions,
  84. task: (destinationFile, downloadOptions) => {
  85. return _this.httpExecutor.download(zipFileInfo.url.href, destinationFile, downloadOptions);
  86. },
  87. done: (() => {
  88. var _ref = (0, _bluebirdLst().coroutine)(function* (updateFile) {
  89. let updateFileSize = zipFileInfo.info.size;
  90. if (updateFileSize == null) {
  91. updateFileSize = (yield (0, _fsExtraP().stat)(updateFile)).size;
  92. }
  93. return yield new Promise((resolve, reject) => {
  94. server.on("request", (request, response) => {
  95. const requestUrl = request.url;
  96. _this._logger.info(`${requestUrl} requested`);
  97. if (requestUrl === "/") {
  98. const data = Buffer.from(`{ "url": "${getServerUrl()}/app.zip" }`);
  99. response.writeHead(200, {
  100. "Content-Type": "application/json",
  101. "Content-Length": data.length
  102. });
  103. response.end(data);
  104. } else if (requestUrl.startsWith("/app.zip")) {
  105. let errorOccurred = false;
  106. response.on("finish", () => {
  107. try {
  108. setImmediate(() => server.close());
  109. } finally {
  110. if (!errorOccurred) {
  111. _this.nativeUpdater.removeListener("error", reject);
  112. resolve([]);
  113. }
  114. }
  115. });
  116. _this._logger.info(`app.zip requested by Squirrel.Mac, pipe ${updateFile}`);
  117. const readStream = (0, _fsExtraP().createReadStream)(updateFile);
  118. readStream.on("error", error => {
  119. try {
  120. response.end();
  121. } catch (e) {
  122. errorOccurred = true;
  123. _this.nativeUpdater.removeListener("error", reject);
  124. reject(new Error(`Cannot pipe "${updateFile}": ${error}`));
  125. }
  126. });
  127. response.writeHead(200, {
  128. "Content-Type": "application/zip",
  129. "Content-Length": updateFileSize
  130. });
  131. readStream.pipe(response);
  132. } else {
  133. _this._logger.warn(`${requestUrl} requested, but not supported`);
  134. response.writeHead(404);
  135. response.end();
  136. }
  137. });
  138. server.listen(0, "127.0.0.1", 8, () => {
  139. _this.nativeUpdater.setFeedURL(`${getServerUrl()}`, {
  140. "Cache-Control": "no-cache"
  141. });
  142. _this.nativeUpdater.once("error", reject);
  143. _this.nativeUpdater.checkForUpdates();
  144. });
  145. });
  146. });
  147. return function done(_x) {
  148. return _ref.apply(this, arguments);
  149. };
  150. })()
  151. });
  152. })();
  153. }
  154. doProxyUpdateFile(nativeResponse, url, headers, sha512, cancellationToken, errorHandler) {
  155. const downloadRequest = this.httpExecutor.doRequest((0, _builderUtilRuntime().configureRequestOptionsFromUrl)(url, {
  156. headers
  157. }), downloadResponse => {
  158. const nativeHeaders = {
  159. "Content-Type": "application/zip"
  160. };
  161. const streams = [];
  162. const downloadListenerCount = this.listenerCount(_main().DOWNLOAD_PROGRESS);
  163. this._logger.info(`${_main().DOWNLOAD_PROGRESS} listener count: ${downloadListenerCount}`);
  164. nativeResponse.writeHead(200, nativeHeaders); // for mac only sha512 is produced (sha256 is published for windows only to preserve backward compatibility)
  165. if (sha512 != null) {
  166. // "hex" to easy migrate to new base64 encoded hash (we already produces latest-mac.yml with hex encoded hash)
  167. streams.push(new (_builderUtilRuntime().DigestTransform)(sha512, "sha512", sha512.length === 128 && !sha512.includes("+") && !sha512.includes("Z") && !sha512.includes("=") ? "hex" : "base64"));
  168. }
  169. streams.push(nativeResponse);
  170. let lastStream = downloadResponse;
  171. for (const stream of streams) {
  172. stream.on("error", errorHandler);
  173. lastStream = lastStream.pipe(stream);
  174. }
  175. });
  176. downloadRequest.on("redirect", (statusCode, method, redirectUrl) => {
  177. if (headers.authorization != null && headers.authorization.startsWith("token")) {
  178. const parsedNewUrl = new URL(redirectUrl);
  179. if (parsedNewUrl.hostname.endsWith(".amazonaws.com")) {
  180. delete headers.authorization;
  181. }
  182. }
  183. this.doProxyUpdateFile(nativeResponse, redirectUrl, headers, sha512, cancellationToken, errorHandler);
  184. });
  185. downloadRequest.on("error", errorHandler);
  186. downloadRequest.end();
  187. }
  188. quitAndInstall() {
  189. this.nativeUpdater.quitAndInstall();
  190. }
  191. } exports.MacUpdater = MacUpdater;
  192. //# sourceMappingURL=MacUpdater.js.map