@jsenv/https-local 3.0.7 → 3.1.1

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 (46) hide show
  1. package/README.md +160 -192
  2. package/package.json +10 -30
  3. package/src/certificate_authority.js +111 -110
  4. package/src/certificate_request.js +37 -36
  5. package/src/hosts_file_verif.js +34 -35
  6. package/src/https_local_cli.mjs +74 -0
  7. package/src/internal/authority_file_infos.js +12 -13
  8. package/src/internal/browser_detection.js +4 -4
  9. package/src/internal/certificate_authority_file_urls.js +23 -23
  10. package/src/internal/certificate_data_converter.js +39 -39
  11. package/src/internal/certificate_generator.js +39 -39
  12. package/src/internal/command.js +6 -6
  13. package/src/internal/exec.js +10 -10
  14. package/src/internal/forge.js +3 -3
  15. package/src/internal/hosts/hosts_utils.js +2 -2
  16. package/src/internal/hosts/parse_hosts.js +67 -66
  17. package/src/internal/hosts/read_hosts.js +5 -6
  18. package/src/internal/hosts/write_hosts.js +29 -31
  19. package/src/internal/hosts/write_line_hosts.js +30 -32
  20. package/src/internal/hosts.js +5 -5
  21. package/src/internal/linux/chrome_linux.js +19 -20
  22. package/src/internal/linux/firefox_linux.js +19 -20
  23. package/src/internal/linux/linux.js +8 -8
  24. package/src/internal/linux/linux_trust_store.js +58 -59
  25. package/src/internal/linux/nss_linux.js +20 -21
  26. package/src/internal/mac/chrome_mac.js +15 -16
  27. package/src/internal/mac/firefox_mac.js +20 -21
  28. package/src/internal/mac/mac.js +10 -10
  29. package/src/internal/mac/mac_keychain.js +46 -47
  30. package/src/internal/mac/nss_mac.js +29 -30
  31. package/src/internal/mac/safari.js +2 -2
  32. package/src/internal/memoize.js +14 -14
  33. package/src/internal/nssdb_browser.js +150 -145
  34. package/src/internal/platform.js +6 -6
  35. package/src/internal/search_certificate_in_command_output.js +4 -4
  36. package/src/internal/trust_query.js +4 -4
  37. package/src/internal/unsupported_platform/unsupported_platform.js +5 -5
  38. package/src/internal/validity_formatting.js +32 -32
  39. package/src/internal/windows/chrome_windows.js +26 -27
  40. package/src/internal/windows/edge.js +2 -2
  41. package/src/internal/windows/firefox_windows.js +31 -32
  42. package/src/internal/windows/windows.js +10 -10
  43. package/src/internal/windows/windows_certutil.js +41 -42
  44. package/src/jsenvParameters.js +2 -2
  45. package/src/main.js +5 -8
  46. package/src/validity_duration.js +12 -12
@@ -1,17 +1,16 @@
1
- import { readFile, writeFile, removeEntry } from "@jsenv/filesystem"
2
- import { UNICODE, createLogger, createDetailedMessage } from "@jsenv/log"
3
-
4
- import { forge } from "./internal/forge.js"
5
- import { getAuthorityFileInfos } from "./internal/authority_file_infos.js"
6
- import { attributeDescriptionFromAttributeArray } from "./internal/certificate_data_converter.js"
1
+ import { readFile, removeEntry, writeFile } from "@jsenv/filesystem";
2
+ import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/humanize";
3
+ import { getAuthorityFileInfos } from "./internal/authority_file_infos.js";
4
+ import { attributeDescriptionFromAttributeArray } from "./internal/certificate_data_converter.js";
5
+ import { createAuthorityRootCertificate } from "./internal/certificate_generator.js";
6
+ import { forge } from "./internal/forge.js";
7
+ import { importPlatformMethods } from "./internal/platform.js";
7
8
  import {
8
- formatTimeDelta,
9
9
  formatDuration,
10
- } from "./internal/validity_formatting.js"
11
- import { createAuthorityRootCertificate } from "./internal/certificate_generator.js"
12
- import { importPlatformMethods } from "./internal/platform.js"
13
- import { jsenvParameters } from "./jsenvParameters.js"
14
- import { verifyRootCertificateValidityDuration } from "./validity_duration.js"
10
+ formatTimeDelta,
11
+ } from "./internal/validity_formatting.js";
12
+ import { jsenvParameters } from "./jsenvParameters.js";
13
+ import { verifyRootCertificateValidityDuration } from "./validity_duration.js";
15
14
 
