@jsenv/https-local 1.0.0 → 1.0.5

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/README.md CHANGED
@@ -30,7 +30,11 @@ npm install --save-dev @jsenv/https-local
30
30
  *
31
31
  * Read more in https://github.com/jsenv/https-local#installCertificateAuthority
32
32
  */
33
- import { installCertificateAuthority, verifyHostsFile } from "@jsenv/https-local"
33
+
34
+ import {
35
+ installCertificateAuthority,
36
+ verifyHostsFile,
37
+ } from "@jsenv/https-local"
34
38
 
35
39
  await installCertificateAuthority({
36
40
  tryToTrust: true,
@@ -38,13 +42,13 @@ await installCertificateAuthority({
38
42
  })
39
43
  await verifyHostsFile({
40
44
  ipMappings: {
41
- "127.0.0.1": ["localhost", "local.example.com"],
45
+ "127.0.0.1": ["localhost"],
42
46
  },
43
47
  tryToUpdatesHostsFile: true,
44
48
  })
45
49
  ```
46
50
 
47
- 3 - Install certificate authority
51
+ 3 - Run file to install certificate authority with node
48
52
 
49
53
  ```console
50
54
  node ./install_certificate_authority.mjs
@@ -55,7 +59,7 @@ node ./install_certificate_authority.mjs
55
59
  ```js
56
60
  /*
57
61
  * This file uses "@jsenv/https-local" to obtain a certificate used to start a server in https.
58
- * The certificate is valid for 396 days and is issued by a certificate authority trusted on this machine.
62
+ * The certificate is valid for 1 year (396 days) and is issued by a certificate authority trusted on this machine.
59
63
  * If the certificate authority was not installed before executing this file, an error is thrown
60
64
  * explaining that certificate authority must be installed first.
61
65
  *
@@ -65,12 +69,12 @@ node ./install_certificate_authority.mjs
65
69
  *
66
70
  * Read more in https://github.com/jsenv/https-local#requestCertificateForLocalhost
67
71
  */
72
+
68
73
  import { createServer } from "node:https"
69
74
  import { requestCertificateForLocalhost } from "@jsenv/https-local"
70
75
 
71
- const { serverCertificate, serverCertificatePrivateKey } = await requestCertificateForLocalhost({
72
- serverCertificateAltNames: ["localhost", "local.example"],
73
- })
76
+ const { serverCertificate, serverCertificatePrivateKey } =
77
+ await requestCertificateForLocalhost()
74
78
 
75
79
  const server = createServer(
76
80
  {
@@ -91,12 +95,15 @@ server.listen(8080)
91
95
  console.log(`Server listening at https://local.example:8080`)
92
96
  ```
93
97
 
94
- 5 - Start your server
98
+ 5 - Run file to start server with node
95
99
 
96
100
  ```console
97
101
  node ./start_dev_server.mjs
98
102
  ```
99
103
 
104
+ At this stage of the documentation you have a server running in https.
105
+ The rest of the documentation goes into details.
106
+
100
107
  # Certificate expiration
101
108
 
102
109
  The server certificate expires after one year which is the maximum duration allowed by web browsers.
@@ -105,7 +112,7 @@ In the unlikely scenario where your local server is running for more than a year
105
112
 
106
113
  The authority root certificate expires after 20 years which is close to the maximum allowed duration.
107
114
 
108
- In the very unlikely scenario where you are using the same machine for more than 20 years, re-execute [installCertificateAuthority](#installCertificateAuthority) to update certificate authority and restart your server.
115
+ In the very unlikely scenario where you are using the same machine for more than 20 years, re-execute [installCertificateAuthority](#installCertificateAuthority) to update certificate authority then restart your server.
109
116
 
110
117
  # installCertificateAuthority
111
118
 
@@ -118,6 +125,11 @@ import { installCertificateAuthority } from "@jsenv/https-local"
118
125
  await installCertificateAuthority()
119
126
  ```
120
127
 
128
+ By default, trusting authority root certificate is a manual process.
129
+ This manual process is documented in [BenMorel/dev-certificates#Import the CA in your browser](https://github.com/BenMorel/dev-certificates/tree/c10cd68945da772f31815b7a36721ddf848ff3a3#import-the-ca-in-your-browser).
130
+
131
+ Trusting the root certificate can also be done programmatically as explained in [Auto trust](#Auto-trust).
132
+
121
133
  Find below logs written in terminal when this function is executed.
122
134
 
123
135
  <details>
@@ -128,7 +140,7 @@ Find below logs written in terminal when this function is executed.
128
140
 
129
141
  ℹ authority root certificate not found in filesystem
130
142
  Generating authority root certificate with a validity of 20 years...
131
- ✔ authority root certificate written at /Users/dmail/https_localhost/http_localhost_root_certificate.crt
143
+ ✔ authority root certificate written at /Users/dmail/https_local/http_local_root_certificate.crt
132
144
  ℹ You should add root certificate to mac keychain
133
145
  ℹ You should add root certificate to firefox
134
146
  ```
@@ -159,7 +171,7 @@ Check if certificate is in firefox...
159
171
 
160
172
  ℹ authority root certificate not found in filesystem
161
173
  Generating authority root certificate with a validity of 20 years...
162
- ✔ authority root certificate written at /home/dmail/.config/https_localhost/https_localhost_root_certificate.crt
174
+ ✔ authority root certificate written at /home/dmail/.config/https_local/https_local_root_certificate.crt
163
175
  ℹ You should add certificate to linux
164
176
  ℹ You should add certificate to chrome
165
177
  ℹ You should add certificate to firefox
@@ -193,7 +205,7 @@ Check if certificate is in firefox...
193
205
 
194
206
  ℹ authority root certificate not found in filesystem
195
207
  Generating authority root certificate with a validity of 20 years...
196
- ✔ authority root certificate written at C:\Users\Dmail\AppData\Local\https_localhost\https_localhost_root_certificate.crt
208
+ ✔ authority root certificate written at C:\Users\Dmail\AppData\Local\https_local\https_local_root_certificate.crt
197
209
  ℹ You should add certificate to windows
198
210
  ℹ You should add certificate to firefox
199
211
  ```
@@ -216,11 +228,6 @@ Check if certificate is trusted by firefox...
216
228
 
217
229
  </details>
218
230
 
219
- By default, trusting authority root certificate is a manual process.
220
- This manual process is documented in [BenMorel/dev-certificates#Import the CA in your browser](https://github.com/BenMorel/dev-certificates/tree/c10cd68945da772f31815b7a36721ddf848ff3a3#import-the-ca-in-your-browser).
221
-
222
- Trusting the root certificate can also be done programmatically as explained the next part.
223
-
224
231
  ## Auto trust
225
232
 
226
233
  It's possible to trust root certificate programmatically using _tryToTrust_
@@ -241,9 +248,9 @@ await installCertificateAuthority({
241
248
 
242
249
  ℹ authority root certificate not found in filesystem
243
250
  Generating authority root certificate with a validity of 20 years...
244
- ✔ authority root certificate written at /Users/dmail/https_localhost/https_localhost_root_certificate.crt
251
+ ✔ authority root certificate written at /Users/dmail/https_local/https_local_root_certificate.crt
245
252
  Adding certificate to mac keychain...
246
- ❯ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "/Users/dmail/https_localhost/https_localhost_root_certificate.crt"
253
+ ❯ sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "/Users/dmail/https_local/https_local_root_certificate.crt"
247
254
  Password:
248
255
  ✔ certificate added to mac keychain
249
256
  Adding certificate to firefox...
@@ -269,7 +276,7 @@ Check if certificate is in Firefox...
269
276
  </details>
270
277
 
271
278
  <details>
272
- <summary>windows</summary>
279
+ <summary>linux</summary>
273
280
 
274
281
  ```console
275
282
  > node ./install_certificate_authority.mjs
@@ -280,9 +287,9 @@ Checking certificate validity...
280
287
  Detect if certificate attributes have changed...
281
288
  ✔ certificate attributes are the same
282
289
  Check if certificate is in linux...
283
- ℹ certificate in linux is outdated
290
+ ℹ certificate not in linux
284
291
  Adding certificate to linux...
285
- ❯ sudo /bin/cp -f "/home/dmail/.config/https_localhost/https_localhost_root_certificate.crt" /usr/local/share/ca-certificates/https_localhost_root_certificate.crt
292
+ ❯ sudo /bin/cp -f "/home/dmail/.config/https_local/https_local_root_certificate.crt" /usr/local/share/ca-certificates/https_local_root_certificate.crt
286
293
  [sudo] Password for dmail :
287
294
  ❯ sudo update-ca-certificates
288
295
  ✔ certificate added to linux
@@ -329,11 +336,11 @@ Detect if certificate attributes have changed...
329
336
  ✔ certificate attributes are the same
330
337
  Check if certificate is trusted by windows...
331
338
  ℹ certificate not trusted by windows
332
- Check if certificate is trusted by firefox...
333
- ℹ unable to detect if certificate is trusted by firefox (not implemented on windows)
334
339
  Adding certificate to windows...
335
- ❯ certutil -addstore -user root C:\Users\Dmail\AppData\Local\https_localhost\https_localhost_root_certificate.crt
340
+ ❯ certutil -addstore -user root C:\Users\Dmail\AppData\Local\https_local\https_local_root_certificate.crt
336
341
  ✔ certificate added to windows
342
+ Check if certificate is trusted by firefox...
343
+ ℹ unable to detect if certificate is trusted by firefox (not implemented on windows)
337
344
  ```
338
345
 
339
346
  _second execution logs_
@@ -354,16 +361,33 @@ Check if certificate is trusted by firefox...
354
361
 
355
362
  </details>
356
363
 
364
+ # requestCertificateForLocalhost
365
+
366
+ _requestCertificateForLocalhost_ function returns a certificate and private key that can be used to start a server in HTTPS.
367
+
368
+ ```js
369
+ import { createServer } from "node:https"
370
+ import { requestCertificateForLocalhost } from "@jsenv/https-local"
371
+
372
+ const { serverCertificate, serverCertificatePrivateKey } =
373
+ await requestCertificateForLocalhost({
374
+ serverCertificateAltNames: ["localhost", "local.example"],
375
+ })
376
+ ```
377
+
378
+ [installCertificateAuthority](#installCertificateAuthority) must be called before this function.
379
+
357
380
  # verifyHostsFile
358
381
 
359
- _verifyHostsFile_ function check your hosts file content to see if ip mappings are present.
382
+ This function is not mandatory to obtain the https certificates.
383
+ But it is useful to programmatically verify ip mappings that are important for your local server are present in hosts file.
360
384
 
361
385
  ```js
362
386
  import { verifyHostsFile } from "@jsenv/https-local"
363
387
 
364
388
  await verifyHostsFile({
365
389
  ipMappings: {
366
- "127.0.0.1": ["localhost", "local.example.com"],
390
+ "127.0.0.1": ["localhost", "local.example"],
367
391
  },
368
392
  })
369
393
  ```
@@ -381,7 +405,7 @@ Check hosts file content...
381
405
  --- hosts file path ---
382
406
  /etc/hosts
383
407
  --- line(s) to add ---
384
- 127.0.0.1 localhost local.example.com
408
+ 127.0.0.1 localhost local.example
385
409
  ```
386
410
 
387
411
  </details>
@@ -397,7 +421,7 @@ Check hosts file content...
397
421
  --- hosts file path ---
398
422
  C:\\Windows\\System32\\Drivers\\etc\\hosts
399
423
  --- line(s) to add ---
400
- 127.0.0.1 localhost local.example.com
424
+ 127.0.0.1 localhost local.example
401
425
  ```
402
426
 
403
427
  </details>
@@ -411,7 +435,7 @@ import { verifyHostsFile } from "@jsenv/https-local"
411
435
 
412
436
  await verifyHostsFile({
413
437
  ipMappings: {
414
- "127.0.0.1": ["localhost", "local.example.com"],
438
+ "127.0.0.1": ["localhost", "local.example"],
415
439
  },
416
440
  tryToUpdateHostsFile: true,
417
441
  })
@@ -424,7 +448,7 @@ await verifyHostsFile({
424
448
  Check hosts file content...
425
449
  ℹ 1 mapping is missing in hosts file
426
450
  Adding 1 mapping(s) in hosts file...
427
- ❯ echo "127.0.0.1 local.example.com" | sudo tee /etc/hosts
451
+ ❯ echo "127.0.0.1 local.example" | sudo tee -a /etc/hosts
428
452
  Password:
429
453
  ✔ mappings added to hosts file
430
454
  ```
@@ -447,7 +471,7 @@ Check hosts file content...
447
471
  Check hosts file content...
448
472
  ℹ 1 mapping is missing in hosts file
449
473
  Adding 1 mapping(s) in hosts file...
450
- ❯ (echo 127.0.0.1 local.example.com) >> C:\\Windows\\System32\\Drivers\\etc\\hosts
474
+ ❯ (echo 127.0.0.1 local.example) >> C:\\Windows\\System32\\Drivers\\etc\\hosts
451
475
  Password:
452
476
  ✔ mappings added to hosts file
453
477
  ```
@@ -462,36 +486,3 @@ Check hosts file content...
462
486
  ```
463
487
 
464
488
  </details>
465
-
466
- # requestCertificateForLocalhost
467
-
468
- _requestCertificateForLocalhost_ function returns a certificate and private key that can be used to start a server in HTTPS.
469
-
470
- ```js
471
- import { createServer } from "node:https"
472
- import { requestCertificateForLocalhost } from "@jsenv/https-local"
473
-
474
- const { serverCertificate, serverCertificatePrivateKey } = await requestCertificateForLocalhost({
475
- serverCertificateAltNames: ["localhost", "local.example.com"],
476
- })
477
-
478
- const server = createServer(
479
- {
480
- cert: serverCertificate,
481
- key: serverCertificatePrivateKey,
482
- },
483
- (request, response) => {
484
- const body = "Hello world"
485
- response.writeHead(200, {
486
- "content-type": "text/plain",
487
- "content-length": Buffer.byteLength(body),
488
- })
489
- response.write(body)
490
- response.end()
491
- },
492
- )
493
- server.listen(8080)
494
- console.log(`Server listening at https://localhost:8080`)
495
- ```
496
-
497
- [installCertificateAuthority](#installCertificateAuthority) must be called before this function.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/https-local",
3
- "version": "1.0.0",
3
+ "version": "1.0.5",
4
4
  "description": "A programmatic way to generate locally trusted certificates",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -13,11 +13,10 @@
13
13
  "url": "https://github.com/jsenv/https-local"
14
14
  },
15
15
  "engines": {
16
- "node": ">=14.17.0"
16
+ "node": ">=16.13.0"
17
17
  },
18
18
  "publishConfig": {
19
- "access": "public",
20
- "registry": "https://registry.npmjs.org"
19
+ "access": "public"
21
20
  },
22
21
  "type": "module",
23
22
  "exports": {
@@ -26,14 +25,17 @@
26
25
  },
27
26
  "./*": "./*"
28
27
  },
28
+ "main": "./main.js",
29
29
  "files": [
30
30
  "/src/",
31
31
  "/main.js"
32
32
  ],
33
33
  "scripts": {
34
- "eslint-check": "node ./node_modules/eslint/bin/eslint.js .",
35
- "generate-importmap": "node ./script/importmap/generate_importmap.mjs",
36
- "measure-performances": "node ./script/performance/generate_performance_report.mjs --local",
34
+ "eslint": "node ./node_modules/eslint/bin/eslint.js . --ext=.js,.mjs",
35
+ "importmap": "node ./script/importmap/importmap.mjs",
36
+ "performances": "node --expose-gc ./script/performance/generate_performance_report.mjs --log",
37
+ "test": "node ./script/test/test.mjs",
38
+ "test-with-coverage": "npm run test -- --coverage",
37
39
  "start-node-server": "node ./script/certificate/start_node_server.mjs",
38
40
  "log-root-certificate-trust": "node ./script/certificate/log_root_certificate_trust.mjs",
39
41
  "trust-root-certificate": "node ./script/certificate/trust_root_certificate.mjs",
@@ -43,39 +45,31 @@
43
45
  "remove-localhost-mappings": "node ./script/hosts/remove_localhost_mappings.mjs",
44
46
  "verify-localhost-mappings": "node ./script/hosts/verify_localhost_mappings.mjs",
45
47
  "ensure-localhost-mappings": "node ./script/hosts/ensure_localhost_mappings.mjs",
46
- "test": "node ./script/test/test.mjs",
47
- "test-with-coverage": "npm run test -- --coverage",
48
- "prettier-format": "node ./script/prettier/prettier_format.mjs",
49
- "prettier-format-stage": "npm run prettier-format -- --staged",
50
- "prettier-check": "npm run prettier-format -- --dry-run",
51
- "install-playwright": "npx playwright install-deps && npx playwright install",
52
- "prepublishOnly": "node ./script/publish/remove_postinstall.mjs",
53
- "postpublish": "node ./script/publish/restore_postinstall.mjs"
48
+ "prettier": "prettier --write .",
49
+ "playwright-install": "npx playwright install-deps && npx playwright install"
54
50
  },
55
51
  "dependencies": {
56
- "@jsenv/filesystem": "2.1.1",
52
+ "@jsenv/filesystem": "2.7.1",
57
53
  "@jsenv/logger": "4.0.1",
58
54
  "command-exists": "1.2.9",
59
55
  "is-unicode-supported": "1.1.0",
60
- "node-forge": "0.10.0",
56
+ "node-forge": "1.2.1",
61
57
  "sudo-prompt": "9.2.1",
62
- "supports-color": "9.0.2",
58
+ "supports-color": "9.2.1",
63
59
  "which": "2.0.2"
64
60
  },
65
61
  "devDependencies": {
66
- "@jsenv/assert": "2.3.0",
67
- "@jsenv/codecov-upload": "3.5.0",
68
- "@jsenv/core": "19.6.2",
69
- "@jsenv/eslint-config": "15.0.2",
70
- "@jsenv/github-release-package": "1.2.3",
71
- "@jsenv/importmap-eslint-resolver": "5.1.0",
72
- "@jsenv/importmap-node-module": "1.0.1",
73
- "@jsenv/package-publish": "1.6.2",
74
- "@jsenv/performance-impact": "1.7.0",
75
- "@jsenv/prettier-check-project": "5.6.1",
76
- "eslint": "7.32.0",
77
- "eslint-plugin-import": "2.24.0",
78
- "playwright": "1.14.0",
79
- "prettier": "2.3.2"
62
+ "@jsenv/assert": "2.4.1",
63
+ "@jsenv/core": "25.3.0",
64
+ "@jsenv/eslint-config": "16.0.9",
65
+ "@jsenv/github-release-package": "1.3.2",
66
+ "@jsenv/importmap-eslint-resolver": "5.2.5",
67
+ "@jsenv/importmap-node-module": "5.1.3",
68
+ "@jsenv/package-publish": "1.7.1",
69
+ "@jsenv/performance-impact": "2.2.4",
70
+ "eslint": "8.7.0",
71
+ "eslint-plugin-import": "2.25.4",
72
+ "playwright": "1.18.0",
73
+ "prettier": "2.5.1"
80
74
  }
81
- }
75
+ }
@@ -6,7 +6,10 @@ import { readFile, writeFile, removeFileSystemNode } from "@jsenv/filesystem"
6
6
  import { infoSign, okSign } from "./internal/logs.js"
7
7
  import { getAuthorityFileInfos } from "./internal/authority_file_infos.js"
8
8
  import { attributeDescriptionFromAttributeArray } from "./internal/certificate_data_converter.js"
9
- import { formatTimeDelta, formatDuration } from "./internal/validity_formatting.js"
9
+ import {
10
+ formatTimeDelta,
11
+ formatDuration,
12
+ } from "./internal/validity_formatting.js"
10
13
  import { importNodeForge } from "./internal/forge.js"
11
14
  import { createAuthorityRootCertificate } from "./internal/certificate_generator.js"
12
15
  import { importPlatformMethods } from "./internal/platform.js"
@@ -54,8 +57,11 @@ export const installCertificateAuthority = async ({
54
57
  )
55
58
  }
56
59
 
57
- const { authorityJsonFileInfo, rootCertificateFileInfo, rootCertificatePrivateKeyFileInfo } =
58
- getAuthorityFileInfos()
60
+ const {
61
+ authorityJsonFileInfo,
62
+ rootCertificateFileInfo,
63
+ rootCertificatePrivateKeyFileInfo,
64
+ } = getAuthorityFileInfos()
59
65
  const authorityJsonFileUrl = authorityJsonFileInfo.url
60
66
  const rootCertificateFileUrl = rootCertificateFileInfo.url
61
67
  const rootPrivateKeyFileUrl = rootCertificatePrivateKeyFileInfo.url
@@ -76,16 +82,23 @@ export const installCertificateAuthority = async ({
76
82
  })
77
83
 
78
84
  const { pki } = await importNodeForge()
79
- const rootCertificate = pemAsFileContent(pki.certificateToPem(rootCertificateForgeObject))
85
+ const rootCertificate = pemAsFileContent(
86
+ pki.certificateToPem(rootCertificateForgeObject),
87
+ )
80
88
  const rootCertificatePrivateKey = pemAsFileContent(
81
89
  pki.privateKeyToPem(rootCertificatePrivateKeyForgeObject),
82
90
  )
83
91
 
84
92
  await writeFile(rootCertificateFileUrl, rootCertificate)
85
93
  await writeFile(rootPrivateKeyFileUrl, rootCertificatePrivateKey)
86
- await writeFile(authorityJsonFileUrl, JSON.stringify({ serialNumber: 0 }, null, " "))
94
+ await writeFile(
95
+ authorityJsonFileUrl,
96
+ JSON.stringify({ serialNumber: 0 }, null, " "),
97
+ )
87
98
 
88
- logger.info(`${okSign} authority root certificate written at ${rootCertificateFileInfo.path}`)
99
+ logger.info(
100
+ `${okSign} authority root certificate written at ${rootCertificateFileInfo.path}`,
101
+ )
89
102
  return {
90
103
  rootCertificateForgeObject,
91
104
  rootCertificatePrivateKeyForgeObject,
@@ -140,14 +153,18 @@ export const installCertificateAuthority = async ({
140
153
  logger.debug(
141
154
  `Authority root certificate is not on filesystem at ${rootCertificateFileInfo.path}`,
142
155
  )
143
- logger.info(`${infoSign} authority root certificate not found in filesystem`)
156
+ logger.info(
157
+ `${infoSign} authority root certificate not found in filesystem`,
158
+ )
144
159
  return generate()
145
160
  }
146
161
  if (!rootCertificatePrivateKeyFileInfo.exists) {
147
162
  logger.debug(
148
163
  `Authority root certificate private key is not on filesystem at ${rootCertificatePrivateKeyFileInfo.path}`,
149
164
  )
150
- logger.info(`${infoSign} authority root certificate not found in filesystem`)
165
+ logger.info(
166
+ `${infoSign} authority root certificate not found in filesystem`,
167
+ )
151
168
  return generate()
152
169
  }
153
170
  logger.debug(
@@ -155,18 +172,23 @@ export const installCertificateAuthority = async ({
155
172
  )
156
173
  logger.info(`${okSign} authority root certificate found in filesystem`)
157
174
 
158
- const rootCertificate = await readFile(rootCertificateFileInfo.path, { as: "string" })
175
+ const rootCertificate = await readFile(rootCertificateFileInfo.path, {
176
+ as: "string",
177
+ })
159
178
  const { pki } = await importNodeForge()
160
179
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
161
180
 
162
181
  logger.info(`Checking certificate validity...`)
163
- const rootCertificateValidityDurationInMs = getCertificateValidityDurationInMs(
182
+ const rootCertificateValidityDurationInMs =
183
+ getCertificateValidityDurationInMs(rootCertificateForgeObject)
184
+ const rootCertificateValidityRemainingMs = getCertificateRemainingMs(
164
185
  rootCertificateForgeObject,
165
186
  )
166
- const rootCertificateValidityRemainingMs = getCertificateRemainingMs(rootCertificateForgeObject)
167
187
  if (rootCertificateValidityRemainingMs < 0) {
168
188
  logger.info(
169
- `${infoSign} certificate expired ${formatTimeDelta(rootCertificateValidityRemainingMs)}`,
189
+ `${infoSign} certificate expired ${formatTimeDelta(
190
+ rootCertificateValidityRemainingMs,
191
+ )}`,
170
192
  )
171
193
  return regenerate()
172
194
  }
@@ -174,30 +196,44 @@ export const installCertificateAuthority = async ({
174
196
  rootCertificateValidityRemainingMs / rootCertificateValidityDurationInMs
175
197
  if (rootCertificateValidityRemainingRatio < aboutToExpireRatio) {
176
198
  logger.info(
177
- `${infoSign} certificate will expire ${formatTimeDelta(rootCertificateValidityRemainingMs)}`,
199
+ `${infoSign} certificate will expire ${formatTimeDelta(
200
+ rootCertificateValidityRemainingMs,
201
+ )}`,
178
202
  )
179
203
  return regenerate()
180
204
  }
181
205
  logger.info(
182
- `${okSign} certificate still valid for ${formatDuration(rootCertificateValidityRemainingMs)}`,
206
+ `${okSign} certificate still valid for ${formatDuration(
207
+ rootCertificateValidityRemainingMs,
208
+ )}`,
183
209
  )
184
210
 
185
211
  logger.info(`Detect if certificate attributes have changed...`)
186
- const rootCertificateDifferences = compareRootCertificateAttributes(rootCertificateForgeObject, {
187
- certificateCommonName,
188
- certificateValidityDurationInMs,
189
- })
212
+ const rootCertificateDifferences = compareRootCertificateAttributes(
213
+ rootCertificateForgeObject,
214
+ {
215
+ certificateCommonName,
216
+ certificateValidityDurationInMs,
217
+ },
218
+ )
190
219
  if (rootCertificateDifferences.length) {
191
220
  const paramNames = Object.keys(rootCertificateDifferences)
192
- logger.info(`${infoSign} certificate attributes are outdated: ${paramNames}`)
221
+ logger.info(
222
+ `${infoSign} certificate attributes are outdated: ${paramNames}`,
223
+ )
193
224
  return regenerate()
194
225
  }
195
226
  logger.info(`${okSign} certificate attributes are the same`)
196
227
 
197
- const rootCertificatePrivateKey = await readFile(rootCertificatePrivateKeyFileInfo.path, {
198
- as: "string",
199
- })
200
- const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(rootCertificatePrivateKey)
228
+ const rootCertificatePrivateKey = await readFile(
229
+ rootCertificatePrivateKeyFileInfo.path,
230
+ {
231
+ as: "string",
232
+ },
233
+ )
234
+ const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(
235
+ rootCertificatePrivateKey,
236
+ )
201
237
 
202
238
  const trustInfo = await platformMethods.executeTrustQuery({
203
239
  logger,
@@ -272,8 +308,11 @@ export const uninstallCertificateAuthority = async ({
272
308
  logger = createLogger({ logLevel }),
273
309
  tryToUntrust = false,
274
310
  } = {}) => {
275
- const { authorityJsonFileInfo, rootCertificateFileInfo, rootCertificatePrivateKeyFileInfo } =
276
- getAuthorityFileInfos()
311
+ const {
312
+ authorityJsonFileInfo,
313
+ rootCertificateFileInfo,
314
+ rootCertificatePrivateKeyFileInfo,
315
+ } = getAuthorityFileInfos()
277
316
 
278
317
  const filesToRemove = []
279
318
 
@@ -283,7 +322,9 @@ export const uninstallCertificateAuthority = async ({
283
322
  if (rootCertificateFileInfo.exists) {
284
323
  // first untrust the root cert file
285
324
  if (tryToUntrust) {
286
- const rootCertificate = await readFile(rootCertificateFileInfo.url, { as: "string" })
325
+ const rootCertificate = await readFile(rootCertificateFileInfo.url, {
326
+ as: "string",
327
+ })
287
328
  const { pki } = await importNodeForge()
288
329
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
289
330
  const rootCertificateCommonName = attributeDescriptionFromAttributeArray(
@@ -15,8 +15,8 @@ export const requestCertificateForLocalhost = async ({
15
15
  logLevel,
16
16
  logger = createLogger({ logLevel }), // to be able to catch logs during unit tests
17
17
 
18
- serverCertificateAltNames = [],
19
- serverCertificateCommonName = "Jsenv localhost server certificate",
18
+ serverCertificateAltNames = ["localhost"],
19
+ serverCertificateCommonName = "https local server certificate",
20
20
  serverCertificateValidityDurationInMs = createValidityDurationOfXDays(396),
21
21
  } = {}) => {
22
22
  if (typeof serverCertificateValidityDurationInMs !== "number") {
@@ -41,8 +41,11 @@ export const requestCertificateForLocalhost = async ({
41
41
  )
42
42
  }
43
43
 
44
- const { authorityJsonFileInfo, rootCertificateFileInfo, rootCertificatePrivateKeyFileInfo } =
45
- getAuthorityFileInfos()
44
+ const {
45
+ authorityJsonFileInfo,
46
+ rootCertificateFileInfo,
47
+ rootCertificatePrivateKeyFileInfo,
48
+ } = getAuthorityFileInfos()
46
49
  if (!rootCertificateFileInfo.exists) {
47
50
  throw new Error(
48
51
  `Certificate authority not found, "installCertificateAuthority" must be called before "requestCertificateForLocalhost"`,
@@ -57,16 +60,26 @@ export const requestCertificateForLocalhost = async ({
57
60
 
58
61
  logger.debug(`Restoring certificate authority from filesystem...`)
59
62
  const { pki } = await importNodeForge()
60
- const rootCertificate = await readFile(rootCertificateFileInfo.url, { as: "string" })
61
- const rootCertificatePrivateKey = await readFile(rootCertificatePrivateKeyFileInfo.url, {
63
+ const rootCertificate = await readFile(rootCertificateFileInfo.url, {
62
64
  as: "string",
63
65
  })
64
- const certificateAuthorityData = await readFile(authorityJsonFileInfo.url, { as: "json" })
66
+ const rootCertificatePrivateKey = await readFile(
67
+ rootCertificatePrivateKeyFileInfo.url,
68
+ {
69
+ as: "string",
70
+ },
71
+ )
72
+ const certificateAuthorityData = await readFile(authorityJsonFileInfo.url, {
73
+ as: "json",
74
+ })
65
75
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
66
- const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(rootCertificatePrivateKey)
76
+ const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(
77
+ rootCertificatePrivateKey,
78
+ )
67
79
  logger.debug(`${okSign} certificate authority restored from filesystem`)
68
80
 
69
- const serverCertificateSerialNumber = certificateAuthorityData.serialNumber + 1
81
+ const serverCertificateSerialNumber =
82
+ certificateAuthorityData.serialNumber + 1
70
83
  await writeFile(
71
84
  authorityJsonFileInfo.url,
72
85
  JSON.stringify({ serialNumber: serverCertificateSerialNumber }, null, " "),
@@ -81,14 +94,17 @@ export const requestCertificateForLocalhost = async ({
81
94
  await requestCertificateFromAuthority({
82
95
  logger,
83
96
  authorityCertificateForgeObject: rootCertificateForgeObject,
84
- auhtorityCertificatePrivateKeyForgeObject: rootCertificatePrivateKeyForgeObject,
97
+ auhtorityCertificatePrivateKeyForgeObject:
98
+ rootCertificatePrivateKeyForgeObject,
85
99
  serialNumber: serverCertificateSerialNumber,
86
100
  altNames: serverCertificateAltNames,
87
101
  commonName: serverCertificateCommonName,
88
102
  validityDurationInMs: serverCertificateValidityDurationInMs,
89
103
  })
90
104
  const serverCertificate = pki.certificateToPem(certificateForgeObject)
91
- const serverCertificatePrivateKey = pki.privateKeyToPem(certificatePrivateKeyForgeObject)
105
+ const serverCertificatePrivateKey = pki.privateKeyToPem(
106
+ certificatePrivateKeyForgeObject,
107
+ )
92
108
  logger.debug(
93
109
  `${okSign} server certificate generated, it will be valid for ${formatDuration(
94
110
  serverCertificateValidityDurationInMs,