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

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 (66) hide show
  1. package/dist/AppImageUpdater.d.ts.map +1 -1
  2. package/dist/AppImageUpdater.js +4 -2
  3. package/dist/AppImageUpdater.js.map +1 -1
  4. package/dist/AppUpdater.d.ts +45 -4
  5. package/dist/AppUpdater.d.ts.map +1 -1
  6. package/dist/AppUpdater.js +199 -36
  7. package/dist/AppUpdater.js.map +1 -1
  8. package/dist/BaseUpdater.d.ts +6 -2
  9. package/dist/BaseUpdater.d.ts.map +1 -1
  10. package/dist/BaseUpdater.js +31 -8
  11. package/dist/BaseUpdater.js.map +1 -1
  12. package/dist/DownloadedUpdateHelper.d.ts +22 -1
  13. package/dist/DownloadedUpdateHelper.d.ts.map +1 -1
  14. package/dist/DownloadedUpdateHelper.js +51 -1
  15. package/dist/DownloadedUpdateHelper.js.map +1 -1
  16. package/dist/NsisUpdater.d.ts +23 -5
  17. package/dist/NsisUpdater.d.ts.map +1 -1
  18. package/dist/NsisUpdater.js +122 -38
  19. package/dist/NsisUpdater.js.map +1 -1
  20. package/dist/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.d.ts +1 -0
  21. package/dist/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.d.ts.map +1 -1
  22. package/dist/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js +7 -3
  23. package/dist/differentialDownloader/ProgressDifferentialDownloadCallbackTransform.js.map +1 -1
  24. package/dist/index.d.ts +1 -6
  25. package/dist/index.d.ts.map +1 -1
  26. package/dist/index.js.map +1 -1
  27. package/dist/providers/BitbucketProvider.d.ts +1 -0
  28. package/dist/providers/BitbucketProvider.d.ts.map +1 -1
  29. package/dist/providers/BitbucketProvider.js +3 -0
  30. package/dist/providers/BitbucketProvider.js.map +1 -1
  31. package/dist/providers/GenericProvider.d.ts +1 -0
  32. package/dist/providers/GenericProvider.d.ts.map +1 -1
  33. package/dist/providers/GenericProvider.js +3 -0
  34. package/dist/providers/GenericProvider.js.map +1 -1
  35. package/dist/providers/GitHubProvider.d.ts +1 -0
  36. package/dist/providers/GitHubProvider.d.ts.map +1 -1
  37. package/dist/providers/GitHubProvider.js +3 -0
  38. package/dist/providers/GitHubProvider.js.map +1 -1
  39. package/dist/providers/GitLabProvider.d.ts +1 -0
  40. package/dist/providers/GitLabProvider.d.ts.map +1 -1
  41. package/dist/providers/GitLabProvider.js +3 -0
  42. package/dist/providers/GitLabProvider.js.map +1 -1
  43. package/dist/providers/KeygenProvider.d.ts +1 -0
  44. package/dist/providers/KeygenProvider.d.ts.map +1 -1
  45. package/dist/providers/KeygenProvider.js +3 -0
  46. package/dist/providers/KeygenProvider.js.map +1 -1
  47. package/dist/providers/PrivateGitHubProvider.d.ts +1 -0
  48. package/dist/providers/PrivateGitHubProvider.d.ts.map +1 -1
  49. package/dist/providers/PrivateGitHubProvider.js +4 -0
  50. package/dist/providers/PrivateGitHubProvider.js.map +1 -1
  51. package/dist/providers/Provider.d.ts +7 -0
  52. package/dist/providers/Provider.d.ts.map +1 -1
  53. package/dist/providers/Provider.js +15 -0
  54. package/dist/providers/Provider.js.map +1 -1
  55. package/dist/types.d.ts +59 -0
  56. package/dist/types.d.ts.map +1 -1
  57. package/dist/types.js +13 -0
  58. package/dist/types.js.map +1 -1
  59. package/dist/util.d.ts.map +1 -1
  60. package/dist/util.js +6 -0
  61. package/dist/util.js.map +1 -1
  62. package/dist/windowsExecutableCodeSignatureVerifier.d.ts +2 -1
  63. package/dist/windowsExecutableCodeSignatureVerifier.d.ts.map +1 -1
  64. package/dist/windowsExecutableCodeSignatureVerifier.js +7 -8
  65. package/dist/windowsExecutableCodeSignatureVerifier.js.map +1 -1
  66. package/package.json +3 -3
@@ -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;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
+ {"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;YAuB3F,oBAAoB;IAyBlC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO;CA+CtD"}
@@ -43,8 +43,10 @@ export class AppImageUpdater extends BaseUpdater {
43
43
  if (downloadUpdateOptions.disableDifferentialDownload || (await this.downloadDifferential(fileInfo, oldFile, updateFile, provider, downloadUpdateOptions))) {
44
44
  await this.httpExecutor.download(fileInfo.url, updateFile, downloadOptions);
45
45
  }
46
- await fsExtra.chmod(updateFile, 0o755);
47
46
  },
47
+ // deferred until after verification: the temporary path is predictable, so marking the AppImage executable
48
+ // before it is verified would leave an unverified binary runnable for as long as verification takes
49
+ afterVerification: updateFile => fsExtra.chmod(updateFile, 0o755),
48
50
  });
49
51
  }