16
15
  export const installCertificateAuthority = async ({
17
16
  logLevel,
@@ -29,80 +28,80 @@ export const installCertificateAuthority = async ({
29
28
  if (typeof certificateCommonName !== "string") {
30
29
  throw new TypeError(
31
30
  `certificateCommonName must be a string but received ${certificateCommonName}`,
32
- )
31
+ );
33
32
  }
34
33
  if (typeof certificateValidityDurationInMs !== "number") {
35
34
  throw new TypeError(
36
35
  `certificateValidityDurationInMs must be a number but received ${certificateValidityDurationInMs}`,
37
- )
36
+ );
38
37
  }
39
38
  if (certificateValidityDurationInMs < 1) {
40
39
  throw new TypeError(
41
40
  `certificateValidityDurationInMs must be > 0 but received ${certificateValidityDurationInMs}`,
42
- )
41
+ );
43
42
  }
44
43
 
45
44
  const validityDurationInfo = verifyRootCertificateValidityDuration(
46
45
  certificateValidityDurationInMs,
47
- )
46
+ );
48
47
  if (!validityDurationInfo.ok) {
49
- certificateValidityDurationInMs = validityDurationInfo.maxAllowedValue
48
+ certificateValidityDurationInMs = validityDurationInfo.maxAllowedValue;
50
49
  logger.warn(
51
50
  createDetailedMessage(validityDurationInfo.message, {
52
51
  details: validityDurationInfo.details,
53
52
  }),
54
- )
53
+ );
55
54
  }
56
55
 
57
56
  const {
58
57
  authorityJsonFileInfo,
59
58
  rootCertificateFileInfo,
60
59
  rootCertificatePrivateKeyFileInfo,
61
- } = getAuthorityFileInfos()
62
- const authorityJsonFileUrl = authorityJsonFileInfo.url
63
- const rootCertificateFileUrl = rootCertificateFileInfo.url
64
- const rootPrivateKeyFileUrl = rootCertificatePrivateKeyFileInfo.url
65
- const platformMethods = await importPlatformMethods()
60
+ } = getAuthorityFileInfos();
61
+ const authorityJsonFileUrl = authorityJsonFileInfo.url;
62
+ const rootCertificateFileUrl = rootCertificateFileInfo.url;
63
+ const rootPrivateKeyFileUrl = rootCertificatePrivateKeyFileInfo.url;
64
+ const platformMethods = await importPlatformMethods();
66
65
 
67
66
  const generateRootCertificate = async () => {
68
67
  logger.info(
69
68
  `Generating authority root certificate with a validity of ${formatDuration(
70
69
  certificateValidityDurationInMs,
71
70
  )}...`,
72
- )
71
+ );
73
72
  const { rootCertificateForgeObject, rootCertificatePrivateKeyForgeObject } =
74
73
  await createAuthorityRootCertificate({
75
74
  logger,
76
75
  commonName: certificateCommonName,
77
76
  validityDurationInMs: certificateValidityDurationInMs,
78
77
  serialNumber: 0,
79
- })
78
+ });
80
79
 
81
- const { pki } = forge
80
+ const { pki } = forge;
82
81
  const rootCertificate = pemAsFileContent(
83
82
  pki.certificateToPem(rootCertificateForgeObject),
84
- )
83
+ );
85
84
  const rootCertificatePrivateKey = pemAsFileContent(
86
85
  pki.privateKeyToPem(rootCertificatePrivateKeyForgeObject),
87
- )
86
+ );
88
87
 
