electron-updater 4.6.4 → 5.0.0-alpha.2
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.
- package/out/AppUpdater.d.ts +10 -0
- package/out/AppUpdater.js +11 -1
- package/out/AppUpdater.js.map +1 -1
- package/out/MacUpdater.d.ts +1 -0
- package/out/MacUpdater.js +59 -22
- package/out/MacUpdater.js.map +1 -1
- package/out/NsisUpdater.js +6 -0
- package/out/NsisUpdater.js.map +1 -1
- package/out/providerFactory.js +0 -3
- package/out/providerFactory.js.map +1 -1
- package/out/providers/GitHubProvider.js +52 -11
- package/out/providers/GitHubProvider.js.map +1 -1
- package/out/windowsExecutableCodeSignatureVerifier.js +22 -8
- package/out/windowsExecutableCodeSignatureVerifier.js.map +1 -1
- package/package.json +38 -37
- package/CHANGELOG.md +0 -382
- package/out/providers/BintrayProvider.d.ts +0 -11
- package/out/providers/BintrayProvider.js +0 -44
- package/out/providers/BintrayProvider.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"providerFactory.js","sourceRoot":"","sources":["../src/providerFactory.ts"],"names":[],"mappings":";;;AAAA,+
|
|
1
|
+
{"version":3,"file":"providerFactory.js","sourceRoot":"","sources":["../src/providerFactory.ts"],"names":[],"mappings":";;;AAAA,+DAW6B;AAE7B,qEAAiE;AACjE,iEAA6D;AAC7D,+DAA2D;AAC3D,+DAA2D;AAC3D,6EAAyE;AAGzE,SAAgB,sCAAsC,CAAC,GAAW;IAChE,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAA;AAC1C,CAAC;AAFD,wFAEC;AAED,SAAgB,YAAY,CAAC,IAA8C,EAAE,OAAmB,EAAE,cAAsC;IACtI,qCAAqC;IACrC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,MAAM,+BAAQ,CAAC,yCAAyC,EAAE,4CAA4C,CAAC,CAAA;KACxG;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAA;IAC9B,QAAQ,QAAQ,EAAE;QAChB,KAAK,QAAQ,CAAC,CAAC;YACb,MAAM,aAAa,GAAG,IAAqB,CAAA;YAC3C,MAAM,KAAK,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,aAAa,CAAC,KAAK,CAAA;YAC5H,IAAI,KAAK,IAAI,IAAI,EAAE;gBACjB,OAAO,IAAI,+BAAc,CAAC,aAAa,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;aAClE;iBAAM;gBACL,OAAO,IAAI,6CAAqB,CAAC,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,CAAA;aAChF;SACF;QAED,KAAK,WAAW;YACd,OAAO,IAAI,qCAAiB,CAAC,IAAwB,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;QAEjF,KAAK,QAAQ;YACX,OAAO,IAAI,+BAAc,CAAC,IAAqB,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;QAE3E,KAAK,IAAI,CAAC;QACV,KAAK,QAAQ;YACX,OAAO,IAAI,iCAAe,CACxB;gBACE,QAAQ,EAAE,SAAS;gBACnB,GAAG,EAAE,+CAAwB,CAAC,IAAI,CAAC;gBACnC,OAAO,EAAG,IAAsB,CAAC,OAAO,IAAI,IAAI;aACjD,EACD,OAAO,EACP;gBACE,GAAG,cAAc;gBACjB,oEAAoE;gBACpE,yBAAyB,EAAE,KAAK;aACjC,CACF,CAAA;QAEH,KAAK,SAAS,CAAC,CAAC;YACd,MAAM,OAAO,GAAG,IAA4B,CAAA;YAC5C,OAAO,IAAI,iCAAe,CAAC,OAAO,EAAE,OAAO,EAAE;gBAC3C,GAAG,cAAc;gBACjB,yBAAyB,EAAE,OAAO,CAAC,uBAAuB,KAAK,KAAK,IAAI,sCAAsC,CAAC,OAAO,CAAC,GAAG,CAAC;aAC5H,CAAC,CAAA;SACH;QAED,KAAK,QAAQ,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,IAA4B,CAAA;YAC5C,MAAM,WAAW,GAAG,OAAO,CAAC,cAAc,CAAA;YAC1C,IAAI,CAAC,WAAW,EAAE;gBAChB,MAAM,+BAAQ,CAAC,+BAA+B,EAAE,4CAA4C,CAAC,CAAA;aAC9F;YACD,OAAO,IAAI,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC,CAAA;SACzD;QAED;YACE,MAAM,+BAAQ,CAAC,yBAAyB,QAAQ,EAAE,EAAE,kCAAkC,CAAC,CAAA;KAC1F;AACH,CAAC;AA5DD,oCA4DC","sourcesContent":["import {\n AllPublishOptions,\n BaseS3Options,\n BitbucketOptions,\n CustomPublishOptions,\n GenericServerOptions,\n getS3LikeProviderBaseUrl,\n GithubOptions,\n KeygenOptions,\n newError,\n PublishConfiguration,\n} from \"builder-util-runtime\"\nimport { AppUpdater } from \"./AppUpdater\"\nimport { BitbucketProvider } from \"./providers/BitbucketProvider\"\nimport { GenericProvider } from \"./providers/GenericProvider\"\nimport { GitHubProvider } from \"./providers/GitHubProvider\"\nimport { KeygenProvider } from \"./providers/KeygenProvider\"\nimport { PrivateGitHubProvider } from \"./providers/PrivateGitHubProvider\"\nimport { Provider, ProviderRuntimeOptions } from \"./providers/Provider\"\n\nexport function isUrlProbablySupportMultiRangeRequests(url: string): boolean {\n return !url.includes(\"s3.amazonaws.com\")\n}\n\nexport function createClient(data: PublishConfiguration | AllPublishOptions, updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions): Provider<any> {\n // noinspection SuspiciousTypeOfGuard\n if (typeof data === \"string\") {\n throw newError(\"Please pass PublishConfiguration object\", \"ERR_UPDATER_INVALID_PROVIDER_CONFIGURATION\")\n }\n\n const provider = data.provider\n switch (provider) {\n case \"github\": {\n const githubOptions = data as GithubOptions\n const token = (githubOptions.private ? process.env[\"GH_TOKEN\"] || process.env[\"GITHUB_TOKEN\"] : null) || githubOptions.token\n if (token == null) {\n return new GitHubProvider(githubOptions, updater, runtimeOptions)\n } else {\n return new PrivateGitHubProvider(githubOptions, updater, token, runtimeOptions)\n }\n }\n\n case \"bitbucket\":\n return new BitbucketProvider(data as BitbucketOptions, updater, runtimeOptions)\n\n case \"keygen\":\n return new KeygenProvider(data as KeygenOptions, updater, runtimeOptions)\n\n case \"s3\":\n case \"spaces\":\n return new GenericProvider(\n {\n provider: \"generic\",\n url: getS3LikeProviderBaseUrl(data),\n channel: (data as BaseS3Options).channel || null,\n },\n updater,\n {\n ...runtimeOptions,\n // https://github.com/minio/minio/issues/5285#issuecomment-350428955\n isUseMultipleRangeRequest: false,\n }\n )\n\n case \"generic\": {\n const options = data as GenericServerOptions\n return new GenericProvider(options, updater, {\n ...runtimeOptions,\n isUseMultipleRangeRequest: options.useMultipleRangeRequest !== false && isUrlProbablySupportMultiRangeRequests(options.url),\n })\n }\n\n case \"custom\": {\n const options = data as CustomPublishOptions\n const constructor = options.updateProvider\n if (!constructor) {\n throw newError(\"Custom provider not specified\", \"ERR_UPDATER_INVALID_PROVIDER_CONFIGURATION\")\n }\n return new constructor(options, updater, runtimeOptions)\n }\n\n default:\n throw newError(`Unsupported provider: ${provider}`, \"ERR_UPDATER_UNSUPPORTED_PROVIDER\")\n }\n}\n"]}
|
|
@@ -22,7 +22,7 @@ class BaseGitHubProvider extends Provider_1.Provider {
|
|
|
22
22
|
computeGithubBasePath(result) {
|
|
23
23
|
// https://github.com/electron-userland/electron-builder/issues/1903#issuecomment-320881211
|
|
24
24
|
const host = this.options.host;
|
|
25
|
-
return host
|
|
25
|
+
return host !== null && host !== "github.com" && host !== "api.github.com" ? `/api/v3${result}` : result;
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
exports.BaseGitHubProvider = BaseGitHubProvider;
|
|
@@ -33,6 +33,7 @@ class GitHubProvider extends BaseGitHubProvider {
|
|
|
33
33
|
this.updater = updater;
|
|
34
34
|
}
|
|
35
35
|
async getLatestVersion() {
|
|
36
|
+
var _a, _b, _c, _d;
|
|
36
37
|
const cancellationToken = new builder_util_runtime_1.CancellationToken();
|
|
37
38
|
const feedXml = (await this.httpRequest(util_1.newUrlFromBase(`${this.basePath}.atom`, this.baseUrl), {
|
|
38
39
|
accept: "application/xml, application/atom+xml, text/xml, */*",
|
|
@@ -40,11 +41,34 @@ class GitHubProvider extends BaseGitHubProvider {
|
|
|
40
41
|
const feed = builder_util_runtime_1.parseXml(feedXml);
|
|
41
42
|
// noinspection TypeScriptValidateJSTypes
|
|
42
43
|
let latestRelease = feed.element("entry", false, `No published versions on GitHub`);
|
|
43
|
-
let tag;
|
|
44
|
+
let tag = null;
|
|
44
45
|
try {
|
|
45
46
|
if (this.updater.allowPrerelease) {
|
|
46
|
-
|
|
47
|
-
|
|
47
|
+
const currentChannel = ((_a = this.updater) === null || _a === void 0 ? void 0 : _a.channel) || String((_b = semver.prerelease(this.updater.currentVersion)) === null || _b === void 0 ? void 0 : _b[0]) || null;
|
|
48
|
+
for (const element of feed.getElements("entry")) {
|
|
49
|
+
// noinspection TypeScriptValidateJSTypes
|
|
50
|
+
const hrefElement = hrefRegExp.exec(element.element("link").attribute("href"));
|
|
51
|
+
// If this is null then something is wrong and skip this release
|
|
52
|
+
if (hrefElement === null)
|
|
53
|
+
continue;
|
|
54
|
+
// This Release's Tag
|
|
55
|
+
const hrefTag = hrefElement[1];
|
|
56
|
+
//Get Channel from this release's tag
|
|
57
|
+
const hrefChannel = ((_c = semver.prerelease(hrefTag)) === null || _c === void 0 ? void 0 : _c[0]) || null;
|
|
58
|
+
const shouldFetchVersion = !currentChannel || ["alpha", "beta"].includes(currentChannel);
|
|
59
|
+
const isCustomChannel = !["alpha", "beta"].includes(String(hrefChannel));
|
|
60
|
+
// Allow moving from alpha to beta but not down
|
|
61
|
+
const channelMismatch = currentChannel === "beta" && hrefChannel === "alpha";
|
|
62
|
+
if (shouldFetchVersion && !isCustomChannel && !channelMismatch) {
|
|
63
|
+
tag = hrefTag;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
const isNextPreRelease = hrefChannel && hrefChannel === currentChannel;
|
|
67
|
+
if (isNextPreRelease) {
|
|
68
|
+
tag = hrefTag;
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
48
72
|
}
|
|
49
73
|
else {
|
|
50
74
|
tag = await this.getLatestTagName(cancellationToken);
|
|
@@ -63,18 +87,35 @@ class GitHubProvider extends BaseGitHubProvider {
|
|
|
63
87
|
if (tag == null) {
|
|
64
88
|
throw builder_util_runtime_1.newError(`No published versions on GitHub`, "ERR_UPDATER_NO_PUBLISHED_VERSIONS");
|
|
65
89
|
}
|
|
66
|
-
const channelFile = util_1.getChannelFilename(this.getDefaultChannelName());
|
|
67
|
-
const channelFileUrl = util_1.newUrlFromBase(this.getBaseDownloadPath(tag, channelFile), this.baseUrl);
|
|
68
|
-
const requestOptions = this.createRequestOptions(channelFileUrl);
|
|
69
90
|
let rawData;
|
|
91
|
+
let channelFile = "";
|
|
92
|
+
let channelFileUrl = "";
|
|
93
|
+
const fetchData = async (channelName) => {
|
|
94
|
+
channelFile = util_1.getChannelFilename(channelName);
|
|
95
|
+
channelFileUrl = util_1.newUrlFromBase(this.getBaseDownloadPath(String(tag), channelFile), this.baseUrl);
|
|
96
|
+
const requestOptions = this.createRequestOptions(channelFileUrl);
|
|
97
|
+
try {
|
|
98
|
+
return (await this.executor.request(requestOptions, cancellationToken));
|
|
99
|
+
}
|
|
100
|
+
catch (e) {
|
|
101
|
+
if (e instanceof builder_util_runtime_1.HttpError && e.statusCode === 404) {
|
|
102
|
+
throw builder_util_runtime_1.newError(`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}`, "ERR_UPDATER_CHANNEL_FILE_NOT_FOUND");
|
|
103
|
+
}
|
|
104
|
+
throw e;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
70
107
|
try {
|
|
71
|
-
|
|
108
|
+
const channel = this.updater.allowPrerelease ? this.getCustomChannelName(String(((_d = semver.prerelease(tag)) === null || _d === void 0 ? void 0 : _d[0]) || "latest")) : this.getDefaultChannelName();
|
|
109
|
+
rawData = await fetchData(channel);
|
|
72
110
|
}
|
|
73
111
|
catch (e) {
|
|
74
|
-
if (
|
|
75
|
-
|
|
112
|
+
if (this.updater.allowPrerelease) {
|
|
113
|
+
// Allow fallback to `latest.yml`
|
|
114
|
+
rawData = await fetchData(this.getDefaultChannelName());
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
throw e;
|
|
76
118
|
}
|
|
77
|
-
throw e;
|
|
78
119
|
}
|
|
79
120
|
const result = Provider_1.parseUpdateInfo(rawData, channelFile, channelFileUrl);
|
|
80
121
|
if (result.releaseName == null) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GitHubProvider.js","sourceRoot":"","sources":["../../src/providers/GitHubProvider.ts"],"names":[],"mappings":";;;AAAA,+DAAwJ;AACxJ,iCAAgC;AAChC,6BAAyB;AAGzB,kCAAwE;AACxE,yCAA4F;AAE5F,MAAM,UAAU,GAAG,iBAAiB,CAAA;AAKpC,MAAsB,kBAAyC,SAAQ,mBAAW;IAKhF,YAAyC,OAAsB,EAAE,WAAmB,EAAE,cAAsC;QAC1H,KAAK,CAAC;YACJ,GAAG,cAAc;YACjB,4BAA4B;YAC5B,yBAAyB,EAAE,KAAK;SACjC,CAAC,CAAA;QALqC,YAAO,GAAP,OAAO,CAAe;QAO7D,IAAI,CAAC,OAAO,GAAG,iBAAU,CAAC,gCAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,CAAA;QAC1D,MAAM,OAAO,GAAG,WAAW,KAAK,YAAY,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAA;QAC7E,IAAI,CAAC,UAAU,GAAG,iBAAU,CAAC,gCAAS,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAA;IAC3D,CAAC;IAES,qBAAqB,CAAC,MAAc;QAC5C,2FAA2F;QAC3F,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAA;QAC9B,OAAO,IAAI,IAAI,IAAI,IAAI,IAAI,KAAK,YAAY,IAAI,IAAI,KAAK,gBAAgB,CAAC,CAAC,CAAC,UAAU,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;IACzG,CAAC;CACF;AAtBD,gDAsBC;AAED,MAAa,cAAe,SAAQ,kBAAoC;IACtE,YAA+B,OAAsB,EAAmB,OAAmB,EAAE,cAAsC;QACjI,KAAK,CAAC,OAAO,EAAE,YAAY,EAAE,cAAc,CAAC,CAAA;QADf,YAAO,GAAP,OAAO,CAAe;QAAmB,YAAO,GAAP,OAAO,CAAY;IAE3F,CAAC;IAED,KAAK,CAAC,gBAAgB;QACpB,MAAM,iBAAiB,GAAG,IAAI,wCAAiB,EAAE,CAAA;QAEjD,MAAM,OAAO,GAAW,CAAC,MAAM,IAAI,CAAC,WAAW,CAC7C,qBAAc,CAAC,GAAG,IAAI,CAAC,QAAQ,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,EACrD;YACE,MAAM,EAAE,sDAAsD;SAC/D,EACD,iBAAiB,CAClB,CAAE,CAAA;QAEH,MAAM,IAAI,GAAG,+BAAQ,CAAC,OAAO,CAAC,CAAA;QAC9B,yCAAyC;QACzC,IAAI,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,EAAE,iCAAiC,CAAC,CAAA;QACnF,IAAI,GAAkB,CAAA;QACtB,IAAI;YACF,IAAI,IAAI,CAAC,OAAO,CAAC,eAAe,EAAE;gBAChC,yCAAyC;gBACzC,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAE,CAAC,CAAC,CAAC,CAAA;aAC3E;iBAAM;gBACL,GAAG,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,CAAA;gBACpD,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;oBAC/C,yCAAyC;oBACzC,IAAI,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAE,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE;wBAC1E,aAAa,GAAG,OAAO,CAAA;wBACvB,MAAK;qBACN;iBACF;aACF;SACF;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,+BAAQ,CAAC,+BAA+B,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,YAAY,OAAO,EAAE,EAAE,kCAAkC,CAAC,CAAA;SAC7H;QAED,IAAI,GAAG,IAAI,IAAI,EAAE;YACf,MAAM,+BAAQ,CAAC,iCAAiC,EAAE,mCAAmC,CAAC,CAAA;SACvF;QAED,MAAM,WAAW,GAAG,yBAAkB,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC,CAAA;QACpE,MAAM,cAAc,GAAG,qBAAc,CAAC,IAAI,CAAC,mBAAmB,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QAC/F,MAAM,cAAc,GAAG,IAAI,CAAC,oBAAoB,CAAC,cAAc,CAAC,CAAA;QAChE,IAAI,OAAe,CAAA;QACnB,IAAI;YACF,OAAO,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,cAAc,EAAE,iBAAiB,CAAC,CAAE,CAAA;SAC5E;QAAC,OAAO,CAAC,EAAE;YACV,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,IAAI,CAAC,YAAY,gCAAS,IAAI,CAAC,CAAC,UAAU,KAAK,GAAG,EAAE;gBACnF,MAAM,+BAAQ,CAAC,eAAe,WAAW,qCAAqC,cAAc,MAAM,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,oCAAoC,CAAC,CAAA;aAChK;YACD,MAAM,CAAC,CAAA;SACR;QAED,MAAM,MAAM,GAAG,0BAAe,CAAC,OAAO,EAAE,WAAW,EAAE,cAAc,CAAC,CAAA;QACpE,IAAI,MAAM,CAAC,WAAW,IAAI,IAAI,EAAE;YAC9B,MAAM,CAAC,WAAW,GAAG,aAAa,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAA;SAChE;QAED,IAAI,MAAM,CAAC,YAAY,IAAI,IAAI,EAAE;YAC/B,MAAM,CAAC,YAAY,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,EAAE,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,EAAE,aAAa,CAAC,CAAA;SACxH;QACD,OAAO;YACL,GAAG,EAAE,GAAG;YACR,GAAG,MAAM;SACV,CAAA;IACH,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,iBAAoC;QACjE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAA;QAC5B,sFAAsF;QACtF,MAAM,GAAG,GACP,OAAO,CAAC,IAAI,IAAI,IAAI,IAAI,OAAO,CAAC,IAAI,KAAK,YAAY;YACnD,CAAC,CAAC,qBAAc,CAAC,GAAG,IAAI,CAAC,QAAQ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC;YACzD,CAAC,CAAC,IAAI,SAAG,CAAC,GAAG,IAAI,CAAC,qBAAqB,CAAC,UAAU,OAAO,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,WAAW,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAA;QAC1H,IAAI;YACF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,iBAAiB,CAAC,CAAA;YAC9F,IAAI,OAAO,IAAI,IAAI,EAAE;gBACnB,OAAO,IAAI,CAAA;aACZ;YAED,MAAM,WAAW,GAAsB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;YAC1D,OAAO,WAAW,CAAC,QAAQ,CAAA;SAC5B;QAAC,OAAO,CAAC,EAAE;YACV,MAAM,+BAAQ,CAAC,4CAA4C,GAAG,iDAAiD,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,sCAAsC,CAAC,CAAA;SAC/K;IACH,CAAC;IAED,IAAY,QAAQ;QAClB,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,WAAW,CAAA;IAC/D,CAAC;IAED,YAAY,CAAC,UAA4B;QACvC,yDAAyD;QACzD,OAAO,uBAAY,CAAC,UAAU,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAA;IACpH,CAAC;IAEO,mBAAmB,CAAC,GAAW,EAAE,QAAgB;QACvD,OAAO,GAAG,IAAI,CAAC,QAAQ,aAAa,GAAG,IAAI,QAAQ,EAAE,CAAA;IACvD,CAAC;CACF;AArGD,wCAqGC;AAMD,SAAS,YAAY,CAAC,MAAgB;IACpC,MAAM,MAAM,GAAG,MAAM,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAA;IACpD,+DAA+D;IAC/D,OAAO,MAAM,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAA;AAC/C,CAAC;AAED,SAAgB,mBAAmB,CAAC,cAA6B,EAAE,eAAwB,EAAE,IAAc,EAAE,aAAkB;IAC7H,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,YAAY,CAAC,aAAa,CAAC,CAAA;KACnC;IAED,MAAM,YAAY,GAA2B,EAAE,CAAA;IAC/C,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE;QAC/C,yCAAyC;QACzC,MAAM,cAAc,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAE,CAAC,CAAC,CAAC,CAAA;QAC9F,IAAI,MAAM,CAAC,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC,EAAE;YAC7C,YAAY,CAAC,IAAI,CAAC;gBAChB,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,YAAY,CAAC,OAAO,CAAC;aAC5B,CAAC,CAAA;SACH;KACF;IACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC,CAAA;AAC3E,CAAC;AAjBD,kDAiBC","sourcesContent":["import { CancellationToken, GithubOptions, githubUrl, HttpError, newError, parseXml, ReleaseNoteInfo, UpdateInfo, XElement } from \"builder-util-runtime\"\nimport * as semver from \"semver\"\nimport { URL } from \"url\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { ResolvedUpdateFileInfo } from \"../main\"\nimport { getChannelFilename, newBaseUrl, newUrlFromBase } from \"../util\"\nimport { parseUpdateInfo, Provider, ProviderRuntimeOptions, resolveFiles } from \"./Provider\"\n\nconst hrefRegExp = /\\/tag\\/([^/]+)$/\n\ninterface GithubUpdateInfo extends UpdateInfo {\n tag: string\n}\nexport abstract class BaseGitHubProvider<T extends UpdateInfo> extends Provider<T> {\n // so, we don't need to parse port (because node http doesn't support host as url does)\n protected readonly baseUrl: URL\n protected readonly baseApiUrl: URL\n\n protected constructor(protected readonly options: GithubOptions, defaultHost: string, runtimeOptions: ProviderRuntimeOptions) {\n super({\n ...runtimeOptions,\n /* because GitHib uses S3 */\n isUseMultipleRangeRequest: false,\n })\n\n this.baseUrl = newBaseUrl(githubUrl(options, defaultHost))\n const apiHost = defaultHost === \"github.com\" ? \"api.github.com\" : defaultHost\n this.baseApiUrl = newBaseUrl(githubUrl(options, apiHost))\n }\n\n protected computeGithubBasePath(result: string): string {\n // https://github.com/electron-userland/electron-builder/issues/1903#issuecomment-320881211\n const host = this.options.host\n return host != null && host !== \"github.com\" && host !== \"api.github.com\" ? `/api/v3${result}` : result\n }\n}\n\nexport class GitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {\n constructor(protected readonly options: GithubOptions, private readonly updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions) {\n super(options, \"github.com\", runtimeOptions)\n }\n\n async getLatestVersion(): Promise<GithubUpdateInfo> {\n const cancellationToken = new CancellationToken()\n\n const feedXml: string = (await this.httpRequest(\n newUrlFromBase(`${this.basePath}.atom`, this.baseUrl),\n {\n accept: \"application/xml, application/atom+xml, text/xml, */*\",\n },\n cancellationToken\n ))!\n\n const feed = parseXml(feedXml)\n // noinspection TypeScriptValidateJSTypes\n let latestRelease = feed.element(\"entry\", false, `No published versions on GitHub`)\n let tag: string | null\n try {\n if (this.updater.allowPrerelease) {\n // noinspection TypeScriptValidateJSTypes\n tag = hrefRegExp.exec(latestRelease.element(\"link\").attribute(\"href\"))![1]\n } else {\n tag = await this.getLatestTagName(cancellationToken)\n for (const element of feed.getElements(\"entry\")) {\n // noinspection TypeScriptValidateJSTypes\n if (hrefRegExp.exec(element.element(\"link\").attribute(\"href\"))![1] === tag) {\n latestRelease = element\n break\n }\n }\n }\n } catch (e) {\n throw newError(`Cannot parse releases feed: ${e.stack || e.message},\\nXML:\\n${feedXml}`, \"ERR_UPDATER_INVALID_RELEASE_FEED\")\n }\n\n if (tag == null) {\n throw newError(`No published versions on GitHub`, \"ERR_UPDATER_NO_PUBLISHED_VERSIONS\")\n }\n\n const channelFile = getChannelFilename(this.getDefaultChannelName())\n const channelFileUrl = newUrlFromBase(this.getBaseDownloadPath(tag, channelFile), this.baseUrl)\n const requestOptions = this.createRequestOptions(channelFileUrl)\n let rawData: string\n try {\n rawData = (await this.executor.request(requestOptions, cancellationToken))!\n } catch (e) {\n if (!this.updater.allowPrerelease && e instanceof HttpError && e.statusCode === 404) {\n throw newError(`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n throw e\n }\n\n const result = parseUpdateInfo(rawData, channelFile, channelFileUrl)\n if (result.releaseName == null) {\n result.releaseName = latestRelease.elementValueOrEmpty(\"title\")\n }\n\n if (result.releaseNotes == null) {\n result.releaseNotes = computeReleaseNotes(this.updater.currentVersion, this.updater.fullChangelog, feed, latestRelease)\n }\n return {\n tag: tag,\n ...result,\n }\n }\n\n private async getLatestTagName(cancellationToken: CancellationToken): Promise<string | null> {\n const options = this.options\n // do not use API for GitHub to avoid limit, only for custom host or GitHub Enterprise\n const url =\n options.host == null || options.host === \"github.com\"\n ? newUrlFromBase(`${this.basePath}/latest`, this.baseUrl)\n : new URL(`${this.computeGithubBasePath(`/repos/${options.owner}/${options.repo}/releases`)}/latest`, this.baseApiUrl)\n try {\n const rawData = await this.httpRequest(url, { Accept: \"application/json\" }, cancellationToken)\n if (rawData == null) {\n return null\n }\n\n const releaseInfo: GithubReleaseInfo = JSON.parse(rawData)\n return releaseInfo.tag_name\n } catch (e) {\n throw newError(`Unable to find latest version on GitHub (${url}), please ensure a production release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n private get basePath(): string {\n return `/${this.options.owner}/${this.options.repo}/releases`\n }\n\n resolveFiles(updateInfo: GithubUpdateInfo): Array<ResolvedUpdateFileInfo> {\n // still replace space to - due to backward compatibility\n return resolveFiles(updateInfo, this.baseUrl, p => this.getBaseDownloadPath(updateInfo.tag, p.replace(/ /g, \"-\")))\n }\n\n private getBaseDownloadPath(tag: string, fileName: string): string {\n return `${this.basePath}/download/${tag}/${fileName}`\n }\n}\n\ninterface GithubReleaseInfo {\n readonly tag_name: string\n}\n\nfunction getNoteValue(parent: XElement): string {\n const result = parent.elementValueOrEmpty(\"content\")\n // GitHub reports empty notes as <content>No content.</content>\n return result === \"No content.\" ? \"\" : result\n}\n\nexport function computeReleaseNotes(currentVersion: semver.SemVer, isFullChangelog: boolean, feed: XElement, latestRelease: any): string | Array<ReleaseNoteInfo> | null {\n if (!isFullChangelog) {\n return getNoteValue(latestRelease)\n }\n\n const releaseNotes: Array<ReleaseNoteInfo> = []\n for (const release of feed.getElements(\"entry\")) {\n // noinspection TypeScriptValidateJSTypes\n const versionRelease = /\\/tag\\/v?([^/]+)$/.exec(release.element(\"link\").attribute(\"href\"))![1]\n if (semver.lt(currentVersion, versionRelease)) {\n releaseNotes.push({\n version: versionRelease,\n note: getNoteValue(release),\n })\n }\n }\n return releaseNotes.sort((a, b) => semver.rcompare(a.version, b.version))\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GitHubProvider.js","sourceRoot":"","sources":["../../src/providers/GitHubProvider.ts"],"names":[],"mappings":"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","sourcesContent":["import { CancellationToken, GithubOptions, githubUrl, HttpError, newError, parseXml, ReleaseNoteInfo, UpdateInfo, XElement } from \"builder-util-runtime\"\nimport * as semver from \"semver\"\nimport { URL } from \"url\"\nimport { AppUpdater } from \"../AppUpdater\"\nimport { ResolvedUpdateFileInfo } from \"../main\"\nimport { getChannelFilename, newBaseUrl, newUrlFromBase } from \"../util\"\nimport { parseUpdateInfo, Provider, ProviderRuntimeOptions, resolveFiles } from \"./Provider\"\n\nconst hrefRegExp = /\\/tag\\/([^/]+)$/\n\ninterface GithubUpdateInfo extends UpdateInfo {\n tag: string\n}\nexport abstract class BaseGitHubProvider<T extends UpdateInfo> extends Provider<T> {\n // so, we don't need to parse port (because node http doesn't support host as url does)\n protected readonly baseUrl: URL\n protected readonly baseApiUrl: URL\n\n protected constructor(protected readonly options: GithubOptions, defaultHost: string, runtimeOptions: ProviderRuntimeOptions) {\n super({\n ...runtimeOptions,\n /* because GitHib uses S3 */\n isUseMultipleRangeRequest: false,\n })\n\n this.baseUrl = newBaseUrl(githubUrl(options, defaultHost))\n const apiHost = defaultHost === \"github.com\" ? \"api.github.com\" : defaultHost\n this.baseApiUrl = newBaseUrl(githubUrl(options, apiHost))\n }\n\n protected computeGithubBasePath(result: string): string {\n // https://github.com/electron-userland/electron-builder/issues/1903#issuecomment-320881211\n const host = this.options.host\n return host !== null && host !== \"github.com\" && host !== \"api.github.com\" ? `/api/v3${result}` : result\n }\n}\n\nexport class GitHubProvider extends BaseGitHubProvider<GithubUpdateInfo> {\n constructor(protected readonly options: GithubOptions, private readonly updater: AppUpdater, runtimeOptions: ProviderRuntimeOptions) {\n super(options, \"github.com\", runtimeOptions)\n }\n\n async getLatestVersion(): Promise<GithubUpdateInfo> {\n const cancellationToken = new CancellationToken()\n\n const feedXml: string = (await this.httpRequest(\n newUrlFromBase(`${this.basePath}.atom`, this.baseUrl),\n {\n accept: \"application/xml, application/atom+xml, text/xml, */*\",\n },\n cancellationToken\n ))!\n\n const feed = parseXml(feedXml)\n // noinspection TypeScriptValidateJSTypes\n let latestRelease = feed.element(\"entry\", false, `No published versions on GitHub`)\n let tag: string | null = null\n try {\n if (this.updater.allowPrerelease) {\n const currentChannel = this.updater?.channel || String(semver.prerelease(this.updater.currentVersion)?.[0]) || null\n for (const element of feed.getElements(\"entry\")) {\n // noinspection TypeScriptValidateJSTypes\n const hrefElement = hrefRegExp.exec(element.element(\"link\").attribute(\"href\"))!\n\n // If this is null then something is wrong and skip this release\n if (hrefElement === null) continue\n\n // This Release's Tag\n const hrefTag = hrefElement[1]\n //Get Channel from this release's tag\n const hrefChannel = semver.prerelease(hrefTag)?.[0] || null\n\n const shouldFetchVersion = !currentChannel || [\"alpha\", \"beta\"].includes(currentChannel)\n const isCustomChannel = ![\"alpha\", \"beta\"].includes(String(hrefChannel))\n // Allow moving from alpha to beta but not down\n const channelMismatch = currentChannel === \"beta\" && hrefChannel === \"alpha\"\n\n if (shouldFetchVersion && !isCustomChannel && !channelMismatch) {\n tag = hrefTag\n break\n }\n\n const isNextPreRelease = hrefChannel && hrefChannel === currentChannel\n if (isNextPreRelease) {\n tag = hrefTag\n break\n }\n }\n } else {\n tag = await this.getLatestTagName(cancellationToken)\n for (const element of feed.getElements(\"entry\")) {\n // noinspection TypeScriptValidateJSTypes\n if (hrefRegExp.exec(element.element(\"link\").attribute(\"href\"))![1] === tag) {\n latestRelease = element\n break\n }\n }\n }\n } catch (e) {\n throw newError(`Cannot parse releases feed: ${e.stack || e.message},\\nXML:\\n${feedXml}`, \"ERR_UPDATER_INVALID_RELEASE_FEED\")\n }\n\n if (tag == null) {\n throw newError(`No published versions on GitHub`, \"ERR_UPDATER_NO_PUBLISHED_VERSIONS\")\n }\n\n let rawData: string\n let channelFile = \"\"\n let channelFileUrl: any = \"\"\n const fetchData = async (channelName: string) => {\n channelFile = getChannelFilename(channelName)\n channelFileUrl = newUrlFromBase(this.getBaseDownloadPath(String(tag), channelFile), this.baseUrl)\n const requestOptions = this.createRequestOptions(channelFileUrl)\n try {\n return (await this.executor.request(requestOptions, cancellationToken))!\n } catch (e) {\n if (e instanceof HttpError && e.statusCode === 404) {\n throw newError(`Cannot find ${channelFile} in the latest release artifacts (${channelFileUrl}): ${e.stack || e.message}`, \"ERR_UPDATER_CHANNEL_FILE_NOT_FOUND\")\n }\n throw e\n }\n }\n\n try {\n const channel = this.updater.allowPrerelease ? this.getCustomChannelName(String(semver.prerelease(tag)?.[0] || \"latest\")) : this.getDefaultChannelName()\n rawData = await fetchData(channel)\n } catch (e) {\n if (this.updater.allowPrerelease) {\n // Allow fallback to `latest.yml`\n rawData = await fetchData(this.getDefaultChannelName())\n } else {\n throw e\n }\n }\n\n const result = parseUpdateInfo(rawData, channelFile, channelFileUrl)\n if (result.releaseName == null) {\n result.releaseName = latestRelease.elementValueOrEmpty(\"title\")\n }\n\n if (result.releaseNotes == null) {\n result.releaseNotes = computeReleaseNotes(this.updater.currentVersion, this.updater.fullChangelog, feed, latestRelease)\n }\n return {\n tag: tag,\n ...result,\n }\n }\n\n private async getLatestTagName(cancellationToken: CancellationToken): Promise<string | null> {\n const options = this.options\n // do not use API for GitHub to avoid limit, only for custom host or GitHub Enterprise\n const url =\n options.host == null || options.host === \"github.com\"\n ? newUrlFromBase(`${this.basePath}/latest`, this.baseUrl)\n : new URL(`${this.computeGithubBasePath(`/repos/${options.owner}/${options.repo}/releases`)}/latest`, this.baseApiUrl)\n try {\n const rawData = await this.httpRequest(url, { Accept: \"application/json\" }, cancellationToken)\n if (rawData == null) {\n return null\n }\n\n const releaseInfo: GithubReleaseInfo = JSON.parse(rawData)\n return releaseInfo.tag_name\n } catch (e) {\n throw newError(`Unable to find latest version on GitHub (${url}), please ensure a production release exists: ${e.stack || e.message}`, \"ERR_UPDATER_LATEST_VERSION_NOT_FOUND\")\n }\n }\n\n private get basePath(): string {\n return `/${this.options.owner}/${this.options.repo}/releases`\n }\n\n resolveFiles(updateInfo: GithubUpdateInfo): Array<ResolvedUpdateFileInfo> {\n // still replace space to - due to backward compatibility\n return resolveFiles(updateInfo, this.baseUrl, p => this.getBaseDownloadPath(updateInfo.tag, p.replace(/ /g, \"-\")))\n }\n\n private getBaseDownloadPath(tag: string, fileName: string): string {\n return `${this.basePath}/download/${tag}/${fileName}`\n }\n}\n\ninterface GithubReleaseInfo {\n readonly tag_name: string\n}\n\nfunction getNoteValue(parent: XElement): string {\n const result = parent.elementValueOrEmpty(\"content\")\n // GitHub reports empty notes as <content>No content.</content>\n return result === \"No content.\" ? \"\" : result\n}\n\nexport function computeReleaseNotes(currentVersion: semver.SemVer, isFullChangelog: boolean, feed: XElement, latestRelease: any): string | Array<ReleaseNoteInfo> | null {\n if (!isFullChangelog) {\n return getNoteValue(latestRelease)\n }\n\n const releaseNotes: Array<ReleaseNoteInfo> = []\n for (const release of feed.getElements(\"entry\")) {\n // noinspection TypeScriptValidateJSTypes\n const versionRelease = /\\/tag\\/v?([^/]+)$/.exec(release.element(\"link\").attribute(\"href\"))![1]\n if (semver.lt(currentVersion, versionRelease)) {\n releaseNotes.push({\n version: versionRelease,\n note: getNoteValue(release),\n })\n }\n }\n return releaseNotes.sort((a, b) => semver.rcompare(a.version, b.version))\n}\n"]}
|
|
@@ -37,7 +37,7 @@ function verifySignature(publisherNames, unescapedTempUpdateFile, logger) {
|
|
|
37
37
|
"-InputFormat",
|
|
38
38
|
"None",
|
|
39
39
|
"-Command",
|
|
40
|
-
`Get-AuthenticodeSignature '${tempUpdateFile}' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }`,
|
|
40
|
+
`Get-AuthenticodeSignature -LiteralPath '${tempUpdateFile}' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }`,
|
|
41
41
|
], {
|
|
42
42
|
timeout: 20 * 1000,
|
|
43
43
|
}, (error, stdout, stderr) => {
|
|
@@ -49,10 +49,25 @@ function verifySignature(publisherNames, unescapedTempUpdateFile, logger) {
|
|
|
49
49
|
}
|
|
50
50
|
const data = parseOut(Buffer.from(stdout, "base64").toString("utf-8"));
|
|
51
51
|
if (data.Status === 0) {
|
|
52
|
-
const
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
52
|
+
const subject = builder_util_runtime_1.parseDn(data.SignerCertificate.Subject);
|
|
53
|
+
let match = false;
|
|
54
|
+
for (const name of publisherNames) {
|
|
55
|
+
const dn = builder_util_runtime_1.parseDn(name);
|
|
56
|
+
if (dn.size) {
|
|
57
|
+
// if we have a full DN, compare all values
|
|
58
|
+
const allKeys = Array.from(dn.keys());
|
|
59
|
+
match = allKeys.every(key => {
|
|
60
|
+
return dn.get(key) === subject.get(key);
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
else if (name === subject.get("CN")) {
|
|
64
|
+
logger.warn(`Signature validated using only CN ${name}. Please add your full Distinguished Name (DN) to publisherNames configuration`);
|
|
65
|
+
match = true;
|
|
66
|
+
}
|
|
67
|
+
if (match) {
|
|
68
|
+
resolve(null);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
56
71
|
}
|
|
57
72
|
}
|
|
58
73
|
const result = `publisherNames: ${publisherNames.join(" | ")}, raw info: ` + JSON.stringify(data, (name, value) => (name === "RawData" ? undefined : value), 2);
|
|
@@ -60,7 +75,7 @@ function verifySignature(publisherNames, unescapedTempUpdateFile, logger) {
|
|
|
60
75
|
resolve(result);
|
|
61
76
|
}
|
|
62
77
|
catch (e) {
|
|
63
|
-
logger
|
|
78
|
+
handleError(logger, e, null);
|
|
64
79
|
resolve(null);
|
|
65
80
|
return;
|
|
66
81
|
}
|
|
@@ -101,8 +116,7 @@ function handleError(logger, error, stderr) {
|
|
|
101
116
|
throw error;
|
|
102
117
|
}
|
|
103
118
|
if (stderr) {
|
|
104
|
-
|
|
105
|
-
return;
|
|
119
|
+
throw new Error(`Cannot execute Get-AuthenticodeSignature, stderr: ${stderr}. Failing signature validation due to unknown stderr.`);
|
|
106
120
|
}
|
|
107
121
|
}
|
|
108
122
|
function isOldWin6() {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"windowsExecutableCodeSignatureVerifier.js","sourceRoot":"","sources":["../src/windowsExecutableCodeSignatureVerifier.ts"],"names":[],"mappings":";;;AAAA,+DAA8C;AAC9C,iDAAsD;AACtD,yBAAwB;AAGxB,8DAA8D;AAC9D,kJAAkJ;AAClJ,kEAAkE;AAClE,SAAgB,eAAe,CAAC,cAA6B,EAAE,uBAA+B,EAAE,MAAc;IAC5G,OAAO,IAAI,OAAO,CAAgB,OAAO,CAAC,EAAE;QAC1C,6EAA6E;QAC7E,oDAAoD;QACpD,EAAE;QACF,uCAAuC;QACvC,gBAAgB;QAChB,oEAAoE;QACpE,MAAM;QACN,+FAA+F;QAC/F,wCAAwC;QACxC,EAAE;QACF,iCAAiC;QACjC,2HAA2H;QAC3H,0EAA0E;QAC1E,sEAAsE;QACtE,4EAA4E;QAC5E,EAAE;QACF,0FAA0F;QAC1F,kFAAkF;QAClF,sEAAsE;QACtE,MAAM,cAAc,GAAG,uBAAuB,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;QAEtF,oEAAoE;QACpE,oEAAoE;QACpE,wBAAQ,CACN,gBAAgB,EAChB;YACE,YAAY;YACZ,iBAAiB;YACjB,cAAc;YACd,MAAM;YACN,UAAU;YACV,
|
|
1
|
+
{"version":3,"file":"windowsExecutableCodeSignatureVerifier.js","sourceRoot":"","sources":["../src/windowsExecutableCodeSignatureVerifier.ts"],"names":[],"mappings":"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","sourcesContent":["import { parseDn } from \"builder-util-runtime\"\nimport { execFile, execFileSync } from \"child_process\"\nimport * as os from \"os\"\nimport { Logger } from \"./main\"\n\n// $certificateInfo = (Get-AuthenticodeSignature 'xxx\\yyy.exe'\n// | where {$_.Status.Equals([System.Management.Automation.SignatureStatus]::Valid) -and $_.SignerCertificate.Subject.Contains(\"CN=siemens.com\")})\n// | Out-String ; if ($certificateInfo) { exit 0 } else { exit 1 }\nexport function verifySignature(publisherNames: Array<string>, unescapedTempUpdateFile: string, logger: Logger): Promise<string | null> {\n return new Promise<string | null>(resolve => {\n // Escape quotes and backticks in filenames to prevent user from breaking the\n // arguments and perform a remote command injection.\n //\n // Consider example powershell command:\n // ```powershell\n // Get-AuthenticodeSignature 'C:\\\\path\\\\my-bad-';calc;'filename.exe'\n // ```\n // The above would work expected and find the file name, however, it will also execute `;calc;`\n // command and start the calculator app.\n //\n // From Powershell quoting rules:\n // https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_quoting_rules?view=powershell-7\n // * Double quotes `\"` are treated literally within single-quoted strings;\n // * Single quotes can be escaped by doubling them: 'don''t' -> don't;\n // * Backticks can be escaped by doubling them: 'A backtick (``) character';\n //\n // Also note that at this point the file has already been written to the disk, thus we are\n // guaranteed that the path will not contain any illegal characters like <>:\"/\\|?*\n // https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file\n const tempUpdateFile = unescapedTempUpdateFile.replace(/'/g, \"''\").replace(/`/g, \"``\")\n\n // https://github.com/electron-userland/electron-builder/issues/2421\n // https://github.com/electron-userland/electron-builder/issues/2535\n execFile(\n \"powershell.exe\",\n [\n \"-NoProfile\",\n \"-NonInteractive\",\n \"-InputFormat\",\n \"None\",\n \"-Command\",\n `Get-AuthenticodeSignature -LiteralPath '${tempUpdateFile}' | ConvertTo-Json -Compress | ForEach-Object { [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($_)) }`,\n ],\n {\n timeout: 20 * 1000,\n },\n (error, stdout, stderr) => {\n try {\n if (error != null || stderr) {\n handleError(logger, error, stderr)\n resolve(null)\n return\n }\n\n const data = parseOut(Buffer.from(stdout, \"base64\").toString(\"utf-8\"))\n if (data.Status === 0) {\n const subject = parseDn(data.SignerCertificate.Subject)\n let match = false\n for (const name of publisherNames) {\n const dn = parseDn(name)\n if (dn.size) {\n // if we have a full DN, compare all values\n const allKeys = Array.from(dn.keys())\n match = allKeys.every(key => {\n return dn.get(key) === subject.get(key)\n })\n } else if (name === subject.get(\"CN\")!) {\n logger.warn(`Signature validated using only CN ${name}. Please add your full Distinguished Name (DN) to publisherNames configuration`)\n match = true\n }\n if (match) {\n resolve(null)\n return\n }\n }\n }\n\n const result = `publisherNames: ${publisherNames.join(\" | \")}, raw info: ` + JSON.stringify(data, (name, value) => (name === \"RawData\" ? undefined : value), 2)\n logger.warn(`Sign verification failed, installer signed with incorrect certificate: ${result}`)\n resolve(result)\n } catch (e: any) {\n handleError(logger, e, null)\n resolve(null)\n return\n }\n }\n )\n })\n}\n\nfunction parseOut(out: string): any {\n const data = JSON.parse(out)\n delete data.PrivateKey\n delete data.IsOSBinary\n delete data.SignatureType\n const signerCertificate = data.SignerCertificate\n if (signerCertificate != null) {\n delete signerCertificate.Archived\n delete signerCertificate.Extensions\n delete signerCertificate.Handle\n delete signerCertificate.HasPrivateKey\n // duplicates data.SignerCertificate (contains RawData)\n delete signerCertificate.SubjectName\n }\n delete data.Path\n return data\n}\n\nfunction handleError(logger: Logger, error: Error | null, stderr: string | null): void {\n if (isOldWin6()) {\n logger.warn(\n `Cannot execute Get-AuthenticodeSignature: ${error || stderr}. Ignoring signature validation due to unsupported powershell version. Please upgrade to powershell 3 or higher.`\n )\n return\n }\n\n try {\n execFileSync(\"powershell.exe\", [\"-NoProfile\", \"-NonInteractive\", \"-Command\", \"ConvertTo-Json test\"], { timeout: 10 * 1000 } as any)\n } catch (testError: any) {\n logger.warn(\n `Cannot execute ConvertTo-Json: ${testError.message}. Ignoring signature validation due to unsupported powershell version. Please upgrade to powershell 3 or higher.`\n )\n return\n }\n\n if (error != null) {\n throw error\n }\n\n if (stderr) {\n throw new Error(`Cannot execute Get-AuthenticodeSignature, stderr: ${stderr}. Failing signature validation due to unknown stderr.`)\n }\n}\n\nfunction isOldWin6(): boolean {\n const winVersion = os.release()\n return winVersion.startsWith(\"6.\") && !winVersion.startsWith(\"6.3\")\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,38 +1,39 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
2
|
+
"name": "electron-updater",
|
|
3
|
+
"version": "5.0.0-alpha.2",
|
|
4
|
+
"description": "Cross platform updater for electron applications",
|
|
5
|
+
"main": "out/main.js",
|
|
6
|
+
"author": "Vladimir Krivosheev",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/electron-userland/electron-builder.git",
|
|
11
|
+
"directory": "packages/electron-updater"
|
|
12
|
+
},
|
|
13
|
+
"bugs": "https://github.com/electron-userland/electron-builder/issues",
|
|
14
|
+
"homepage": "https://github.com/electron-userland/electron-builder",
|
|
15
|
+
"files": [
|
|
16
|
+
"out"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@types/semver": "^7.3.6",
|
|
20
|
+
"builder-util-runtime": "9.0.0-alpha.0",
|
|
21
|
+
"fs-extra": "^10.0.0",
|
|
22
|
+
"js-yaml": "^4.1.0",
|
|
23
|
+
"lazy-val": "^1.0.5",
|
|
24
|
+
"lodash.escaperegexp": "^4.1.2",
|
|
25
|
+
"lodash.isequal": "^4.5.0",
|
|
26
|
+
"semver": "^7.3.5"
|
|
27
|
+
},
|
|
28
|
+
"devDependencies": {
|
|
29
|
+
"@types/fs-extra": "9.0.13",
|
|
30
|
+
"@types/js-yaml": "4.0.3",
|
|
31
|
+
"@types/lodash.escaperegexp": "4.1.6",
|
|
32
|
+
"@types/lodash.isequal": "4.5.5"
|
|
33
|
+
},
|
|
34
|
+
"typings": "./out/main.d.ts",
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"tag": "next"
|
|
37
|
+
},
|
|
38
|
+
"readme": "# electron-updater\n\nThis module allows you to automatically update your application. You only need to install this module and write two lines of code!\nTo publish your updates you just need simple file hosting, it does not require a dedicated server.\n\nSee [Auto Update](https://electron.build/auto-update) for more information.\n\nSupported OS:\n - macOS ([Squirrel.Mac](https://github.com/Squirrel/Squirrel.Mac)).\n - Windows (NSIS).\n - Linux (AppImage).\n\n## Credits\n\nThanks to [Evolve Labs](https://www.evolvehq.com) for donating the npm package name.\n"
|
|
39
|
+
}
|