electron-updater 7.0.0-alpha.7 → 7.0.0-alpha.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/AppImageUpdater.d.ts +2 -1
  2. package/dist/AppImageUpdater.d.ts.map +1 -1
  3. package/dist/AppImageUpdater.js.map +1 -1
  4. package/dist/AppUpdater.d.ts +43 -5
  5. package/dist/AppUpdater.d.ts.map +1 -1
  6. package/dist/AppUpdater.js +164 -9
  7. package/dist/AppUpdater.js.map +1 -1
  8. package/dist/BaseUpdater.d.ts +3 -3
  9. package/dist/BaseUpdater.d.ts.map +1 -1
  10. package/dist/BaseUpdater.js +2 -2
  11. package/dist/BaseUpdater.js.map +1 -1
  12. package/dist/DebUpdater.d.ts +2 -2
  13. package/dist/DebUpdater.d.ts.map +1 -1
  14. package/dist/DebUpdater.js.map +1 -1
  15. package/dist/MacUpdater.d.ts +3 -3
  16. package/dist/MacUpdater.d.ts.map +1 -1
  17. package/dist/MacUpdater.js +5 -4
  18. package/dist/MacUpdater.js.map +1 -1
  19. package/dist/NsisUpdater.d.ts +2 -1
  20. package/dist/NsisUpdater.d.ts.map +1 -1
  21. package/dist/NsisUpdater.js.map +1 -1
  22. package/dist/PacmanUpdater.d.ts +2 -2
  23. package/dist/PacmanUpdater.d.ts.map +1 -1
  24. package/dist/PacmanUpdater.js.map +1 -1
  25. package/dist/RpmUpdater.d.ts +2 -2
  26. package/dist/RpmUpdater.d.ts.map +1 -1
  27. package/dist/RpmUpdater.js.map +1 -1
  28. package/dist/differentialDownloader/DataSplitter.d.ts +3 -2
  29. package/dist/differentialDownloader/DataSplitter.d.ts.map +1 -1
  30. package/dist/differentialDownloader/DataSplitter.js +36 -15
  31. package/dist/differentialDownloader/DataSplitter.js.map +1 -1
  32. package/dist/differentialDownloader/multipleRangeDownloader.d.ts.map +1 -1
  33. package/dist/differentialDownloader/multipleRangeDownloader.js +22 -2
  34. package/dist/differentialDownloader/multipleRangeDownloader.js.map +1 -1
  35. package/dist/types.d.ts +22 -1
  36. package/dist/types.d.ts.map +1 -1
  37. package/dist/types.js.map +1 -1
  38. package/dist/windowsExecutableCodeSignatureVerifier.d.ts.map +1 -1
  39. package/dist/windowsExecutableCodeSignatureVerifier.js +117 -78
  40. package/dist/windowsExecutableCodeSignatureVerifier.js.map +1 -1
  41. package/package.json +2 -2
@@ -1,12 +1,13 @@
1
1
  import { AllPublishOptions } from "builder-util-runtime";
2
2
  import { DownloadUpdateOptions } from "./AppUpdater.js";
3
3
  import { BaseUpdater, InstallOptions } from "./BaseUpdater.js";