89
- await writeFile(rootCertificateFileUrl, rootCertificate)
90
- await writeFile(rootPrivateKeyFileUrl, rootCertificatePrivateKey)
88
+ await writeFile(rootCertificateFileUrl, rootCertificate);
89
+ await writeFile(rootPrivateKeyFileUrl, rootCertificatePrivateKey);
91
90
  await writeFile(
92
91
  authorityJsonFileUrl,
93
92
  JSON.stringify({ serialNumber: 0 }, null, " "),
94
- )
93
+ );
95
94
 
96
95
  logger.info(
97
96
  `${UNICODE.OK} authority root certificate written at ${rootCertificateFileInfo.path}`,
98
- )
97
+ );
99
98
  return {
100
99
  rootCertificateForgeObject,
101
100
  rootCertificatePrivateKeyForgeObject,
102
101
  rootCertificate,
103
102
  rootCertificatePrivateKey,
104
- }
105
- }
103
+ };
104
+ };
106
105
 
107
106
  const generate = async () => {
108
107
  const {
@@ -110,7 +109,7 @@ export const installCertificateAuthority = async ({
110
109
  rootCertificatePrivateKeyForgeObject,
111
110
  rootCertificate,
112
111
  rootCertificatePrivateKey,
113
- } = await generateRootCertificate()
112
+ } = await generateRootCertificate();
114
113
 
115
114
  const trustInfo = await platformMethods.executeTrustQuery({
116
115
  logger,
@@ -120,7 +119,7 @@ export const installCertificateAuthority = async ({
120
119
  certificate: rootCertificate,
121
120
  verb: tryToTrust ? "ADD_TRUST" : "CHECK_TRUST",
122
121
  NSSDynamicInstall,
123
- })
122
+ });
124
123
 
125
124
  return {
126
125
  rootCertificateForgeObject,
@@ -129,8 +128,8 @@ export const installCertificateAuthority = async ({
129
128
  rootCertificatePrivateKey,
130
129
  rootCertificateFilePath: rootCertificateFileInfo.path,
131
130
  trustInfo,
132
- }
133
- }
131
+ };
132
+ };
134
133
 
135
134
  const regenerate = async () => {
136
135
  if (tryToTrust) {
@@ -140,97 +139,97 @@ export const installCertificateAuthority = async ({
140
139
  certificateFileUrl: rootCertificateFileUrl,
141
140
  certificate: rootCertificate,
142
141
  verb: "REMOVE_TRUST",
143
- })
142
+ });
144
143
  }
145
- return generate()
146
- }
144
+ return generate();
145
+ };
147
146
 
148
- logger.debug(`Search existing certificate authority on filesystem...`)
147
+ logger.debug(`Search existing certificate authority on filesystem...`);
149
148
  if (!rootCertificateFileInfo.exists) {
150
149
  logger.debug(
151
150
  `Authority root certificate is not on filesystem at ${rootCertificateFileInfo.path}`,
152
- )
151
+ );
153
152
  logger.info(
154
153
  `${UNICODE.INFO} authority root certificate not found in filesystem`,
155
- )
156
- return generate()
154
+ );
155
+ return generate();
157
156
  }
158
157
  if (!rootCertificatePrivateKeyFileInfo.exists) {
159
158
  logger.debug(
160
159
  `Authority root certificate private key is not on filesystem at ${rootCertificatePrivateKeyFileInfo.path}`,
161
- )
160
+ );
162
161
  logger.info(
163
162
  `${UNICODE.INFO} authority root certificate not found in filesystem`,
164
- )
165
- return generate()
163
+ );
164
+ return generate();
166
165
  }
167
166
  logger.debug(
168
167
  `found authority root certificate files at ${rootCertificateFileInfo.path} and ${rootCertificatePrivateKeyFileInfo.path}`,
169
- )
170
- logger.info(`${UNICODE.OK} authority root certificate found in filesystem`)
168
+ );
169
+ logger.info(`${UNICODE.OK} authority root certificate found in filesystem`);
171
170
 
172
171
  const rootCertificate = await readFile(rootCertificateFileInfo.path, {
173
172
  as: "string",
174
- })
175
- const { pki } = forge
176
- const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
173
+ });
174
+ const { pki } = forge;
175
+ const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate);
177
176
 
