1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.createTempUpdateFile = createTempUpdateFile;
|
7 | exports.DownloadedUpdateHelper = void 0;
|
8 |
|
9 | function _crypto() {
|
10 | const data = require("crypto");
|
11 |
|
12 | _crypto = function () {
|
13 | return data;
|
14 | };
|
15 |
|
16 | return data;
|
17 | }
|
18 |
|
19 | var _fs = require("fs");
|
20 |
|
21 | function _lodash() {
|
22 | const data = _interopRequireDefault(require("lodash.isequal"));
|
23 |
|
24 | _lodash = function () {
|
25 | return data;
|
26 | };
|
27 |
|
28 | return data;
|
29 | }
|
30 |
|
31 | function _fsExtra() {
|
32 | const data = require("fs-extra");
|
33 |
|
34 | _fsExtra = function () {
|
35 | return data;
|
36 | };
|
37 |
|
38 | return data;
|
39 | }
|
40 |
|
41 | var path = _interopRequireWildcard(require("path"));
|
42 |
|
43 | function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
|
44 |
|
45 | 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; }
|
46 |
|
47 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
48 |
|
49 |
|
50 | class DownloadedUpdateHelper {
|
51 | constructor(cacheDir) {
|
52 | this.cacheDir = cacheDir;
|
53 | this._file = null;
|
54 | this._packageFile = null;
|
55 | this.versionInfo = null;
|
56 | this.fileInfo = null;
|
57 | this._downloadedFileInfo = null;
|
58 | }
|
59 |
|
60 | get downloadedFileInfo() {
|
61 | return this._downloadedFileInfo;
|
62 | }
|
63 |
|
64 | get file() {
|
65 | return this._file;
|
66 | }
|
67 |
|
68 | get packageFile() {
|
69 | return this._packageFile;
|
70 | }
|
71 |
|
72 | get cacheDirForPendingUpdate() {
|
73 | return path.join(this.cacheDir, "pending");
|
74 | }
|
75 |
|
76 | async validateDownloadedPath(updateFile, updateInfo, fileInfo, logger) {
|
77 | if (this.versionInfo != null && this.file === updateFile && this.fileInfo != null) {
|
78 |
|
79 |
|
80 | if ((0, _lodash().default)(this.versionInfo, updateInfo) && (0, _lodash().default)(this.fileInfo.info, fileInfo.info) && (await (0, _fsExtra().pathExists)(updateFile))) {
|
81 | return updateFile;
|
82 | } else {
|
83 | return null;
|
84 | }
|
85 | }
|
86 |
|
87 |
|
88 | const cachedUpdateFile = await this.getValidCachedUpdateFile(fileInfo, logger);
|
89 |
|
90 | if (cachedUpdateFile === null) {
|
91 | return null;
|
92 | }
|
93 |
|
94 | logger.info(`Update has already been downloaded to ${updateFile}).`);
|
95 | this._file = cachedUpdateFile;
|
96 | return cachedUpdateFile;
|
97 | }
|
98 |
|
99 | async setDownloadedFile(downloadedFile, packageFile, versionInfo, fileInfo, updateFileName, isSaveCache) {
|
100 | this._file = downloadedFile;
|
101 | this._packageFile = packageFile;
|
102 | this.versionInfo = versionInfo;
|
103 | this.fileInfo = fileInfo;
|
104 | this._downloadedFileInfo = {
|
105 | fileName: updateFileName,
|
106 | sha512: fileInfo.info.sha512,
|
107 | isAdminRightsRequired: fileInfo.info.isAdminRightsRequired === true
|
108 | };
|
109 |
|
110 | if (isSaveCache) {
|
111 | await (0, _fsExtra().outputJson)(this.getUpdateInfoFile(), this._downloadedFileInfo);
|
112 | }
|
113 | }
|
114 |
|
115 | async clear() {
|
116 | this._file = null;
|
117 | this._packageFile = null;
|
118 | this.versionInfo = null;
|
119 | this.fileInfo = null;
|
120 | await this.cleanCacheDirForPendingUpdate();
|
121 | }
|
122 |
|
123 | async cleanCacheDirForPendingUpdate() {
|
124 | try {
|
125 |
|
126 | await (0, _fsExtra().emptyDir)(this.cacheDirForPendingUpdate);
|
127 | } catch (ignore) {
|
128 | }
|
129 | }
|
130 | |
131 |
|
132 |
|
133 |
|
134 |
|
135 |
|
136 |
|
137 | async getValidCachedUpdateFile(fileInfo, logger) {
|
138 | var _a;
|
139 |
|
140 | const updateInfoFilePath = this.getUpdateInfoFile();
|
141 | const doesUpdateInfoFileExist = await (0, _fsExtra().pathExistsSync)(updateInfoFilePath);
|
142 |
|
143 | if (!doesUpdateInfoFileExist) {
|
144 | return null;
|
145 | }
|
146 |
|
147 | let cachedInfo;
|
148 |
|
149 | try {
|
150 | cachedInfo = await (0, _fsExtra().readJson)(updateInfoFilePath);
|
151 | } catch (error) {
|
152 | let message = `No cached update info available`;
|
153 |
|
154 | if (error.code !== "ENOENT") {
|
155 | await this.cleanCacheDirForPendingUpdate();
|
156 | message += ` (error on read: ${error.message})`;
|
157 | }
|
158 |
|
159 | logger.info(message);
|
160 | return null;
|
161 | }
|
162 |
|
163 | const isCachedInfoFileNameValid = (_a = (cachedInfo === null || cachedInfo === void 0 ? void 0 : cachedInfo.fileName) !== null) !== null && _a !== void 0 ? _a : false;
|
164 |
|
165 | if (!isCachedInfoFileNameValid) {
|
166 | logger.warn(`Cached update info is corrupted: no fileName, directory for cached update will be cleaned`);
|
167 | await this.cleanCacheDirForPendingUpdate();
|
168 | return null;
|
169 | }
|
170 |
|
171 | if (fileInfo.info.sha512 !== cachedInfo.sha512) {
|
172 | logger.info(`Cached update sha512 checksum doesn't match the latest available update. New update must be downloaded. Cached: ${cachedInfo.sha512}, expected: ${fileInfo.info.sha512}. Directory for cached update will be cleaned`);
|
173 | await this.cleanCacheDirForPendingUpdate();
|
174 | return null;
|
175 | }
|
176 |
|
177 | const updateFile = path.join(this.cacheDirForPendingUpdate, cachedInfo.fileName);
|
178 |
|
179 | if (!(await (0, _fsExtra().pathExists)(updateFile))) {
|
180 | logger.info("Cached update file doesn't exist, directory for cached update will be cleaned");
|
181 | await this.cleanCacheDirForPendingUpdate();
|
182 | return null;
|
183 | }
|
184 |
|
185 | const sha512 = await hashFile(updateFile);
|
186 |
|
187 | if (fileInfo.info.sha512 !== sha512) {
|
188 | logger.warn(`Sha512 checksum doesn't match the latest available update. New update must be downloaded. Cached: ${sha512}, expected: ${fileInfo.info.sha512}`);
|
189 | await this.cleanCacheDirForPendingUpdate();
|
190 | return null;
|
191 | }
|
192 |
|
193 | this._downloadedFileInfo = cachedInfo;
|
194 | return updateFile;
|
195 | }
|
196 |
|
197 | getUpdateInfoFile() {
|
198 | return path.join(this.cacheDirForPendingUpdate, "update-info.json");
|
199 | }
|
200 |
|
201 | }
|
202 |
|
203 | exports.DownloadedUpdateHelper = DownloadedUpdateHelper;
|
204 |
|
205 | function hashFile(file, algorithm = "sha512", encoding = "base64", options) {
|
206 | return new Promise((resolve, reject) => {
|
207 | const hash = (0, _crypto().createHash)(algorithm);
|
208 | hash.on("error", reject).setEncoding(encoding);
|
209 | (0, _fs.createReadStream)(file, { ...options,
|
210 | highWaterMark: 1024 * 1024
|
211 |
|
212 |
|
213 | }).on("error", reject).on("end", () => {
|
214 | hash.end();
|
215 | resolve(hash.read());
|
216 | }).pipe(hash, {
|
217 | end: false
|
218 | });
|
219 | });
|
220 | }
|
221 |
|
222 | async function createTempUpdateFile(name, cacheDir, log) {
|
223 |
|
224 | let nameCounter = 0;
|
225 | let result = path.join(cacheDir, name);
|
226 |
|
227 | for (let i = 0; i < 3; i++) {
|
228 | try {
|
229 | await (0, _fsExtra().unlink)(result);
|
230 | return result;
|
231 | } catch (e) {
|
232 | if (e.code === "ENOENT") {
|
233 | return result;
|
234 | }
|
235 |
|
236 | log.warn(`Error on remove temp update file: ${e}`);
|
237 | result = path.join(cacheDir, `${nameCounter++}-${name}`);
|
238 | }
|
239 | }
|
240 |
|
241 | return result;
|
242 | }
|
243 |
|
244 |
|
\ | No newline at end of file |