50
52
  async downloadDifferential(fileInfo, oldFile, updateFile, provider, downloadUpdateOptions) {
@@ -55,7 +57,7 @@ export class AppImageUpdater extends BaseUpdater {
55
57
  logger: this._logger,
56
58
  newFile: updateFile,
57
59
  isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest,
58
- requestHeaders: downloadUpdateOptions.requestHeaders,
60
+ requestHeaders: this.downloadRequestHeaders(fileInfo.url, downloadUpdateOptions),
59
61
  cancellationToken: downloadUpdateOptions.cancellationToken,
60
62
  };
61
63
  if (this.listenerCount(DOWNLOAD_PROGRESS) > 0) {
@@ -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, 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"]}
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 // deferred until after verification: the temporary path is predictable, so marking the AppImage executable\n // before it is verified would leave an unverified binary runnable for as long as verification takes\n afterVerification: updateFile => fsExtra.chmod(updateFile, 0o755),\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: this.downloadRequestHeaders(fileInfo.url, downloadUpdateOptions),\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,8 +9,8 @@ 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, DownloadExecutorResult, UpdateDownloadedEvent, UpdaterSignal } from "./types.js";
13
- import { VerifyUpdateSupport } from "./index.js";
12
+ import { AutoInstallEvent, Logger, QuitAndInstallOptions, ResolvedUpdateFileInfo, UpdateCheckResult, DownloadExecutorResult, UpdateDownloadedEvent, UpdaterSignal, VerifyUpdateFile } from "./types.js";
13
+ import type { VerifyUpdateSupport } from "./index.js";
14
14
  export type AppUpdaterEvents = {
15
15
  error: (error: Error, message?: string) => void;
16
16
  login: (info: AuthInfo, callback: LoginCallback) => void;
@@ -127,15 +127,22 @@ export declare abstract class AppUpdater extends AppUpdater_base {
127
127
  */
128
128
  allowUnverifiedLinuxPackages: boolean;
129
129
  private _disableWebInstaller;
130
+ protected disableWebInstallerDefault: boolean;
130
131
  /**
131
- * Whether to block NSIS web-installer packages. Web installer files might not have signature verification, so they are disabled by default as of v27.
132
+ * Whether to block NSIS web-installer packages. Web installer files might not have signature verification, so they are disabled by default as of v27:
133
+ * a web-installer update is rejected with `ERR_UPDATER_WEB_INSTALLER_DISABLED` at download time, before an install on next launch, and at install time unless this is `false`.
132
134
  *
133
- * v27 grace period: apps that do not explicitly set this property will warn (but still download) if a web-installer update is received. In v28 the warning becomes an error and the download is blocked (`ERR_UPDATER_WEB_INSTALLER_DISABLED`). Apps that explicitly set this to `true` throw immediately. Set it to `false` only if you intentionally publish and rely on NSIS web-installer packages.
135
+ * `NsisUpdater` defaults it to `false` for installs made by an `nsis-web` installer built with electron-builder v27+ (`resources/package-type` marker).
136
+ * Set it to `false` explicitly only if you intentionally publish and rely on NSIS web-installer packages and your installs lack that marker.
137
+ *
138
+ * Set it before the app is `ready` (e.g. right after creating the updater): with `autoInstallEvent: "onNextLaunch"` a pending
139
+ * web-installer update is checked against it when the app is ready, and rejected (its pending-install marker cleared) while it is `true`.
134
140
  *
135
141
  * @default true
136
142
  */
137
143
  get disableWebInstaller(): boolean;
138
144
  set disableWebInstaller(value: boolean);
145
+ protected get isWebInstallerEnabledByApp(): boolean;
139
146
  /**
140
147
  * *NSIS only* Disable differential downloads and always perform full download of installer.
141
148
  *
@@ -189,6 +196,8 @@ export declare abstract class AppUpdater extends AppUpdater_base {
189
196
  */
190
197
  updateManifestPublicKey: string | Array<string> | null;
191
198
  private manifestVerificationWarned;
199
+ private crossOriginHeadersWarned;
200
+ private crossOriginFeedQueryWarned;
192
201
  /**
193
202
  * The request headers.
194
203
  */
@@ -215,6 +224,26 @@ export declare abstract class AppUpdater extends AppUpdater_base {
215
224
  * @private
216
225
  */
217
226
  set updateConfigPath(value: string | null);
227
+ protected _verifyUpdateFile: VerifyUpdateFile;
228
+ /**
229
+ * Allows developer to set custom logic for verifying an update file before it is allowed to become installable.
230
+ * When the verification fails, the file is deleted and electron-updater emits an `ERR_UPDATER_INVALID_UPDATE_FILE` error.
231
+ * The default behavior is a stub – immediately succeeds.
232
+ *
233
+ * It runs on every path that can lead to an install:
234
+ * - right after a fresh download, while the file still sits under a temporary name and before it is renamed into the
235
+ * updater cache under its real filename, so an unverified file can never be executed under its real name;
236
+ * - when an update downloaded by an earlier session is reused from the updater cache;
237
+ * - before an install-on-next-launch spawns the cached installer (see {@link BaseUpdater}).
238
+ *
239
+ * The custom logic gets `updateFilePath` (the file to verify), `originalUpdateFileName` (its real filename), the
240
+ * optional `packageFilePath` of an NSIS web installer package, and the active `cancellationToken` when the
241
+ * verification belongs to a download.
242
+ *
243
+ * Assigning `null` restores the default stub.
244
+ */
245
+ get verifyUpdateFile(): VerifyUpdateFile;
246
+ set verifyUpdateFile(value: VerifyUpdateFile | null | undefined);
218
247
  protected _isUpdateSupported: VerifyUpdateSupport;
219
248
  /**
220
249
  * Allows developer to override default logic for determining if an update is supported.
@@ -295,6 +324,13 @@ export declare abstract class AppUpdater extends AppUpdater_base {
295
324
  abstract quitAndInstall(options?: QuitAndInstallOptions): void;
296
325
  private loadUpdateConfig;
297
326
  private computeRequestHeaders;
327
+ /**
328
+ * Headers for a download from `url`: when the provider has a `feedBaseUrl`, the credential-bearing ones are dropped if `url` is on
329
+ * another origin than `originUrl` (the feed by default). `null` keeps them for every URL.
330
+ */
331
+ protected downloadRequestHeaders(url: URL, downloadUpdateOptions: DownloadUpdateOptions, originUrl?: URL): OutgoingHttpHeaders;
332
+ private announceCrossOriginDownload;
333
+ private static checkFeedBaseUrlDeclared;
298
334
  private getOrCreateStagingUserId;
299
335
  protected getOrCreateDownloadHelper(): Promise<DownloadedUpdateHelper>;
300
336
  protected executeDownload(taskOptions: DownloadExecutorTask): Promise<DownloadExecutorResult>;
@@ -322,6 +358,11 @@ export interface DownloadExecutorTask {
322
358
  readonly fileInfo: ResolvedUpdateFileInfo;
323
359
  readonly downloadUpdateOptions: DownloadUpdateOptions;
324
360
  readonly task: (destinationFile: string, downloadOptions: DownloadOptions, packageFile: string | null, removeTempDirIfAny: () => Promise<any>) => Promise<any>;
361
+ /**
362
+ * Runs after the downloaded file passed verification and before it is renamed into the cache under its real name.
363
+ * For anything that must not be done to a file that is still unverified — making it executable, in particular.
364
+ */
365
+ readonly afterVerification?: (destinationFile: string) => Promise<void>;
325
366
  readonly done?: (event: UpdateDownloadedEvent) => Promise<any>;
326
367
  }
327
368
  export interface DownloadNotification {
@@ -1 +1 @@
1
- {"version":3,"file":"AppUpdater.d.ts","sourceRoot":"","sources":["../src/AppUpdater.ts"],"names":[],"mappings":"AACA,OAAO,EACL,iBAAiB,EAEjB,iBAAiB,EAEjB,oBAAoB,EACpB,UAAU,EAEV,eAAe,EAEf,YAAY,EAMb,MAAM,sBAAsB,CAAA;AAK7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,MAAM,CAAA;AAE1C,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAA;AAE/B,OAAO,EAAiJ,MAAM,EAAE,MAAM,QAAQ,CAAA;AAC9K,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAwB,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAE1F,OAAO,EAAuC,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAG9F,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAA;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACtD,KAAK,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAA;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AAIxC,OAAO,EACL,gBAAgB,EAEhB,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EAEtB,iBAAiB,EACjB,sBAAsB,EACtB,qBAAqB,EACrB,aAAa,EACd,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAIhD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;IAC/C,KAAK,EAAE,CAAC,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,KAAK,IAAI,CAAA;IACxD,qBAAqB,EAAE,MAAM,IAAI,CAAA;IACjC,sBAAsB,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IAClD,kBAAkB,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IAC9C,mBAAmB,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,IAAI,CAAA;IAC3D,mBAAmB,EAAE,CAAC,IAAI,EAAE,YAAY,KAAK,IAAI,CAAA;IACjD,kBAAkB,EAAE,CAAC,IAAI,EAAE,UAAU,KAAK,IAAI,CAAA;IAC9C,2BAA2B,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CACpD,CAAA;+BAEyD,UAAU,YAAY,CAAC,gBAAgB,CAAC;AAAlG,8BAAsB,UAAW,SAAQ,eAA0D;IACjG;;;OAGG;IACH,YAAY,UAAO;IAEnB;;;;;;;;;;;;;;;;;;OAkBG;IACH,gBAAgB,EAAE,gBAAgB,CAAW;IAE7C;;;;;;;;OAQG;IACH,IAAI,oBAAoB,IAAI,OAAO,CAElC;IAED,IAAI,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAStC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,+BAA+B,IAAI,OAAO,CAAC,OAAO,CAAC;IAKnD;;;OAGG;IACH,sBAAsB,UAAO;IAE7B;;;;OAIG;IACH,eAAe,UAAQ;IAEvB;;;OAGG;IACH,aAAa,UAAQ;IAErB;;;;;;OAMG;IACH,cAAc,UAAQ;IAEtB;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,4BAA4B,UAAO;IAEnC,OAAO,CAAC,oBAAoB,CAAiC;IAE7D;;;;;;OAMG;IACH,IAAI,mBAAmB,IAAI,OAAO,CAEjC;IAED,IAAI,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAErC;IAED;;;;OAIG;IACH,2BAA2B,UAAQ;IAEnC;;;;;;OAMG;IACH,oBAAoB,UAAQ;IAE5B;;;;;;;;;OASG;IACI,+BAA+B,EAAE,MAAM,GAAG,IAAI,CAAO;IAE5D;;OAEG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAA;IAE/B,OAAO,CAAC,QAAQ,CAAsB;IAEtC,SAAS,CAAC,sBAAsB,EAAE,sBAAsB,GAAG,IAAI,CAAO;IAEtE;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,GAAG,IAAI,CAE3B;IAED;;;;OAIG;IACH,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAY/B;IAED;;;;;;;;;OASG;IACH,uBAAuB,EAAE,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAO;IAE7D,OAAO,CAAC,0BAA0B,CAAQ;IAE1C;;OAEG;IACH,cAAc,EAAE,mBAAmB,GAAG,IAAI,CAAO;IAEjD;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,MAAM;IAM3B,SAAS,CAAC,OAAO,EAAE,MAAM,CAAU;IAGnC,IAAI,UAAU,IAAI,OAAO,CAExB;IAED;;;OAGG;IACH,IAAI,MAAM,IAAI,MAAM,GAAG,IAAI,CAE1B;IAED,IAAI,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAE9B;IAGD;;OAEG;IACH,QAAQ,CAAC,OAAO,gBAA0B;IAE1C,OAAO,CAAC,oBAAoB,CAAsB;IAGlD;;;OAGG;IACH,IAAI,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAIxC;IAED,SAAS,CAAC,kBAAkB,EAAE,mBAAmB,CAAwD;IAEzG;;;OAGG;IACH,IAAI,iBAAiB,IAAI,mBAAmB,CAE3C;IAED,IAAI,iBAAiB,CAAC,KAAK,EAAE,mBAAmB,EAI/C;IAED,SAAS,CAAC,oBAAoB,EAAE,mBAAmB,CAAgD;IAEnG;;;;OAIG;IACH,IAAI,mBAAmB,IAAI,mBAAmB,CAE7C;IAED,IAAI,mBAAmB,CAAC,KAAK,EAAE,mBAAmB,EAIjD;IAED,OAAO,CAAC,aAAa,CAAsC;IAE3D,SAAS,CAAC,QAAQ,CAAC,oBAAoB,eAA0D;IAMjG,OAAO,CAAC,sBAAsB,CAA0C;IACxE,OAAO,CAAC,eAAe,CAA+C;IAEtE,SAAS,CAAC,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAA;IAElC,SAAS,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,IAAI,CAAO;IAKpE,SAAS,aAAa,OAAO,EAAE,iBAAiB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,CAAC,EAAE,UAAU;IAiCrF,UAAU,IAAI,MAAM,GAAG,IAAI,GAAG,SAAS;IAIvC;;;OAGG;IACH,UAAU,CAAC,OAAO,EAAE,oBAAoB,GAAG,iBAAiB,GAAG,MAAM;IAerE;;;OAGG;IACH,eAAe,IAAI,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IA6B7C,eAAe,IAAI,OAAO;IAUjC,wBAAwB,CAAC,oBAAoB,CAAC,EAAE,oBAAoB,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAkBxG,OAAO,CAAC,MAAM,CAAC,0BAA0B;YAc3B,cAAc;IAuB5B,OAAO,CAAC,mBAAmB;YAOb,iBAAiB;IAkC/B,OAAO,CAAC,sBAAsB;cAgBd,wBAAwB,IAAI,OAAO,CAAC,qBAAqB,CAAC;IAkB1E;;;;;;;;;;;;OAYG;YACW,uBAAuB;IA0CrC,OAAO,CAAC,4BAA4B;YAQtB,iBAAiB;IAiC/B,SAAS,CAAC,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI;IASzD;;;;OAIG;IACH,cAAc,CAAC,iBAAiB,GAAE,iBAA2C,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAgD/G,SAAS,CAAC,aAAa,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI;IAIvC,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,qBAAqB,GAAG,IAAI;IAItE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IAElH;;;;;;;;;OASG;IACH,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,EAAE,qBAAqB,GAAG,IAAI;YA0BhD,gBAAgB;IAO9B,OAAO,CAAC,qBAAqB;YAcf,wBAAwB;cAgDtB,yBAAyB,IAAI,OAAO,CAAC,sBAAsB,CAAC;cAmB5D,eAAe,CAAC,WAAW,EAAE,oBAAoB,GAAG,OAAO,CAAC,sBAAsB,CAAC;cAoHnF,6BAA6B,CAC3C,QAAQ,EAAE,sBAAsB,EAChC,qBAAqB,EAAE,qBAAqB,EAC5C,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvB,oBAAoB,EAAE,MAAM,GAC3B,OAAO,CAAC,OAAO,CAAC;CA4FpB;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB,CAAA;IACrD,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAA;IAC5C,QAAQ,CAAC,iBAAiB,EAAE,iBAAiB,CAAA;IAC7C,QAAQ,CAAC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IACtC,QAAQ,CAAC,2BAA2B,CAAC,EAAE,OAAO,CAAA;CAC/C;AAOD,eAAe;AACf,qBAAa,UAAW,YAAW,MAAM;IAEvC,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;IAKlB,IAAI,CAAC,OAAO,CAAC,EAAE,GAAG;IAKlB,KAAK,CAAC,OAAO,CAAC,EAAE,GAAG;CAGpB;AAED,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,UAAU,CAAA;IAChB,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAA;CACxB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAA;IACzC,QAAQ,CAAC,qBAAqB,EAAE,qBAAqB,CAAA;IACrD,QAAQ,CAAC,IAAI,EAAE,CAAC,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;IAE9J,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,qBAAqB,KAAK,OAAO,CAAC,GAAG,CAAC,CAAA;CAC/D;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,MAAM,CAAA;CACd;AAED,eAAe;AACf,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,gBAAgB,CAAA;IAE1B,yBAAyB,CAAC,EAAE,OAAO,CAAA;CACpC"}
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, collectManifestSignatures, normalizePublicKeyList, verifyManifestSignatures, } from "builder-util-runtime";
2
+ import { asArray, CancellationToken, newError, UUID, CancellationError, HttpExecutor, 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";
@@ -15,8 +15,10 @@ import { GenericProvider } from "./providers/GenericProvider.js";
15
15
  import { createClient, isUrlProbablySupportMultiRangeRequests } from "./providerFactory.js";
16
16
  import { gunzipSync, gzipSync } from "zlib";
17
17
  import { GenericDifferentialDownloader } from "./differentialDownloader/GenericDifferentialDownloader.js";
18
- import { DOWNLOAD_PROGRESS, UPDATE_DOWNLOADED, UpdaterSignal, } from "./types.js";
18
+ import { DOWNLOAD_PROGRESS, UPDATE_DOWNLOADED, UpdaterSignal, verificationFailureMessage, } from "./types.js";
19
19
  const require = createRequire(import.meta.url);
20
+ // shared rather than per-instance so that `updater.verifyUpdateFile === DEFAULT_VERIFY_UPDATE_FILE` identifies "no custom verifier"
21
+ const DEFAULT_VERIFY_UPDATE_FILE = _params => Promise.resolve({ response: "success" });
20
22
  export class AppUpdater extends EventEmitter {
21
23
  /**
22
24
  * @deprecated Removed in v27 — use {@link autoInstallEvent}. This accessor is a compatibility shim
@@ -61,18 +63,27 @@ export class AppUpdater extends EventEmitter {
61
63
  return Promise.resolve(false);
62
64
  }
63
65
  /**
64
- * Whether to block NSIS web-installer packages. Web installer files might not have signature verification, so they are disabled by default as of v27.
66
+ * Whether to block NSIS web-installer packages. Web installer files might not have signature verification, so they are disabled by default as of v27:
67
+ * a web-installer update is rejected with `ERR_UPDATER_WEB_INSTALLER_DISABLED` at download time, before an install on next launch, and at install time unless this is `false`.
65
68
  *
66
- * v27 grace period: apps that do not explicitly set this property will warn (but still download) if a web-installer update is received. In v28 the warning becomes an error and the download is blocked (`ERR_UPDATER_WEB_INSTALLER_DISABLED`). Apps that explicitly set this to `true` throw immediately. Set it to `false` only if you intentionally publish and rely on NSIS web-installer packages.
69
+ * `NsisUpdater` defaults it to `false` for installs made by an `nsis-web` installer built with electron-builder v27+ (`resources/package-type` marker).
70
+ * Set it to `false` explicitly only if you intentionally publish and rely on NSIS web-installer packages and your installs lack that marker.
71
+ *
72
+ * Set it before the app is `ready` (e.g. right after creating the updater): with `autoInstallEvent: "onNextLaunch"` a pending
73
+ * web-installer update is checked against it when the app is ready, and rejected (its pending-install marker cleared) while it is `true`.
67
74
  *
68
75
  * @default true
69
76
  */
70
77
  get disableWebInstaller() {
71
- return this._disableWebInstaller ?? true;
78
+ return this._disableWebInstaller ?? this.disableWebInstallerDefault;
72
79
  }
73
80
  set disableWebInstaller(value) {
74
81
  this._disableWebInstaller = value;
75
82
  }
83
+ // the app itself set disableWebInstaller to false (not the nsis-web default)
84
+ get isWebInstallerEnabledByApp() {
85
+ return this._disableWebInstaller === false;
86
+ }
76
87
  /**
77
88
  * Get the update channel. Doesn't return `channel` from the update configuration, only if was previously set.
78
89
  */
@@ -129,6 +140,29 @@ export class AppUpdater extends EventEmitter {
129
140
  this._appUpdateConfigPath = value;
130
141
  this.configOnDisk = new Lazy(() => this.loadUpdateConfig());
131
142
  }
143
+ /**
144
+ * Allows developer to set custom logic for verifying an update file before it is allowed to become installable.
145
+ * When the verification fails, the file is deleted and electron-updater emits an `ERR_UPDATER_INVALID_UPDATE_FILE` error.
146
+ * The default behavior is a stub – immediately succeeds.
147
+ *
148
+ * It runs on every path that can lead to an install:
149
+ * - right after a fresh download, while the file still sits under a temporary name and before it is renamed into the
150
+ * updater cache under its real filename, so an unverified file can never be executed under its real name;
151
+ * - when an update downloaded by an earlier session is reused from the updater cache;
152
+ * - before an install-on-next-launch spawns the cached installer (see {@link BaseUpdater}).
153
+ *
154
+ * The custom logic gets `updateFilePath` (the file to verify), `originalUpdateFileName` (its real filename), the
155
+ * optional `packageFilePath` of an NSIS web installer package, and the active `cancellationToken` when the
156
+ * verification belongs to a download.
157
+ *
158
+ * Assigning `null` restores the default stub.
159
+ */
160
+ get verifyUpdateFile() {
161
+ return this._verifyUpdateFile;
162
+ }
163
+ set verifyUpdateFile(value) {
164
+ this._verifyUpdateFile = value ?? DEFAULT_VERIFY_UPDATE_FILE;
165
+ }
132
166
  /**
133
167
  * Allows developer to override default logic for determining if an update is supported.
134
168
  * The default logic compares the `UpdateInfo` minimum system version against the `os.release()` with `semver` package
@@ -228,7 +262,10 @@ export class AppUpdater extends EventEmitter {
228
262
  * @default true
229
263
  */
230
264
  this.allowUnverifiedLinuxPackages = true;
265
+ // undefined until the app sets disableWebInstaller, so NsisUpdater can tell a `false` set by the app from the nsis-web default
231
266
  this._disableWebInstaller = undefined;
267
+ // the value of disableWebInstaller while the app has not set it; NsisUpdater sets it to false for an install made by an nsis-web installer
268
+ this.disableWebInstallerDefault = true;
232
269
  /**
233
270
  * *NSIS only* Disable differential downloads and always perform full download of installer.
234
271
  *
@@ -268,6 +305,9 @@ export class AppUpdater extends EventEmitter {
268
305
  */
269
306
  this.updateManifestPublicKey = null;
270
307
  this.manifestVerificationWarned = false;
308
+ // v27 behaviour changes a plain-JavaScript app would otherwise not notice: each is announced once per updater
309
+ this.crossOriginHeadersWarned = false;
310
+ this.crossOriginFeedQueryWarned = false;
271
311
  /**
272
312
  * The request headers.
273
313
  */
@@ -279,6 +319,7 @@ export class AppUpdater extends EventEmitter {
279
319
  */
280
320
  this.signals = new UpdaterSignal(this);
281
321
  this._appUpdateConfigPath = null;
322
+ this._verifyUpdateFile = DEFAULT_VERIFY_UPDATE_FILE;
282
323
  this._isUpdateSupported = updateInfo => this.checkIfUpdateSupported(updateInfo);
283
324
  this._isUserWithinRollout = updateInfo => this.isStagingMatch(updateInfo);
284
325
  this.clientPromise = null;
@@ -389,7 +430,10 @@ export class AppUpdater extends EventEmitter {
389
430
  }
390
431
  void it.downloadPromise.then(() => {
391
432
  const notificationContent = AppUpdater.formatDownloadNotification(it.updateInfo.version, this.app.name, downloadNotification);
392
- new (require("electron").Notification)(notificationContent).show();
433
+ const ElectronNotification = require("electron").Notification;
434
+ new ElectronNotification(notificationContent).show();
435
+ }, () => {
436
+ // downloadUpdate already dispatches the error event
393
437
  });
394
438
  return it;
395
439
  });
@@ -530,7 +574,12 @@ export class AppUpdater extends EventEmitter {
530
574
  // `reason` is set when the manifest fails the structural checks a signed manifest must pass (e.g. an empty
531
575
  // `files` list or control characters in a signed field) — those are rejected before any key is tried.
532
576
  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");
577
+ // download URLs written into latest*.yml after signing (e.g. pre-signed URLs) are the likely cause, rather than tampering
578
+ const blockMapUrlHint = (info.files ?? []).some(it => it?.blockMapUrl != null)
579
+ ? " files[].blockMapUrl is covered by the signature, like files[].url, so it has to be in latest*.yml before the manifest is signed: " +
580
+ "https://www.electron.build/docs/features/signed-update-manifests#what-is-signed"
581
+ : "";
582
+ throw newError(`Update manifest signature verification failed for version ${info.version}: ${cause}. The update metadata may have been tampered with. Refusing to update.${blockMapUrlHint}`, "ERR_UPDATER_MANIFEST_SIGNATURE_INVALID");
534
583
  }
535
584
  this._logger.debug?.(`Update manifest for version ${info.version} verified with trusted key ${result.keyId}`);
536
585
  this._logger.info(`Update manifest signature verified for version ${info.version}`);
@@ -604,11 +653,19 @@ export class AppUpdater extends EventEmitter {
604
653
  }
605
654
  return e;
606
655
  };
656
+ const requestHeaders = this.computeRequestHeaders(updateInfoAndProvider.provider);
657
+ try {
658
+ // fail before any download rather than in the middle of one
659
+ AppUpdater.checkFeedBaseUrlDeclared(updateInfoAndProvider.provider, requestHeaders);
660
+ }
661
+ catch (e) {
662
+ return Promise.reject(errorHandler(e));
663
+ }
607
664
  this.downloadPromise = this.doDownloadUpdate({
608
665
  updateInfoAndProvider,
609
- requestHeaders: this.computeRequestHeaders(updateInfoAndProvider.provider),
666
+ requestHeaders,
610
667
  cancellationToken,
611
- disableWebInstaller: this._disableWebInstaller,
668
+ disableWebInstaller: this.disableWebInstaller,
612
669
  disableDifferentialDownload: this.disableDifferentialDownload,
613
670
  })
614
671
  .catch((e) => {
@@ -665,6 +722,55 @@ export class AppUpdater extends EventEmitter {
665
722
  }
666
723
  return this.computeFinalHeaders({ accept: "*/*" });
667
724
  }
725
+ /**
726
+ * Headers for a download from `url`: when the provider has a `feedBaseUrl`, the credential-bearing ones are dropped if `url` is on
727
+ * another origin than `originUrl` (the feed by default). `null` keeps them for every URL.
728
+ */
729
+ downloadRequestHeaders(url, downloadUpdateOptions, originUrl) {
730
+ const provider = downloadUpdateOptions.updateInfoAndProvider.provider;
731
+ const headers = downloadUpdateOptions.requestHeaders;
732
+ AppUpdater.checkFeedBaseUrlDeclared(provider, headers);
733
+ const feedBaseUrl = provider.feedBaseUrl;
734
+ if (feedBaseUrl == null) {
735
+ return headers;
736
+ }
737
+ const credentialOrigin = originUrl ?? feedBaseUrl;
738
+ if (HttpExecutor.isCrossOrigin(credentialOrigin, url)) {
739
+ this.announceCrossOriginDownload(url, credentialOrigin, headers, originUrl == null ? feedBaseUrl : null);
740
+ }
741
+ return HttpExecutor.removeCrossOriginSensitiveHeaders(headers, credentialOrigin, url);
742
+ }
743
+ // Only names are logged (header names, query parameter names, origins), never values.
744
+ announceCrossOriginDownload(url, credentialOrigin, headers, feedBaseUrl) {
745
+ const docs = "https://www.electron.build/docs/migration/v27-breaking-changes#update-credentials-stay-on-the-feeds-origin";
746
+ const names = HttpExecutor.sensitiveHeaderNames(headers);
747
+ if (names.length !== 0 && !this.crossOriginHeadersWarned) {
748
+ this.crossOriginHeadersWarned = true;
749
+ this._logger.warn(`electron-updater 7 (electron-builder v27) sends the credential headers from requestHeaders / addAuthHeader only to the update feed's origin (${credentialOrigin.origin}): ` +
750
+ `${names.join(", ")} not sent to ${url.origin}, which is another origin. ` +
751
+ `If that server needs them, serve the update files from the feed origin or use pre-signed URLs. ${docs}`);
752
+ }
753
+ const feedQueryNames = feedBaseUrl == null ? [] : [...new Set(feedBaseUrl.searchParams.keys())];
754
+ if (feedQueryNames.length !== 0 && !this.crossOriginFeedQueryWarned) {
755
+ this.crossOriginFeedQueryWarned = true;
756
+ this._logger.warn(`electron-updater 7 (electron-builder v27) adds the feed URL's query string (${feedQueryNames.join(", ")}) only to URLs on the update feed's origin (${feedBaseUrl.origin}): ` +
757
+ `not added to the download from ${url.origin}, which keeps its own query string. ` +
758
+ `If that server needs it, serve the update files from the feed origin or use pre-signed URLs. ${docs}`);
759
+ }
760
+ }
761
+ // Credential headers are only sent where the provider says (Provider.feedBaseUrl); a provider that does not say is a configuration error.
762
+ static checkFeedBaseUrlDeclared(provider, headers) {
763
+ if (provider.feedBaseUrl !== undefined) {
764
+ return;
765
+ }
766
+ const names = HttpExecutor.sensitiveHeaderNames(headers);
767
+ if (names.length !== 0) {
768
+ throw newError(`The custom update provider ${provider.constructor.name} does not declare feedBaseUrl, but its downloads would send the credential headers ${names.join(", ")} ` +
769
+ `(from requestHeaders, addAuthHeader or fileExtraDownloadHeaders). Override Provider.feedBaseUrl to return the feed URL ` +
770
+ `(the headers are then only sent to its origin), or null to send the request headers to every origin. ` +
771
+ `https://www.electron.build/docs/migration/v27-breaking-changes#update-credentials-stay-on-the-feeds-origin`, "ERR_UPDATER_FEED_BASE_URL_NOT_DECLARED");
772
+ }
773
+ }
668
774
  async getOrCreateStagingUserId() {
669
775
  const file = path.join(this.app.userDataPath, ".updaterId");
670
776
  try {
@@ -729,7 +835,7 @@ export class AppUpdater extends EventEmitter {
729
835
  this._logger.warn("Update artifact is validated with a SHA-256 (sha2) checksum only. SHA-256 update checksums are deprecated; electron-builder v28 will require SHA-512 and reject SHA-256-only update metadata (fail-closed). Regenerate latest*.yml with a current electron-builder and avoid pinning electronUpdaterCompatibility to a legacy (<2.15 / 1.x) range.");
730
836
  }
731
837
  const downloadOptions = {
732
- headers: taskOptions.downloadUpdateOptions.requestHeaders,
838
+ headers: this.downloadRequestHeaders(fileInfo.url, taskOptions.downloadUpdateOptions),
733
839
  cancellationToken: taskOptions.downloadUpdateOptions.cancellationToken,
734
840
  sha2: fileInfo.info.sha2,
735
841
  sha512: fileInfo.info.sha512,
@@ -740,22 +846,10 @@ export class AppUpdater extends EventEmitter {
740
846
  const updateInfo = taskOptions.downloadUpdateOptions.updateInfoAndProvider.info;
741
847
  const version = updateInfo.version;
742
848
  const packageInfo = fileInfo.packageInfo;
743
- function getCacheUpdateFileName() {
744
- // NodeJS URL doesn't decode automatically
745
- const urlPath = decodeURIComponent(taskOptions.fileInfo.url.pathname);
746
- if (urlPath.toLowerCase().endsWith(`.${taskOptions.fileExtension.toLowerCase()}`)) {
747
- return path.basename(urlPath);
748
- }
749
- else {
750
- // url like /latest — use basename so a server-supplied path like "../../etc/evil"
751
- // cannot escape the cache directory via path.join
752
- return path.basename(taskOptions.fileInfo.info.url);
753
- }
754
- }
755
849
  const downloadedUpdateHelper = await this.getOrCreateDownloadHelper();
756
850
  const cacheDir = downloadedUpdateHelper.cacheDirForPendingUpdate;
757
851
  await fsExtra.mkdir(cacheDir, { recursive: true });
758
- const updateFileName = getCacheUpdateFileName();
852
+ const updateFileName = getCacheUpdateFileName(taskOptions.fileInfo, taskOptions.fileExtension);
759
853
  let updateFile = path.join(cacheDir, updateFileName);
760
854
  const packageFile = packageInfo == null ? null : path.join(cacheDir, `package-${version}${path.extname(packageInfo.path) || ".7z"}`);
761
855
  const pendingBlockMapFile = path.join(cacheDir, "current.blockmap");
@@ -780,11 +874,7 @@ export class AppUpdater extends EventEmitter {
780
874
  return withLegacyArrayCompat(packageFile == null ? { updateFile } : { updateFile, packageFile }, this._logger);
781
875
  };
782
876
  const log = this._logger;
783
- const cachedUpdateFile = await downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
784
- if (cachedUpdateFile != null) {
785
- updateFile = cachedUpdateFile;
786
- return await done(false);
787
- }
877
+ const cancellationToken = taskOptions.downloadUpdateOptions.cancellationToken;
788
878
  const removeFileIfAny = async () => {
789
879
  await downloadedUpdateHelper.clear().catch(() => {
790
880
  // ignore
@@ -793,6 +883,35 @@ export class AppUpdater extends EventEmitter {
793
883
  // ignore
794
884
  });
795
885
  };
886
+ const verifyUpdateFile = async (fileToVerify) => {
887
+ const failure = verificationFailureMessage(await this.verifyUpdateFile({
888
+ updateFilePath: fileToVerify,
889
+ originalUpdateFileName: updateFileName,
890
+ // only offered when the companion package was actually written: `packageFile` is derived from the update
891
+ // metadata, so it is non-null for any channel file carrying a `packages` block even on targets that never
892
+ // download one
893
+ packageFilePath: packageFile != null && (await fsExtra.pathExists(packageFile)) ? packageFile : undefined,
894
+ cancellationToken,
895
+ }));
896
+ if (failure != null) {
897
+ throw newError(`Downloaded update file ${updateFileName} failed verification: ${failure}`, "ERR_UPDATER_INVALID_UPDATE_FILE");
898
+ }
899
+ };
900
+ const cachedUpdateFile = await downloadedUpdateHelper.validateDownloadedPath(updateFile, updateInfo, fileInfo, log);
901
+ if (cachedUpdateFile != null) {
902
+ updateFile = cachedUpdateFile;
903
+ // an update downloaded by an earlier session is about to be announced as ready to install without being
904
+ // downloaded again, so the custom verifier has to gate it here too — its only other gate is the sha512 taken
905
+ // from the very update metadata a custom verifier exists to distrust
906
+ try {
907
+ await verifyUpdateFile(updateFile);
908
+ }
909
+ catch (e) {
910
+ await removeFileIfAny();
911
+ throw e;
912
+ }
913
+ return await done(false);
914
+ }
796
915
  // a fresh download starts — drop any blockmap left over from a previous update round, so that when this round
797
916
  // does not produce a new one (e.g. the differential download is skipped), the leftover cannot be promoted to the
798
917
  // cache next to a file it does not describe
@@ -800,6 +919,18 @@ export class AppUpdater extends EventEmitter {
800
919
  const tempUpdateFile = await createTempUpdateFile(`temp-${updateFileName}`, cacheDir, log);
801
920
  try {
802
921
  await taskOptions.task(tempUpdateFile, downloadOptions, packageFile, removeFileIfAny);
922
+ // checked before verifying as well as after: verification can be arbitrarily expensive (hashing a large
923
+ // installer, a remote attestation call), and there is no point paying for it on a download already cancelled
924
+ if (cancellationToken.cancelled) {
925
+ throw new CancellationError();
926
+ }
927
+ await verifyUpdateFile(tempUpdateFile);
928
+ if (cancellationToken.cancelled) {
929
+ throw new CancellationError();
930
+ }
931
+ // only now may the file be made executable — doing it inside `task` would leave an unverified binary
932
+ // executable under a predictable path for as long as verification takes
933
+ await taskOptions.afterVerification?.(tempUpdateFile);
803
934
  await retry(() => fsExtra.rename(tempUpdateFile, updateFile), {
804
935
  retries: 60,
805
936
  interval: 500,
@@ -835,11 +966,24 @@ export class AppUpdater extends EventEmitter {
835
966
  return true;
836
967
  }
837
968
  const provider = downloadUpdateOptions.updateInfoAndProvider.provider;
838
- const blockmapFileUrls = await provider.getBlockMapFiles(fileInfo.url, this.app.version, downloadUpdateOptions.updateInfoAndProvider.info.version, this.previousBlockmapBaseUrlOverride);
839
- this._logger.info(`Download block maps (old: "${blockmapFileUrls[0]}", new: ${blockmapFileUrls[1]})`);
840
- const downloadBlockMap = async (url) => {
969
+ const override = this.previousBlockmapBaseUrlOverride;
970
+ const getBlockMapFiles = () => provider.getBlockMapFiles(fileInfo.url, this.app.version, downloadUpdateOptions.updateInfoAndProvider.info.version, override);
971
+ let oldBlockMapUrl;
972
+ let newBlockMapUrl;
973
+ if (fileInfo.blockMapUrl == null) {
974
+ ;
975
+ [oldBlockMapUrl, newBlockMapUrl] = await getBlockMapFiles();
976
+ }
977
+ else {
978
+ // The update manifest names the new blockmap (e.g. separately pre-signed), so a URL derived from the new file's URL is not
979
+ // valid for the old one: the old blockmap comes from the cache, else from previousBlockmapBaseUrlOverride.
980
+ newBlockMapUrl = fileInfo.blockMapUrl;
981
+ oldBlockMapUrl = override ? (await getBlockMapFiles())[0] : null;
982
+ }
983
+ this._logger.info(`Download block maps (old: "${oldBlockMapUrl ?? "cache only"}", new: ${newBlockMapUrl})`);
984
+ const downloadBlockMap = async (url, originUrl) => {
841
985
  const data = await this.httpExecutor.downloadToBuffer(url, {
842
- headers: downloadUpdateOptions.requestHeaders,
986
+ headers: this.downloadRequestHeaders(url, downloadUpdateOptions, originUrl),
843
987
  cancellationToken: downloadUpdateOptions.cancellationToken,
844
988
  });
845
989
  if (data == null || data.length === 0) {
@@ -858,7 +1002,7 @@ export class AppUpdater extends EventEmitter {
858
1002
  logger: this._logger,
859
1003
  newFile: installerPath,
860
1004
  isUseMultipleRangeRequest: provider.isUseMultipleRangeRequest,
861
- requestHeaders: downloadUpdateOptions.requestHeaders,
1005
+ requestHeaders: this.downloadRequestHeaders(fileInfo.url, downloadUpdateOptions),
862
1006
  cancellationToken: downloadUpdateOptions.cancellationToken,
863
1007
  };
864
1008
  if (this.listenerCount(DOWNLOAD_PROGRESS) > 0) {
@@ -880,14 +1024,21 @@ export class AppUpdater extends EventEmitter {
880
1024
  }
881
1025
  return null;
882
1026
  };
883
- const newBlockMapData = await downloadBlockMap(blockmapFileUrls[1]);
1027
+ const newBlockMapData = await downloadBlockMap(newBlockMapUrl);
884
1028
  await saveBlockMapToCacheDir(newBlockMapData, this.downloadedUpdateHelper.cacheDirForPendingUpdate);
885
1029
  // get old blockmap from cache dir first, if not found, download it
886
1030
  let oldBlockMapData = await getBlockMapFromCacheDir(this.downloadedUpdateHelper.cacheDir);
887
1031
  isOldBlockMapFromCache = oldBlockMapData != null;
888
1032
  if (oldBlockMapData == null) {
889
- this._logger.info(`No cached blockmap for the old installer, downloading it from "${blockmapFileUrls[0]}"`);
890
- oldBlockMapData = await downloadBlockMap(blockmapFileUrls[0]);
1033
+ if (oldBlockMapUrl == null) {
1034
+ // the full download caches the new blockmap downloaded above, so the next update can be differential
1035
+ this._logger.info("No cached blockmap for the old installer, and the update manifest sets blockMapUrl, so the old blockmap URL cannot be derived " +
1036
+ "(set previousBlockmapBaseUrlOverride to download it): downloading the full update");
1037
+ return true;
1038
+ }
1039
+ this._logger.info(`No cached blockmap for the old installer, downloading it from "${oldBlockMapUrl}"`);
1040
+ // the old blockmap comes from previousBlockmapBaseUrlOverride when the app sets it, so that origin gets the credentials
1041
+ oldBlockMapData = await downloadBlockMap(oldBlockMapUrl, override ? new URL(override) : undefined);
891
1042
  }
892
1043
  await new GenericDifferentialDownloader(fileInfo.info, this.httpExecutor, downloadOptions).download(oldBlockMapData, newBlockMapData);
893
1044
  return false;
@@ -905,6 +1056,18 @@ export class AppUpdater extends EventEmitter {
905
1056
  }
906
1057
  }
907
1058
  }
1059
+ /** @internal */
1060
+ export function getCacheUpdateFileName(fileInfo, fileExtension) {
1061
+ // NodeJS URL doesn't decode automatically
1062
+ const urlPath = decodeURIComponent(fileInfo.url.pathname);
1063
+ const fileName = path.basename(urlPath.toLowerCase().endsWith(`.${fileExtension.toLowerCase()}`) ? urlPath : fileInfo.info.url);
1064
+ // basename(".") and basename("..") remain traversal segments. Reject them explicitly,
1065
+ // along with values that cannot be represented as a single portable filename.
1066
+ if (fileName.length === 0 || fileName === "." || fileName === ".." || fileName.includes("\0") || fileName.includes("/") || fileName.includes("\\")) {
1067
+ throw newError(`Invalid update file name: ${JSON.stringify(fileName)}`, "ERR_UPDATER_INVALID_FILE_NAME");
1068
+ }
1069
+ return fileName;
1070
+ }
908
1071
  function hasPrereleaseComponents(version) {
909
1072
  const versionPrereleaseComponent = getVersionPreleaseComponents(version);
910
1073
  return versionPrereleaseComponent != null && versionPrereleaseComponent.length > 0;