178
- logger.info(`Checking certificate validity...`)
177
+ logger.info(`Checking certificate validity...`);
179
178
  const rootCertificateValidityDurationInMs =
180
- getCertificateValidityDurationInMs(rootCertificateForgeObject)
179
+ getCertificateValidityDurationInMs(rootCertificateForgeObject);
181
180
  const rootCertificateValidityRemainingMs = getCertificateRemainingMs(
182
181
  rootCertificateForgeObject,
183
- )
182
+ );
184
183
  if (rootCertificateValidityRemainingMs < 0) {
185
184
  logger.info(
186
185
  `${UNICODE.INFO} certificate expired ${formatTimeDelta(
187
186
  rootCertificateValidityRemainingMs,
188
187
  )}`,
189
- )
190
- return regenerate()
188
+ );
189
+ return regenerate();
191
190
  }
192
191
  const rootCertificateValidityRemainingRatio =
193
- rootCertificateValidityRemainingMs / rootCertificateValidityDurationInMs
192
+ rootCertificateValidityRemainingMs / rootCertificateValidityDurationInMs;
194
193
  if (rootCertificateValidityRemainingRatio < aboutToExpireRatio) {
195
194
  logger.info(
196
195
  `${UNICODE.INFO} certificate will expire ${formatTimeDelta(
197
196
  rootCertificateValidityRemainingMs,
198
197
  )}`,
199
- )
200
- return regenerate()
198
+ );
199
+ return regenerate();
201
200
  }
202
201
  logger.info(
203
202
  `${UNICODE.OK} certificate still valid for ${formatDuration(
204
203
  rootCertificateValidityRemainingMs,
205
204
  )}`,
206
- )
205
+ );
207
206
 
208
- logger.info(`Detect if certificate attributes have changed...`)
207
+ logger.info(`Detect if certificate attributes have changed...`);
209
208
  const rootCertificateDifferences = compareRootCertificateAttributes(
210
209
  rootCertificateForgeObject,
211
210
  {
212
211
  certificateCommonName,
213
212
  certificateValidityDurationInMs,
214
213
  },
215
- )
214
+ );
216
215
  if (rootCertificateDifferences.length) {
217
- const paramNames = Object.keys(rootCertificateDifferences)
216
+ const paramNames = Object.keys(rootCertificateDifferences);
218
217
  logger.info(
219
218
  `${UNICODE.INFO} certificate attributes are outdated: ${paramNames}`,
220
- )
221
- return regenerate()
219
+ );
220
+ return regenerate();
222
221
  }
223
- logger.info(`${UNICODE.OK} certificate attributes are the same`)
222
+ logger.info(`${UNICODE.OK} certificate attributes are the same`);
224
223
 
225
224
  const rootCertificatePrivateKey = await readFile(
226
225
  rootCertificatePrivateKeyFileInfo.path,
227
226
  {
228
227
  as: "string",
229
228
  },
230
- )
229
+ );
231
230
  const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(
232
231
  rootCertificatePrivateKey,
233
- )
232
+ );
234
233
  const trustInfo = await platformMethods.executeTrustQuery({
235
234
  logger,
236
235
  certificateCommonName,
@@ -238,7 +237,7 @@ export const installCertificateAuthority = async ({
238
237
  certificate: rootCertificate,
239
238
  verb: tryToTrust ? "ENSURE_TRUST" : "CHECK_TRUST",
240
239
  NSSDynamicInstall,
241
- })
240
+ });
242
241
 
243
242
  return {
244
243
  rootCertificateForgeObject,
@@ -247,8 +246,8 @@ export const installCertificateAuthority = async ({
247
246
  rootCertificatePrivateKey,
248
247
  rootCertificateFilePath: rootCertificateFileInfo.path,
249
248
  trustInfo,
250
- }
251
- }
249
+ };
250
+ };
252
251
 
253
252
  // const getCertificateValidSinceInMs = (forgeCertificate) => {
254
253
  // const { notBefore } = forgeCertificate.validity