4
+ import { DownloadExecutorResult } from "./types.js";
4
5
  export declare class AppImageUpdater extends BaseUpdater {
5
6
  constructor(options?: AllPublishOptions | null, app?: any);
6
7
  isUpdaterActive(): boolean;
7
8
  protected get isAutoInstallOnNextLaunchSupported(): boolean;
8
9
  /*** @private */
9
- protected doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<Array<string>>;
10
+ protected doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<DownloadExecutorResult>;
10
11
  private downloadDifferential;
11
12
  protected doInstall(options: InstallOptions): boolean;
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"AppImageUpdater.d.ts","sourceRoot":"","sources":["../src/AppImageUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAY,MAAM,sBAAsB,CAAA;AAKlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAM9D,qBAAa,eAAgB,SAAQ,WAAW;gBAClC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG;IAIlD,eAAe,IAAI,OAAO;IAajC,SAAS,KAAK,kCAAkC,IAAI,OAAO,CAE1D;IAED,gBAAgB;IAChB,SAAS,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAsBlF,oBAAoB;IAyBlC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO;CA+CtD"}
1
+ {"version":3,"file":"AppImageUpdater.d.ts","sourceRoot":"","sources":["../src/AppImageUpdater.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAY,MAAM,sBAAsB,CAAA;AAKlE,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAI9D,OAAO,EAA6C,sBAAsB,EAAE,MAAM,YAAY,CAAA;AAE9F,qBAAa,eAAgB,SAAQ,WAAW;gBAClC,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG;IAIlD,eAAe,IAAI,OAAO;IAajC,SAAS,KAAK,kCAAkC,IAAI,OAAO,CAE1D;IAED,gBAAgB;IAChB,SAAS,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;YAsB3F,oBAAoB;IAyBlC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO;CA+CtD"}
@@ -1 +1 @@
1
- {"version":3,"file":"AppImageUpdater.js","sourceRoot":"","sources":["../src/AppImageUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllPublishOptions, newError } from \"builder-util-runtime\"\nimport { execFileSync } from \"child_process\"\nimport fsExtra from \"fs-extra\"\nimport { unlinkSync } from \"fs\"\nimport * as path from \"path\"\nimport { DownloadUpdateOptions } from \"./AppUpdater.js\"\nimport { BaseUpdater, InstallOptions } from \"./BaseUpdater.js\"\nimport { DifferentialDownloaderOptions } from \"./differentialDownloader/DifferentialDownloader.js\"\nimport { FileWithEmbeddedBlockMapDifferentialDownloader } from \"./differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js\"\nimport { findFile, Provider } from \"./providers/Provider.js\"\nimport { DOWNLOAD_PROGRESS, ResolvedUpdateFileInfo } from \"./types.js\"\n\nexport class AppImageUpdater extends BaseUpdater {\n constructor(options?: AllPublishOptions | null, app?: any) {\n super(options, app)\n }\n\n public isUpdaterActive(): boolean {\n if (process.env[\"APPIMAGE\"] == null && !this.forceDevUpdateConfig) {\n if (process.env[\"SNAP\"] == null) {\n this._logger.warn(\"APPIMAGE env is not defined, current application is not an AppImage\")\n } else {\n this._logger.info(\"SNAP env is defined, updater is disabled\")\n }\n return false\n }\n return super.isUpdaterActive()\n }\n\n // replacing the AppImage file needs no elevation, so the automatic install at startup is allowed\n protected get isAutoInstallOnNextLaunchSupported(): boolean {\n return true\n }\n\n /*** @private */\n protected doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<Array<string>> {\n const provider = downloadUpdateOptions.updateInfoAndProvider.provider\n const fileInfo = findFile(provider.resolveFiles(downloadUpdateOptions.updateInfoAndProvider.info), \"AppImage\", [\"rpm\", \"deb\", \"pacman\"])!\n return this.executeDownload({\n fileExtension: \"AppImage\",\n fileInfo,\n downloadUpdateOptions,\n task: async (updateFile, downloadOptions) => {\n const oldFile = process.env[\"APPIMAGE\"]!\n if (oldFile == null) {\n throw newError(\"APPIMAGE env is not defined\", \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n\n if (downloadUpdateOptions.disableDifferentialDownload || (await this.downloadDifferential(fileInfo, oldFile, updateFile, provider, downloadUpdateOptions))) {\n await this.httpExecutor.download(fileInfo.url, updateFile, downloadOptions)\n }\n\n await fsExtra.chmod(updateFile, 0o755)\n },\n })\n }\n\n private async downloadDifferential(fileInfo: ResolvedUpdateFileInfo, oldFile: string, updateFile: string, provider: Provider<any>, downloadUpdateOptions: DownloadUpdateOptions) {\n try {\n const downloadOptions: DifferentialDownloaderOptions = {\n newUrl: fileInfo.url,\n oldFile,\n logger: this._logger,\n newFile: updateFile,\n isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest,\n requestHeaders: downloadUpdateOptions.requestHeaders,\n cancellationToken: downloadUpdateOptions.cancellationToken,\n }\n\n if (this.listenerCount(DOWNLOAD_PROGRESS) > 0) {\n downloadOptions.onProgress = it => this.emit(DOWNLOAD_PROGRESS, it)\n }\n\n await new FileWithEmbeddedBlockMapDifferentialDownloader(fileInfo.info, this.httpExecutor, downloadOptions).download()\n return false\n } catch (e: any) {\n this._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`)\n // during test (developer machine mac) we must throw error\n return process.platform === \"linux\"\n }\n }\n\n protected doInstall(options: InstallOptions): boolean {\n const appImageFile = process.env[\"APPIMAGE\"]!\n if (appImageFile == null) {\n throw newError(\"APPIMAGE env is not defined\", \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n if (!path.isAbsolute(appImageFile) || appImageFile.includes(\"\\0\")) {\n throw newError(`APPIMAGE env is not a valid absolute path: \"${appImageFile}\"`, \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n\n // https://stackoverflow.com/a/1712051/1910191\n unlinkSync(appImageFile)\n\n let destination: string\n const existingBaseName = path.basename(appImageFile)\n const installerPath = this.installerPath\n if (installerPath == null) {\n this.dispatchError(new Error(\"No update filepath provided, can't quit and install\"))\n return false\n }\n // https://github.com/electron-userland/electron-builder/issues/2964\n // if no version in existing file name, it means that user wants to preserve current custom name\n if (path.basename(installerPath) === existingBaseName || !/\\d+\\.\\d+\\.\\d+/.test(existingBaseName)) {\n // no version in the file name, overwrite existing\n destination = appImageFile\n } else {\n destination = path.join(path.dirname(appImageFile), path.basename(installerPath))\n }\n\n execFileSync(\"mv\", [\"-f\", installerPath, destination])\n if (destination !== appImageFile) {\n this.emit(\"appimage-filename-updated\", destination)\n }\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n APPIMAGE_SILENT_INSTALL: \"true\",\n }\n\n if (options.isForceRunAfter) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.spawnLog(destination, [], env)\n } else {\n env.APPIMAGE_EXIT_AFTER_INSTALL = \"true\"\n execFileSync(destination, [], { env })\n }\n return true\n }\n}\n"]}
1
+ {"version":3,"file":"AppImageUpdater.js","sourceRoot":"","sources":["../src/AppImageUpdater.ts"],"names":[],"mappings":"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","sourcesContent":["import { AllPublishOptions, newError } from \"builder-util-runtime\"\nimport { execFileSync } from \"child_process\"\nimport fsExtra from \"fs-extra\"\nimport { unlinkSync } from \"fs\"\nimport * as path from \"path\"\nimport { DownloadUpdateOptions } from \"./AppUpdater.js\"\nimport { BaseUpdater, InstallOptions } from \"./BaseUpdater.js\"\nimport { DifferentialDownloaderOptions } from \"./differentialDownloader/DifferentialDownloader.js\"\nimport { FileWithEmbeddedBlockMapDifferentialDownloader } from \"./differentialDownloader/FileWithEmbeddedBlockMapDifferentialDownloader.js\"\nimport { findFile, Provider } from \"./providers/Provider.js\"\nimport { DOWNLOAD_PROGRESS, ResolvedUpdateFileInfo, DownloadExecutorResult } from \"./types.js\"\n\nexport class AppImageUpdater extends BaseUpdater {\n constructor(options?: AllPublishOptions | null, app?: any) {\n super(options, app)\n }\n\n public isUpdaterActive(): boolean {\n if (process.env[\"APPIMAGE\"] == null && !this.forceDevUpdateConfig) {\n if (process.env[\"SNAP\"] == null) {\n this._logger.warn(\"APPIMAGE env is not defined, current application is not an AppImage\")\n } else {\n this._logger.info(\"SNAP env is defined, updater is disabled\")\n }\n return false\n }\n return super.isUpdaterActive()\n }\n\n // replacing the AppImage file needs no elevation, so the automatic install at startup is allowed\n protected get isAutoInstallOnNextLaunchSupported(): boolean {\n return true\n }\n\n /*** @private */\n protected doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<DownloadExecutorResult> {\n const provider = downloadUpdateOptions.updateInfoAndProvider.provider\n const fileInfo = findFile(provider.resolveFiles(downloadUpdateOptions.updateInfoAndProvider.info), \"AppImage\", [\"rpm\", \"deb\", \"pacman\"])!\n return this.executeDownload({\n fileExtension: \"AppImage\",\n fileInfo,\n downloadUpdateOptions,\n task: async (updateFile, downloadOptions) => {\n const oldFile = process.env[\"APPIMAGE\"]!\n if (oldFile == null) {\n throw newError(\"APPIMAGE env is not defined\", \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n\n if (downloadUpdateOptions.disableDifferentialDownload || (await this.downloadDifferential(fileInfo, oldFile, updateFile, provider, downloadUpdateOptions))) {\n await this.httpExecutor.download(fileInfo.url, updateFile, downloadOptions)\n }\n\n await fsExtra.chmod(updateFile, 0o755)\n },\n })\n }\n\n private async downloadDifferential(fileInfo: ResolvedUpdateFileInfo, oldFile: string, updateFile: string, provider: Provider<any>, downloadUpdateOptions: DownloadUpdateOptions) {\n try {\n const downloadOptions: DifferentialDownloaderOptions = {\n newUrl: fileInfo.url,\n oldFile,\n logger: this._logger,\n newFile: updateFile,\n isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest,\n requestHeaders: downloadUpdateOptions.requestHeaders,\n cancellationToken: downloadUpdateOptions.cancellationToken,\n }\n\n if (this.listenerCount(DOWNLOAD_PROGRESS) > 0) {\n downloadOptions.onProgress = it => this.emit(DOWNLOAD_PROGRESS, it)\n }\n\n await new FileWithEmbeddedBlockMapDifferentialDownloader(fileInfo.info, this.httpExecutor, downloadOptions).download()\n return false\n } catch (e: any) {\n this._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`)\n // during test (developer machine mac) we must throw error\n return process.platform === \"linux\"\n }\n }\n\n protected doInstall(options: InstallOptions): boolean {\n const appImageFile = process.env[\"APPIMAGE\"]!\n if (appImageFile == null) {\n throw newError(\"APPIMAGE env is not defined\", \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n if (!path.isAbsolute(appImageFile) || appImageFile.includes(\"\\0\")) {\n throw newError(`APPIMAGE env is not a valid absolute path: \"${appImageFile}\"`, \"ERR_UPDATER_OLD_FILE_NOT_FOUND\")\n }\n\n // https://stackoverflow.com/a/1712051/1910191\n unlinkSync(appImageFile)\n\n let destination: string\n const existingBaseName = path.basename(appImageFile)\n const installerPath = this.installerPath\n if (installerPath == null) {\n this.dispatchError(new Error(\"No update filepath provided, can't quit and install\"))\n return false\n }\n // https://github.com/electron-userland/electron-builder/issues/2964\n // if no version in existing file name, it means that user wants to preserve current custom name\n if (path.basename(installerPath) === existingBaseName || !/\\d+\\.\\d+\\.\\d+/.test(existingBaseName)) {\n // no version in the file name, overwrite existing\n destination = appImageFile\n } else {\n destination = path.join(path.dirname(appImageFile), path.basename(installerPath))\n }\n\n execFileSync(\"mv\", [\"-f\", installerPath, destination])\n if (destination !== appImageFile) {\n this.emit(\"appimage-filename-updated\", destination)\n }\n\n const env: NodeJS.ProcessEnv = {\n ...process.env,\n APPIMAGE_SILENT_INSTALL: \"true\",\n }\n\n if (options.isForceRunAfter) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n this.spawnLog(destination, [], env)\n } else {\n env.APPIMAGE_EXIT_AFTER_INSTALL = \"true\"\n execFileSync(destination, [], { env })\n }\n return true\n }\n}\n"]}
@@ -9,7 +9,7 @@ import { Provider, ProviderPlatform } from "./providers/Provider.js";
9
9
  import type { TypedEmitter } from "tiny-typed-emitter";
10
10
  type Session = Electron.Session;
11
11
  import type { AuthInfo } from "electron";
12
- import { AutoInstallEvent, Logger, QuitAndInstallOptions, ResolvedUpdateFileInfo, UpdateCheckResult, UpdateDownloadedEvent, UpdaterSignal } from "./types.js";
12
+ import { AutoInstallEvent, Logger, QuitAndInstallOptions, ResolvedUpdateFileInfo, UpdateCheckResult, DownloadExecutorResult, UpdateDownloadedEvent, UpdaterSignal } from "./types.js";
13
13
  import { VerifyUpdateSupport } from "./index.js";
14
14
  export type AppUpdaterEvents = {
15
15
  error: (error: Error, message?: string) => void;
@@ -49,6 +49,17 @@ export declare abstract class AppUpdater extends AppUpdater_base {
49
49
  * @default "onQuit"
50
50
  */
51
51
  autoInstallEvent: AutoInstallEvent;
52
+ /**
53
+ * @deprecated Removed in v27 — use {@link autoInstallEvent}. This accessor is a compatibility shim
54
+ * and will be deleted in v28.
55
+ *
56
+ * A boolean cannot express the three install timings, so `autoInstallOnAppQuit` was replaced rather
57
+ * than extended. Without this shim the property assignment silently no-ops on a plain object: an app
58
+ * that set `autoInstallOnAppQuit = false` to opt *out* of install-on-quit would keep the `"onQuit"`
59
+ * default and install on quit anyway — the exact opposite of what it asked for.
60
+ */
61
+ get autoInstallOnAppQuit(): boolean;
62
+ set autoInstallOnAppQuit(value: boolean);
52
63
  /**
53
64
  * Installs an update that a previous launch marked as pending (see `autoInstallEvent: "onNextLaunch"` and
54
65
  * `quitAndInstall({ waitUntilNextLaunch: true })`), then quits the app.
@@ -166,6 +177,18 @@ export declare abstract class AppUpdater extends AppUpdater_base {
166
177
  * `allowDowngrade` will be automatically set to `true`. If this behavior is not suitable for you, simple set `allowDowngrade` explicitly after.
167
178
  */
168
179
  set channel(value: string | null);
180
+ /**
181
+ * The Ed25519 public key(s) (PEM or base64 SPKI) trusted to have signed the update manifest — the
182
+ * install's trust list. A single string or an array of keys; a manifest is accepted when any listed key
183
+ * validates one of its signatures. When set (non-empty), overrides the `updateManifestPublicKey` value
184
+ * embedded in `app-update.yml`.
185
+ *
186
+ * When at least one key is available (here or in config) the manifest signature is enforced and a
187
+ * download will not start unless verification succeeds. When no key is available, verification is
188
+ * skipped (opt-in) and a one-time warning is logged.
189
+ */
190
+ updateManifestPublicKey: string | Array<string> | null;
191
+ private manifestVerificationWarned;
169
192
  /**
170
193
  * The request headers.
171
194
  */
@@ -233,17 +256,32 @@ export declare abstract class AppUpdater extends AppUpdater_base {
233
256
  private isUpdateAvailable;
234
257
  private checkIfUpdateSupported;
235
258
  protected getUpdateInfoAndProvider(): Promise<UpdateInfoAndProvider>;
259
+ /**
260
+ * Verifies the Ed25519 signature(s) embedded in the update manifest against the configured trust list.
261
+ * Provider-agnostic: runs for every provider since it operates on the resolved `UpdateInfo`.
262
+ *
263
+ * - No public key configured → verification skipped (opt-in phase), warns once.
264
+ * - Key(s) configured, manifest carries no signature at all → throws ERR_UPDATER_MANIFEST_NOT_SIGNED.
265
+ * - Key(s) configured, no trusted key validates any signature → throws ERR_UPDATER_MANIFEST_SIGNATURE_INVALID.
266
+ *
267
+ * A manifest may carry several signatures (`signatures`, one per signing key, tagged with the key id) plus
268
+ * the legacy single `signature`; any trusted key matching any of them is sufficient, which is what allows
269
+ * a release to be dual-signed while installs trust `[old, new]` during key rotation. Never fails open once
270
+ * a key is configured. A throw here propagates before any download starts (fail-closed).
271
+ */
272
+ private verifyManifestSignature;
236
273
  private createProviderRuntimeOptions;
237
274
  private doCheckForUpdates;
238
275
  protected onUpdateAvailable(updateInfo: UpdateInfo): void;
239
276
  /**
240
277
  * Start downloading update manually. You can use this method if `autoDownload` option is set to `false`.
241
- * @returns {Promise<Array<string>>} Paths to downloaded files.
278
+ * @returns {Promise<DownloadExecutorResult>} The downloaded files: `updateFile` is the path to the downloaded update (installer, AppImage, zip, ...),
279
+ * `packageFile` is the path to the NSIS web installer package and is only set for web installers.
242
280
  */
243
- downloadUpdate(cancellationToken?: CancellationToken): Promise<Array<string>>;
281
+ downloadUpdate(cancellationToken?: CancellationToken): Promise<DownloadExecutorResult>;
244
282
  protected dispatchError(e: Error): void;
245
283
  protected dispatchUpdateDownloaded(event: UpdateDownloadedEvent): void;
246
- protected abstract doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<Array<string>>;
284
+ protected abstract doDownloadUpdate(downloadUpdateOptions: DownloadUpdateOptions): Promise<DownloadExecutorResult>;
247
285
  /**
248
286
  * Restarts the app and installs the update after it has been downloaded.
249
287
  * It should only be called after `update-downloaded` has been emitted.
@@ -259,7 +297,7 @@ export declare abstract class AppUpdater extends AppUpdater_base {
259
297
  private computeRequestHeaders;
260
298
  private getOrCreateStagingUserId;
261
299
  protected getOrCreateDownloadHelper(): Promise<DownloadedUpdateHelper>;
262
- protected executeDownload(taskOptions: DownloadExecutorTask): Promise<Array<string>>;
300
+ protected executeDownload(taskOptions: DownloadExecutorTask): Promise<DownloadExecutorResult>;
263
301
  protected differentialDownloadInstaller(fileInfo: ResolvedUpdateFileInfo, downloadUpdateOptions: DownloadUpdateOptions, installerPath: string, provider: Provider<any>, oldInstallerFileName: string): Promise<boolean>;
264
302
  }
265
303
  export interface DownloadUpdateOptions {
@@ -1 +1 @@
1
- {"version":3,"file":"AppUpdater.d.ts","sourceRoot":"","sources":["../src/AppUpdater.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AppUpdater.d.ts","sourceRoot":"","sources":["../src/AppUpdater.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { createRequire } from "node:module";
2
- import { asArray, CancellationToken, newError, UUID, CancellationError, retry, } from "builder-util-runtime";
2
+ import { asArray, CancellationToken, newError, UUID, CancellationError, retry, collectManifestSignatures, normalizePublicKeyList, verifyManifestSignatures, } from "builder-util-runtime";
3
3
  import { randomBytes } from "crypto";
4
4
  import { release } from "os";
5
5
  import { EventEmitter } from "events";
@@ -18,6 +18,26 @@ import { GenericDifferentialDownloader } from "./differentialDownloader/GenericD
18
18
  import { DOWNLOAD_PROGRESS, UPDATE_DOWNLOADED, UpdaterSignal, } from "./types.js";
19
19
  const require = createRequire(import.meta.url);
20
20
  export class AppUpdater extends EventEmitter {
21
+ /**
22
+ * @deprecated Removed in v27 — use {@link autoInstallEvent}. This accessor is a compatibility shim
23
+ * and will be deleted in v28.
24
+ *
25
+ * A boolean cannot express the three install timings, so `autoInstallOnAppQuit` was replaced rather
26
+ * than extended. Without this shim the property assignment silently no-ops on a plain object: an app
27
+ * that set `autoInstallOnAppQuit = false` to opt *out* of install-on-quit would keep the `"onQuit"`
28
+ * default and install on quit anyway — the exact opposite of what it asked for.
29
+ */
30
+ get autoInstallOnAppQuit() {
31
+ return this.autoInstallEvent === "onQuit";
32
+ }
33
+ set autoInstallOnAppQuit(value) {
34
+ const mapped = value ? "onQuit" : "manual";
35
+ this._logger.warn(`autoInstallOnAppQuit was removed in electron-updater 7 (electron-builder v27) — use autoInstallEvent instead. ` +
36
+ `Mapping autoInstallOnAppQuit = ${value} to autoInstallEvent = "${mapped}". ` +
37
+ `This compatibility shim is removed in v28. ` +
38
+ `https://www.electron.build/docs/migration/v27-breaking-changes#autoinstallevent-replaces-autoinstallonappquit`);
39
+ this.autoInstallEvent = mapped;
40
+ }
21
41
  /**
22
42
  * Installs an update that a previous launch marked as pending (see `autoInstallEvent: "onNextLaunch"` and
23
43
  * `quitAndInstall({ waitUntilNextLaunch: true })`), then quits the app.
@@ -236,6 +256,18 @@ export class AppUpdater extends EventEmitter {
236
256
  this.previousBlockmapBaseUrlOverride = null;
237
257
  this._channel = null;
238
258
  this.downloadedUpdateHelper = null;
259
+ /**
260
+ * The Ed25519 public key(s) (PEM or base64 SPKI) trusted to have signed the update manifest — the
261
+ * install's trust list. A single string or an array of keys; a manifest is accepted when any listed key
262
+ * validates one of its signatures. When set (non-empty), overrides the `updateManifestPublicKey` value
263
+ * embedded in `app-update.yml`.
264
+ *
265
+ * When at least one key is available (here or in config) the manifest signature is enforced and a
266
+ * download will not start unless verification succeeds. When no key is available, verification is
267
+ * skipped (opt-in) and a one-time warning is logged.
268
+ */
269
+ this.updateManifestPublicKey = null;
270
+ this.manifestVerificationWarned = false;
239
271
  /**
240
272
  * The request headers.
241
273
  */
@@ -381,8 +413,8 @@ export class AppUpdater extends EventEmitter {
381
413
  if (stagingPercentage == null) {
382
414
  return true;
383
415
  }
384
- stagingPercentage = parseInt(stagingPercentage, 10);
385
- if (isNaN(stagingPercentage)) {
416
+ stagingPercentage = Number(stagingPercentage);
417
+ if (!Number.isFinite(stagingPercentage)) {
386
418
  this._logger.warn(`Staging percentage is NaN: ${rawStagingPercentage}`);
387
419
  return true;
388
420
  }
@@ -449,11 +481,60 @@ export class AppUpdater extends EventEmitter {
449
481
  const client = await this.clientPromise;
450
482
  const stagingUserId = await this.stagingUserIdPromise.value;
451
483
  client.setRequestHeaders(this.computeFinalHeaders({ "x-user-staging-id": stagingUserId }));
484
+ const info = await client.getLatestVersion();
485
+ await this.verifyManifestSignature(info);
452
486
  return {
453
- info: await client.getLatestVersion(),
487
+ info,
454
488
  provider: client,
455
489
  };
456
490
  }
491
+ /**
492
+ * Verifies the Ed25519 signature(s) embedded in the update manifest against the configured trust list.
493
+ * Provider-agnostic: runs for every provider since it operates on the resolved `UpdateInfo`.
494
+ *
495
+ * - No public key configured → verification skipped (opt-in phase), warns once.
496
+ * - Key(s) configured, manifest carries no signature at all → throws ERR_UPDATER_MANIFEST_NOT_SIGNED.
497
+ * - Key(s) configured, no trusted key validates any signature → throws ERR_UPDATER_MANIFEST_SIGNATURE_INVALID.
498
+ *
499
+ * A manifest may carry several signatures (`signatures`, one per signing key, tagged with the key id) plus
500
+ * the legacy single `signature`; any trusted key matching any of them is sufficient, which is what allows
501
+ * a release to be dual-signed while installs trust `[old, new]` during key rotation. Never fails open once
502
+ * a key is configured. A throw here propagates before any download starts (fail-closed).
503
+ */
504
+ async verifyManifestSignature(info) {
505
+ let trustedKeys = normalizePublicKeyList(this.updateManifestPublicKey);
506
+ if (trustedKeys.length === 0) {
507
+ try {
508
+ trustedKeys = normalizePublicKeyList((await this.configOnDisk.value)?.updateManifestPublicKey);
509
+ }
510
+ catch (e) {
511
+ // app-update.yml is read elsewhere too; a missing/unreadable config here just means "no key"
512
+ if (e.code !== "ENOENT") {
513
+ this._logger.warn(`Cannot read updateManifestPublicKey from update config: ${e.message || e}`);
514
+ }
515
+ trustedKeys = [];
516
+ }
517
+ }
518
+ if (trustedKeys.length === 0) {
519
+ if (!this.manifestVerificationWarned) {
520
+ this.manifestVerificationWarned = true;
521
+ this._logger.warn("update manifest signature verification is disabled. Configure updateManifestPublicKey (and sign manifests at build time) to enable it.");
522
+ }
523
+ return;
524
+ }
525
+ if (collectManifestSignatures(info).length === 0) {
526
+ throw newError(`Update manifest for version ${info.version} is not signed, but updateManifestPublicKey is configured. Refusing to update.`, "ERR_UPDATER_MANIFEST_NOT_SIGNED");
527
+ }
528
+ const result = verifyManifestSignatures(info, trustedKeys);
529
+ if (!result.ok) {
530
+ // `reason` is set when the manifest fails the structural checks a signed manifest must pass (e.g. an empty
531
+ // `files` list or control characters in a signed field) — those are rejected before any key is tried.
532
+ const cause = result.reason == null ? `none of the ${trustedKeys.length} trusted key(s) validates any of its signatures` : `the signed manifest is malformed (${result.reason})`;
533
+ throw newError(`Update manifest signature verification failed for version ${info.version}: ${cause}. The update metadata may have been tampered with. Refusing to update.`, "ERR_UPDATER_MANIFEST_SIGNATURE_INVALID");
534
+ }
535
+ this._logger.debug?.(`Update manifest for version ${info.version} verified with trusted key ${result.keyId}`);
536
+ this._logger.info(`Update manifest signature verified for version ${info.version}`);
537
+ }
457
538
  createProviderRuntimeOptions() {
458
539
  return {
459
540
  isUseMultipleRangeRequest: true,
@@ -494,7 +575,8 @@ export class AppUpdater extends EventEmitter {
494
575
  }
495
576
  /**
496
577
  * Start downloading update manually. You can use this method if `autoDownload` option is set to `false`.
497
- * @returns {Promise<Array<string>>} Paths to downloaded files.
578
+ * @returns {Promise<DownloadExecutorResult>} The downloaded files: `updateFile` is the path to the downloaded update (installer, AppImage, zip, ...),
579
+ * `packageFile` is the path to the NSIS web installer package and is only set for web installers.
498
580
  */
499
581
  downloadUpdate(cancellationToken = new CancellationToken()) {
500
582
  const updateInfoAndProvider = this.updateInfoAndProvider;
@@ -543,6 +625,27 @@ export class AppUpdater extends EventEmitter {
543
625
  dispatchUpdateDownloaded(event) {
544
626
  this.emit(UPDATE_DOWNLOADED, event);
545
627
  }
628
+ /**
629
+ * Accepts the v26 positional call shape, `quitAndInstall(isSilent, isForceRunAfter)`.
630
+ *
631
+ * TypeScript callers get a compile error, but plain JavaScript does not: the boolean lands in the
632
+ * destructured options parameter, every field reads back `undefined`, and the defaults silently take
633
+ * over — so `quitAndInstall(true)` performs a NON-silent install. Warn and map instead of ignoring.
634
+ *
635
+ * @internal
636
+ */
637
+ normalizeQuitAndInstallOptions(options, legacyIsForceRunAfter) {
638
+ if (typeof options !== "boolean" && typeof legacyIsForceRunAfter !== "boolean") {
639
+ return options ?? {};
640
+ }
641
+ const isSilent = typeof options === "boolean" ? options : false;
642
+ const isForceRunAfter = legacyIsForceRunAfter === true;
643
+ this._logger.warn(`quitAndInstall(isSilent, isForceRunAfter) was replaced by quitAndInstall({ isSilent, isForceRunAfter }) in electron-updater 7 (electron-builder v27). ` +
644
+ `Interpreting the positional arguments as { isSilent: ${isSilent}, isForceRunAfter: ${isForceRunAfter} }. ` +
645
+ `This compatibility shim is removed in v28. ` +
646
+ `https://www.electron.build/docs/migration/v27-breaking-changes#quitandinstall-takes-an-options-object`);
647
+ return { isSilent, isForceRunAfter };
648
+ }
546
649
  async loadUpdateConfig() {
547
650
  if (this._appUpdateConfigPath == null) {
548
651
  this._appUpdateConfigPath = this.app.appUpdateConfigPath;
@@ -655,17 +758,26 @@ export class AppUpdater extends EventEmitter {
655
758
  const updateFileName = getCacheUpdateFileName();
656
759
  let updateFile = path.join(cacheDir, updateFileName);
657
760
  const packageFile = packageInfo == null ? null : path.join(cacheDir, `package-${version}${path.extname(packageInfo.path) || ".7z"}`);
761
+ const pendingBlockMapFile = path.join(cacheDir, "current.blockmap");
762
+ const cachedBlockMapFile = path.join(downloadedUpdateHelper.cacheDir, "current.blockmap");
658
763
  const done = async (isSaveCache) => {
659
764
  await downloadedUpdateHelper.setDownloadedFile(updateFile, packageFile, updateInfo, fileInfo, updateFileName, isSaveCache);
660
765
  await taskOptions.done({
661
766
  ...updateInfo,
662
767
  downloadedFile: updateFile,
768
+ ...(packageFile == null ? {} : { packageFile }),
663
769
  });
664
- const currentBlockMapFile = path.join(cacheDir, "current.blockmap");
665
- if (await fsExtra.pathExists(currentBlockMapFile)) {
666
- await fsExtra.copyFile(currentBlockMapFile, path.join(downloadedUpdateHelper.cacheDir, "current.blockmap"));
770
+ if (await fsExtra.pathExists(pendingBlockMapFile)) {
771
+ await fsExtra.copyFile(pendingBlockMapFile, cachedBlockMapFile);
772
+ }
773
+ else if (!taskOptions.downloadUpdateOptions.disableDifferentialDownload) {
774
+ // this download did not produce a blockmap, but `taskOptions.done` above refreshes the cached installer —
775
+ // remove the cached blockmap too, so a stale one cannot sit next to a fresh file and poison the next
776
+ // differential download with a wrong copy plan (https://github.com/electron-userland/electron-builder/issues/10097).
777
+ // The differential downloader re-fetches the old blockmap from the server when no cached one exists.
778
+ await fsExtra.remove(cachedBlockMapFile);
667
779
  }
668
- return packageFile == null ? [updateFile] : [updateFile, packageFile];
780
+ return withLegacyArrayCompat(packageFile == null ? { updateFile } : { updateFile, packageFile }, this._logger);
669
781
  };
670
782
  const log = this._logger;
671
783
  const cachedUpdateFile = await downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
@@ -681,6 +793,10 @@ export class AppUpdater extends EventEmitter {
681
793
  // ignore
682
794
  });
683
795
  };
796
+ // a fresh download starts — drop any blockmap left over from a previous update round, so that when this round
797
+ // does not produce a new one (e.g. the differential download is skipped), the leftover cannot be promoted to the
798
+ // cache next to a file it does not describe
799
+ await fsExtra.remove(pendingBlockMapFile);
684
800
  const tempUpdateFile = await createTempUpdateFile(`temp-${updateFileName}`, cacheDir, log);
685
801
  try {
686
802
  await taskOptions.task(tempUpdateFile, downloadOptions, packageFile, removeFileIfAny);
@@ -702,12 +818,18 @@ export class AppUpdater extends EventEmitter {
702
818
  log.info("cancelled");
703
819
  this.emit("update-cancelled", updateInfo);
704
820
  }
821
+ else if (e.code === "ERR_CHECKSUM_MISMATCH") {
822
+ // a differential-download failure never escapes the task (it falls back to a full download),
823
+ // so a checksum mismatch here means the fully downloaded file itself failed verification
824
+ log.warn(`sha512 checksum mismatch after full download of ${updateFileName}: the downloaded file is corrupted or the published update metadata does not match the uploaded file`);
825
+ }
705
826
  throw e;
706
827
  }
707
828
  log.info(`New version ${version} has been downloaded to ${updateFile}`);
708
829
  return await done(true);
709
830
  }
710
831
  async differentialDownloadInstaller(fileInfo, downloadUpdateOptions, installerPath, provider, oldInstallerFileName) {
832
+ let isOldBlockMapFromCache = false;
711
833
  try {
712
834
  if (this._testOnlyOptions != null && !this._testOnlyOptions.isUseDifferentialDownload) {
713
835
  return true;
@@ -762,13 +884,18 @@ export class AppUpdater extends EventEmitter {
762
884
  await saveBlockMapToCacheDir(newBlockMapData, this.downloadedUpdateHelper.cacheDirForPendingUpdate);
763
885
  // get old blockmap from cache dir first, if not found, download it
764
886
  let oldBlockMapData = await getBlockMapFromCacheDir(this.downloadedUpdateHelper.cacheDir);
887
+ isOldBlockMapFromCache = oldBlockMapData != null;
765
888
  if (oldBlockMapData == null) {
889
+ this._logger.info(`No cached blockmap for the old installer, downloading it from "${blockmapFileUrls[0]}"`);
766
890
  oldBlockMapData = await downloadBlockMap(blockmapFileUrls[0]);
767
891
  }
768
892
  await new GenericDifferentialDownloader(fileInfo.info, this.httpExecutor, downloadOptions).download(oldBlockMapData, newBlockMapData);
769
893
  return false;
770
894
  }
771
895
  catch (e) {
896
+ if (e.code === "ERR_CHECKSUM_MISMATCH") {
897
+ this._logger.warn(`sha512 checksum mismatch after differential download (old blockmap ${isOldBlockMapFromCache ? "was read from the local cache" : "was downloaded from the server"}): cached "${oldInstallerFileName}" is likely out of sync with the old blockmap, e.g. because one of them was replaced or evicted independently of the other`);
898
+ }
772
899
  this._logger.error(`Cannot download differentially, fallback to full download: ${e.stack || e}`);
773
900
  if (this._testOnlyOptions != null) {
774
901
  // test mode
@@ -797,4 +924,32 @@ export class NoOpLogger {
797
924
  // ignore
798
925
  }
799
926
  }
927
+ /**
928
+ * Adds a warning `Symbol.iterator` to a {@link DownloadExecutorResult}, for callers still written
929
+ * against v26's `Array<string>` return.
930
+ *
931
+ * `const [installer] = await downloadUpdate()` otherwise throws a bare
932
+ * `TypeError: ... is not iterable`, which names neither `downloadUpdate` nor the replacement, and
933
+ * `files[0]` silently evaluates to `undefined`. Yielding the same positional order the array had
934
+ * ([updateFile, packageFile]) keeps those call sites working for one major while they migrate.
935
+ *
936
+ * Non-enumerable so the object still serializes and compares as a plain `{ updateFile, packageFile }`.
937
+ */
938
+ function withLegacyArrayCompat(result, logger) {
939
+ return Object.defineProperty(result, Symbol.iterator, {
940
+ enumerable: false,
941
+ configurable: true,
942
+ writable: true,
943
+ value: function* () {
944
+ logger.warn("downloadUpdate() resolves with a DownloadExecutorResult object in electron-updater 7 (electron-builder v27), not an array. " +
945
+ "Replace `const [updateFile] = await downloadUpdate()` with `const { updateFile } = await downloadUpdate()`. " +
946
+ "This compatibility shim is removed in v28. " +
947
+ "https://www.electron.build/docs/migration/v27-breaking-changes#downloadupdate-resolves-with-a-downloadexecutorresult-object");
948
+ yield result.updateFile;
949
+ if (result.packageFile != null) {
950
+ yield result.packageFile;
951
+ }
952
+ },
953
+ });
954
+ }
800
955
  //# sourceMappingURL=AppUpdater.js.map