electron-incremental-update 0.5.0 → 0.6.0

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/dist/vite.mjs CHANGED
@@ -1,15 +1,15 @@
1
1
  import {
2
- generateRSA,
3
2
  signature
4
- } from "./chunk-SSJ6PDMK.mjs";
3
+ } from "./chunk-VADH6AZA.mjs";
5
4
 
6
5
  // src/vite.ts
7
6
  import { createLogger } from "vite";
8
7
 
9
- // src/build-plugins/asar.ts
8
+ // src/build-plugins/build.ts
10
9
  import { createReadStream, createWriteStream } from "node:fs";
11
10
  import { readFile, rename, writeFile } from "node:fs/promises";
12
11
  import zlib from "node:zlib";
12
+ import { build } from "esbuild";
13
13
  function gzipFile(filePath) {
14
14
  return new Promise((resolve, reject) => {
15
15
  const gzip = zlib.createGzip();
@@ -46,24 +46,20 @@ async function buildAsar({
46
46
  await pack(electronDistPath, asarOutputPath);
47
47
  await gzipFile(asarOutputPath);
48
48
  }
49
- async function generateVersion({
49
+ async function buildVersion({
50
50
  asarOutputPath,
51
51
  versionPath,
52
52
  privateKey,
53
- publicKey,
54
- productName,
53
+ cert,
55
54
  version
56
55
  }) {
57
56
  const buffer = await readFile(`${asarOutputPath}.gz`);
58
57
  await writeFile(versionPath, JSON.stringify({
59
- signature: signature(buffer, privateKey, publicKey, productName),
58
+ signature: signature(buffer, privateKey, cert, version),
60
59
  version,
61
60
  size: buffer.length
62
61
  }, null, 2));
63
62
  }
64
-
65
- // src/build-plugins/entry.ts
66
- import { build } from "esbuild";
67
63
  async function buildEntry({
68
64
  entryPath,
69
65
  entryOutputPath: outfile,
@@ -83,16 +79,35 @@ async function buildEntry({
83
79
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
84
80
  import { dirname } from "node:path";
85
81
  import { EOL } from "node:os";
86
- function generateKey(privateKeyPath, publicKeyPath, length) {
87
- const ret = generateRSA(length);
88
- writeFileSync(privateKeyPath, ret.privateKey);
89
- writeFileSync(publicKeyPath, ret.publicKey);
90
- return ret;
82
+ import { generateKeyPairSync } from "node:crypto";
83
+ import { CertificateSigningRequest } from "@cyyynthia/jscert";
84
+ function generateCert(privateKey) {
85
+ const dn = {
86
+ country: "zh-CN",
87
+ state: "zj",
88
+ locality: "hz",
89
+ organization: "test",
90
+ organizationalUnit: "test unit",
91
+ commonName: "test.test",
92
+ emailAddress: "test@example.com"
93
+ };
94
+ const csr = new CertificateSigningRequest(dn, privateKey, { digest: "sha256" });
95
+ const expiry = new Date(Date.now() + 365 * 864e5);
96
+ return csr.createSelfSignedCertificate(expiry).toPem();
91
97
  }
92
- function writePublicKeyToMain(entryPath, publicKey) {
98
+ function generateKeys(length = 2048) {
99
+ const { privateKey: _key } = generateKeyPairSync("rsa", { modulusLength: length });
100
+ const cert = generateCert(_key);
101
+ const privateKey = _key.export({ type: "pkcs1", format: "pem" });
102
+ return {
103
+ privateKey,
104
+ cert
105
+ };
106
+ }
107
+ function writeCertToMain(entryPath, cert) {
93
108
  const file = readFileSync(entryPath, "utf-8");
94
- const regex = /const SIGNATURE_PUB = ['`][\s\S]*?['`]/;
95
- const replacement = `const SIGNATURE_PUB = \`${publicKey}\``;
109
+ const regex = /const SIGNATURE_CERT = ['`][\s\S]*?['`]/;
110
+ const replacement = `const SIGNATURE_CERT = \`${cert}\``;
96
111
  let replaced = file;
97
112
  const signaturePubExists = regex.test(file);
98
113
  if (signaturePubExists) {
@@ -117,24 +132,26 @@ function writePublicKeyToMain(entryPath, publicKey) {
117
132
  function getKeys({
118
133
  keyLength,
119
134
  privateKeyPath,
120
- publicKeyPath,
135
+ certPath,
121
136
  entryPath
122
137
  }) {
123
138
  const keysDir = dirname(privateKeyPath);
124
139
  !existsSync(keysDir) && mkdirSync(keysDir);
125
- let privateKey, publicKey;
126
- if (!existsSync(privateKeyPath)) {
127
- const keys = generateKey(privateKeyPath, publicKeyPath, keyLength);
140
+ let privateKey, cert;
141
+ if (!existsSync(privateKeyPath) || !existsSync(certPath)) {
142
+ const keys = generateKeys(keyLength);
128
143
  privateKey = keys.privateKey;
129
- publicKey = keys.publicKey;
144
+ cert = keys.cert;
145
+ writeFileSync(privateKeyPath, privateKey);
146
+ writeFileSync(certPath, cert);
130
147
  } else {
131
148
  privateKey = readFileSync(privateKeyPath, "utf-8");
132
- publicKey = readFileSync(publicKeyPath, "utf-8");
149
+ cert = readFileSync(certPath, "utf-8");
133
150
  }
134
- writePublicKeyToMain(entryPath, publicKey);
151
+ writeCertToMain(entryPath, cert);
135
152
  return {
136
153
  privateKey,
137
- publicKey
154
+ cert
138
155
  };
139
156
  }
140
157
 
@@ -152,9 +169,17 @@ function parseOptions(options) {
152
169
  } = paths;
153
170
  const {
154
171
  privateKeyPath = "keys/private.pem",
155
- publicKeyPath = "keys/public.pem",
156
- keyLength = 2048
172
+ certPath = "keys/cert.pem",
173
+ keyLength = 2048,
174
+ certInfo
157
175
  } = keys;
176
+ let {
177
+ subject = {
178
+ commonName: productName,
179
+ organization: `org.${productName}`
180
+ },
181
+ expires = Date.now() + 365 * 864e5
182
+ } = certInfo || {};
158
183
  const buildAsarOption = {
159
184
  version,
160
185
  asarOutputPath,
@@ -168,18 +193,22 @@ function parseOptions(options) {
168
193
  };
169
194
  let buildVersionOption;
170
195
  if (!isCI) {
171
- const { privateKey, publicKey } = getKeys({
196
+ if (typeof expires === "number") {
197
+ expires = new Date(Date.now() + expires);
198
+ }
199
+ const { privateKey, cert } = getKeys({
172
200
  keyLength,
173
201
  privateKeyPath,
174
- publicKeyPath,
175
- entryPath
202
+ certPath,
203
+ entryPath,
204
+ subject,
205
+ expires
176
206
  });
177
207
  buildVersionOption = {
178
208
  version,
179
209
  asarOutputPath,
180
210
  privateKey,
181
- publicKey,
182
- productName,
211
+ cert,
183
212
  versionPath
184
213
  };
185
214
  }
@@ -205,7 +234,7 @@ function vite_default(options) {
205
234
  }
206
235
  log.info("build asar start");
207
236
  await buildAsar(buildAsarOption);
208
- buildVersionOption && await generateVersion(buildVersionOption);
237
+ buildVersionOption && await buildVersion(buildVersionOption);
209
238
  log.info(`build asar end, output to ${asarOutputPath}`);
210
239
  }
211
240
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "electron-incremental-update",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "electron incremental update tools, powered by vite",
5
5
  "scripts": {
6
6
  "build": "tsup",
@@ -61,6 +61,7 @@
61
61
  "vitest": "^0.32.2"
62
62
  },
63
63
  "dependencies": {
64
+ "@cyyynthia/jscert": "^0.1.2",
64
65
  "ci-info": "^3.8.0"
65
66
  }
66
- }
67
+ }
@@ -1,61 +0,0 @@
1
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
- }) : x)(function(x) {
4
- if (typeof require !== "undefined")
5
- return require.apply(this, arguments);
6
- throw new Error('Dynamic require of "' + x + '" is not supported');
7
- });
8
-
9
- // src/crypto.ts
10
- import { constants, createCipheriv, createDecipheriv, createHash, createSign, createVerify, generateKeyPairSync } from "node:crypto";
11
- import { Buffer as Buffer2 } from "node:buffer";
12
- var aesEncode = "base64url";
13
- function generateRSA(length = 2048) {
14
- const pair = generateKeyPairSync("rsa", { modulusLength: length });
15
- const privateKey = pair.privateKey.export({ type: "pkcs1", format: "pem" });
16
- const publicKey = pair.publicKey.export({ type: "pkcs1", format: "pem" });
17
- return {
18
- privateKey,
19
- publicKey
20
- };
21
- }
22
- function encrypt(plainText, key, iv) {
23
- const cipher = createCipheriv("aes-256-cbc", key, iv);
24
- let encrypted = cipher.update(plainText, "utf8", aesEncode);
25
- encrypted += cipher.final(aesEncode);
26
- return encrypted;
27
- }
28
- function decrypt(encryptedText, key, iv) {
29
- const decipher = createDecipheriv("aes-256-cbc", key, iv);
30
- let decrypted = decipher.update(encryptedText, aesEncode, "utf8");
31
- decrypted += decipher.final("utf8");
32
- return decrypted;
33
- }
34
- function generateKey(buffer, str, length) {
35
- str += createHash("md5").update(buffer.map((v, i) => i & length / 4 && v)).digest("hex");
36
- const hash = createHash("SHA256").update(str).digest("binary");
37
- return Buffer2.from(hash).subarray(0, length);
38
- }
39
- function signature(buffer, privateKey, publicKey, name) {
40
- const sig = createSign("RSA-SHA256").update(buffer).sign({
41
- key: privateKey,
42
- padding: constants.RSA_PKCS1_PADDING,
43
- saltLength: constants.RSA_PSS_SALTLEN_DIGEST
44
- }, "base64");
45
- return encrypt(sig, generateKey(buffer, publicKey, 32), generateKey(buffer, name, 16));
46
- }
47
- function verify(buffer, signature2, publicKey, name) {
48
- try {
49
- const sig = decrypt(signature2, generateKey(buffer, publicKey, 32), generateKey(buffer, name, 16));
50
- return createVerify("RSA-SHA256").update(buffer).verify(publicKey, sig, "base64");
51
- } catch (error) {
52
- return false;
53
- }
54
- }
55
-
56
- export {
57
- __require,
58
- generateRSA,
59
- signature,
60
- verify
61
- };