@@ -258,17 +257,17 @@ export const installCertificateAuthority = async ({
258
257
  // }
259
258
 
260
259
  const getCertificateRemainingMs = (certificateForgeObject) => {
261
- const { notAfter } = certificateForgeObject.validity
262
- const nowDate = Date.now()
263
- const remainingMs = notAfter - nowDate
264
- return remainingMs
265
- }
260
+ const { notAfter } = certificateForgeObject.validity;
261
+ const nowDate = Date.now();
262
+ const remainingMs = notAfter - nowDate;
263
+ return remainingMs;
264
+ };
266
265
 
267
266
  const getCertificateValidityDurationInMs = (certificateForgeObject) => {
268
- const { notBefore, notAfter } = certificateForgeObject.validity
269
- const validityDurationInMs = notAfter - notBefore
270
- return validityDurationInMs
271
- }
267
+ const { notBefore, notAfter } = certificateForgeObject.validity;
268
+ const validityDurationInMs = notAfter - notBefore;
269
+ return validityDurationInMs;
270
+ };
272
271
 
273
272
  const compareRootCertificateAttributes = (
274
273
  rootCertificateForgeObject,
@@ -276,28 +275,28 @@ const compareRootCertificateAttributes = (
276
275
  ) => {
277
276
  const attributeDescription = attributeDescriptionFromAttributeArray(
278
277
  rootCertificateForgeObject.subject.attributes,
279
- )
280
- const differences = {}
278
+ );
279
+ const differences = {};
281
280
 
282
- const { commonName } = attributeDescription
281
+ const { commonName } = attributeDescription;
283
282
  if (commonName !== certificateCommonName) {
284
283
  differences.certificateCommonName = {
285
284
  valueFromCertificate: commonName,
286
285
  valueFromParam: certificateCommonName,
287
- }
286
+ };
288
287
  }
289
288
 
290
- const { notBefore, notAfter } = rootCertificateForgeObject.validity
291
- const rootCertificateValidityDurationInMs = notAfter - notBefore
289
+ const { notBefore, notAfter } = rootCertificateForgeObject.validity;
290
+ const rootCertificateValidityDurationInMs = notAfter - notBefore;
292
291
  if (rootCertificateValidityDurationInMs !== certificateValidityDurationInMs) {
293
292
  differences.rootCertificateValidityDurationInMs = {
294
293
  valueFromCertificate: rootCertificateValidityDurationInMs,
295
294
  valueFromParam: certificateValidityDurationInMs,
296
- }
295
+ };
297
296
  }
298
297
 
299
- return differences
300
- }
298
+ return differences;
299
+ };
301
300
 
302
301
  export const uninstallCertificateAuthority = async ({
303
302
  logLevel,
@@ -308,58 +307,60 @@ export const uninstallCertificateAuthority = async ({
308
307
  authorityJsonFileInfo,
309
308
  rootCertificateFileInfo,
310
309
  rootCertificatePrivateKeyFileInfo,
311
- } = getAuthorityFileInfos()
310
+ } = getAuthorityFileInfos();
312
311
 
313
- const filesToRemove = []
312
+ const filesToRemove = [];
314
313
 
315
314
  if (authorityJsonFileInfo.exists) {
316
- filesToRemove.push(authorityJsonFileInfo.url)
315
+ filesToRemove.push(authorityJsonFileInfo.url);
317
316
  }
318
317
  if (rootCertificateFileInfo.exists) {
319
318
  // first untrust the root cert file
320
319
  if (tryToUntrust) {
321
320
  const rootCertificate = await readFile(rootCertificateFileInfo.url, {
322
321
  as: "string",
323
- })
324
- const { pki } = forge
325
- const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
322
+ });
323
+ const { pki } = forge;
324
+ const rootCertificateForgeObject =
325
+ pki.certificateFromPem(rootCertificate);
326
326
  const rootCertificateCommonName = attributeDescriptionFromAttributeArray(
327
327
  rootCertificateForgeObject.subject.attributes,
328
- ).commonName
329
- const { removeCertificateFromTrustStores } = await importPlatformMethods()
328
+ ).commonName;
329
+ const { removeCertificateFromTrustStores } =
330
+ await importPlatformMethods();
330
331
  await removeCertificateFromTrustStores({
331
332
  logger,
332
333
  certificate: rootCertificate,
333
334
  certificateFileUrl: rootCertificateFileInfo.url,
334
335
  certificateCommonName: rootCertificateCommonName,
335
- })
336
+ });
336
337
  }
337
- filesToRemove.push(rootCertificateFileInfo.url)
338
+ filesToRemove.push(rootCertificateFileInfo.url);
338
339
  }
339
340
  if (rootCertificatePrivateKeyFileInfo.exists) {
340
- filesToRemove.push(rootCertificatePrivateKeyFileInfo.url)
341
+ filesToRemove.push(rootCertificatePrivateKeyFileInfo.url);
341
342
  }
342
343
 
343
344
  if (filesToRemove.length) {
344
- logger.info(`Removing certificate authority files...`)
345
+ logger.info(`Removing certificate authority files...`);
345
346
  await Promise.all(
346
347
  filesToRemove.map(async (file) => {
347
- await removeEntry(file)
348
+ await removeEntry(file);
348
349
  }),
349
- )
350
+ );
350
351
  logger.info(
351
352
  `${UNICODE.OK} certificate authority files removed from filesystem`,
352
- )
353
+ );
353
354
  }
354
- }
355
+ };
355
356
 
356
357
  const pemAsFileContent = (pem) => {
357
358
  if (process.platform === "win32") {
358
- return pem
359
+ return pem;
359
360
  }
360
361
  // prefer \n when writing pem into files
361
- return pem.replace(/\r\n/g, "\n")
362
- }
362
+ return pem.replace(/\r\n/g, "\n");
363
+ };
363
364
 
364
365
  /*
365
366
  * The root certificate files can be "hard" to find because
@@ -1,15 +1,14 @@
1
- import { readFileSync } from "node:fs"
2
- import { writeFileSync } from "@jsenv/filesystem"
3
- import { UNICODE, createLogger, createDetailedMessage } from "@jsenv/log"
4
-
5
- import { forge } from "./internal/forge.js"
1
+ import { writeFileSync } from "@jsenv/filesystem";
2
+ import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/humanize";
3
+ import { readFileSync } from "node:fs";
4
+ import { getAuthorityFileInfos } from "./internal/authority_file_infos.js";
5
+ import { requestCertificateFromAuthority } from "./internal/certificate_generator.js";
6
+ import { forge } from "./internal/forge.js";
7
+ import { formatDuration } from "./internal/validity_formatting.js";
6
8
  import {
7
9
  createValidityDurationOfXDays,
8
10
  verifyServerCertificateValidityDuration,
9
- } from "./validity_duration.js"
10
- import { getAuthorityFileInfos } from "./internal/authority_file_infos.js"
11
- import { requestCertificateFromAuthority } from "./internal/certificate_generator.js"
12
- import { formatDuration } from "./internal/validity_formatting.js"
11
+ } from "./validity_duration.js";
13
12
 
14
13
  export const requestCertificate = ({
15
14
  logLevel,
@@ -22,66 +21,68 @@ export const requestCertificate = ({
22
21
  if (typeof validityDurationInMs !== "number") {
23
22
  throw new TypeError(
24
23
  `validityDurationInMs must be a number but received ${validityDurationInMs}`,
25
- )
24
+ );
26
25
  }
27
26
  if (validityDurationInMs < 1) {
28
27
  throw new TypeError(
29
28
  `validityDurationInMs must be > 0 but received ${validityDurationInMs}`,
30
- )
29
+ );
31
30
  }
32
31
  const validityDurationInfo =
33
- verifyServerCertificateValidityDuration(validityDurationInMs)
32
+ verifyServerCertificateValidityDuration(validityDurationInMs);
34
33
  if (!validityDurationInfo.ok) {
35
- validityDurationInMs = validityDurationInfo.maxAllowedValue
34
+ validityDurationInMs = validityDurationInfo.maxAllowedValue;
36
35
  logger.warn(
37
36
  createDetailedMessage(validityDurationInfo.message, {
38
37
  details: validityDurationInfo.details,
39
38
  }),
40
- )
39
+ );
41
40
  }
42
41
 
43
42
  const {
44
43
  authorityJsonFileInfo,
45
44
  rootCertificateFileInfo,
46
45
  rootCertificatePrivateKeyFileInfo,
47
- } = getAuthorityFileInfos()
46
+ } = getAuthorityFileInfos();
48
47
  if (!rootCertificateFileInfo.exists) {
49
48
  throw new Error(
50
- `Certificate authority not found, "installCertificateAuthority" must be called before "requestServerCertificate"`,
51
- )
49
+ `Certificate authority not found, "installCertificateAuthority" must be called before "requestServerCertificate".
50
+ --- Suggested command to run ---
51
+ npx @jsenv/https-local install --trust`,
52
+ );
52
53
  }
53
54
  if (!rootCertificatePrivateKeyFileInfo.exists) {
54
- throw new Error(`Cannot find authority root certificate private key`)
55
+ throw new Error(`Cannot find authority root certificate private key`);
55
56
  }
56
57
  if (!authorityJsonFileInfo.exists) {
57
- throw new Error(`Cannot find authority json file`)
58
+ throw new Error(`Cannot find authority json file`);
58
59
  }
59
60
 
60
- logger.debug(`Restoring certificate authority from filesystem...`)
61
- const { pki } = forge
61
+ logger.debug(`Restoring certificate authority from filesystem...`);
62
+ const { pki } = forge;
62
63
  const rootCertificate = String(
63
64
  readFileSync(new URL(rootCertificateFileInfo.url)),
64
- )
65
+ );
65
66
  const rootCertificatePrivateKey = String(
66
67
  readFileSync(new URL(rootCertificatePrivateKeyFileInfo.url)),
67
- )
68
+ );
68
69
  const certificateAuthorityData = JSON.parse(
69
70
  String(readFileSync(new URL(authorityJsonFileInfo.url))),
70
- )
71
- const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
71
+ );
72
+ const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate);
72
73
  const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(
73
74
  rootCertificatePrivateKey,
74
- )
75
- logger.debug(`${UNICODE.OK} certificate authority restored from filesystem`)
75
+ );
76
+ logger.debug(`${UNICODE.OK} certificate authority restored from filesystem`);
76
77
 
77
78
  const serverCertificateSerialNumber =
78
- certificateAuthorityData.serialNumber + 1
79
+ certificateAuthorityData.serialNumber + 1;
79
80
  writeFileSync(
80
81
  authorityJsonFileInfo.url,
81
82
  JSON.stringify({ serialNumber: serverCertificateSerialNumber }, null, " "),
82
- )
83
+ );
83
84
 
84
- logger.debug(`Generating server certificate...`)
85
+ logger.debug(`Generating server certificate...`);
85
86
  const { certificateForgeObject, certificatePrivateKeyForgeObject } =
86
87
  requestCertificateFromAuthority({
87
88
  logger,
@@ -92,22 +93,22 @@ export const requestCertificate = ({
92
93
  altNames,
93
94
  commonName,
94
95
  validityDurationInMs,
95
- })
96
- const serverCertificate = pki.certificateToPem(certificateForgeObject)
96
+ });
97
+ const serverCertificate = pki.certificateToPem(certificateForgeObject);
97
98
  const serverCertificatePrivateKey = pki.privateKeyToPem(
98
99
  certificatePrivateKeyForgeObject,
99
- )
100
+ );
100
101
  logger.debug(
101
102
  `${
102
103
  UNICODE.OK
103
104
  } server certificate generated, it will be valid for ${formatDuration(
104
105
  validityDurationInMs,
105
106
  )}`,
106
- )
107
+ );
107
108
 
108
109
  return {
109
110
  certificate: serverCertificate,
110
111
  privateKey: serverCertificatePrivateKey,
111
112
  rootCertificateFilePath: rootCertificateFileInfo.path,
112
- }
113
- }
113
+ };
114
+ };