@jsenv/https-local 3.2.43 → 3.3.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/README.md CHANGED
@@ -1,82 +1,77 @@
1
- # HTTPS Local [![npm package](https://img.shields.io/npm/v/@jsenv/https-local.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/https-local)
2
-
3
- A programmatic way to generate locally trusted certificates for HTTPS development.
4
-
5
- 🔒 Generate certificates trusted by your operating system and browsers
6
- 🌐 Perfect for local HTTPS development
7
- 🖥️ Works on macOS, Linux, and Windows
8
- ⚡ Simple API for certificate management
9
-
10
- ## Table of Contents
11
-
12
- - [HTTPS Local ](#https-local-)
13
- - [Table of Contents](#table-of-contents)
14
- - [Quick Start](#quick-start)
15
- - [How to Use](#how-to-use)
16
- - [1. Install the Root Certificate](#1-install-the-root-certificate)
17
- - [2. Request Certificate for Your Server](#2-request-certificate-for-your-server)
18
- - [3. Start the Server](#3-start-the-server)
19
- - [Certificate Expiration](#certificate-expiration)
20
- - [JavaScript API](#javascript-api)
21
- - [requestCertificate](#requestcertificate)
22
- - [verifyHostsFile](#verifyhostsfile)
23
- - [Auto Update Hosts](#auto-update-hosts)
24
- - [installCertificateAuthority](#installcertificateauthority)
25
- - [Auto Trust](#auto-trust)
26
-
27
- ## Quick Start
1
+ # https local [![npm package](https://img.shields.io/npm/v/@jsenv/https-local.svg?logo=npm&label=package)](https://www.npmjs.com/package/@jsenv/https-local)
28
2
 
29
- ```console
30
- # Install the package
31
- npm install @jsenv/https-local
3
+ MOVED TO https://github.com/jsenv/core/tree/main/packages/independent/https-local
4
+
5
+ A programmatic way to generate locally trusted certificates.
6
+
7
+ Generate certificate(s) trusted by your operating system and browsers.
8
+ This certificate can be used to start your development server in HTTPS.
9
+ Works on mac, linux and windows.
10
+
11
+ # How to use
12
+
13
+ 1 - Install _@jsenv/https-local_
32
14
 
33
- # Install and trust the root certificate
34
- npx @jsenv/https-local install --trust
15
+ ```console
16
+ npm install --save-dev @jsenv/https-local
35
17
  ```
36
18
 
19
+ 2 - Create _install_certificate_authority.mjs_
20
+
37
21
  ```js
38
- // In your server file
39
- import { createServer } from "node:https";
40
- import { requestCertificate } from "@jsenv/https-local";
22
+ /*
23
+ * This file needs to be executed once.
24
+ * After that the root certificate is valid for 20 years.
25
+ * Re-executing this file will log the current root certificate validity and trust status.
26
+ * Re-executing this file 20 years later would reinstall a root certificate and re-trust it.
27
+ *
28
+ * Read more in https://github.com/jsenv/https-local#installCertificateAuthority
29
+ */
30
+
31
+ import {
32
+ installCertificateAuthority,
33
+ verifyHostsFile,
34
+ } from "@jsenv/https-local";
41
35
 
42
- const { certificate, privateKey } = requestCertificate();
43
- const server = createServer(
44
- {
45
- cert: certificate,
46
- key: privateKey,
47
- },
48
- (request, response) => {
49
- response.end("Hello HTTPS world!");
36
+ await installCertificateAuthority({
37
+ tryToTrust: true,
38
+ NSSDynamicInstall: true,
39
+ });
40
+ await verifyHostsFile({
41
+ ipMappings: {
42
+ "127.0.0.1": ["localhost"],
50
43
  },
51
- ).listen(8443, () => {
52
- console.log("HTTPS server running at https://localhost:8443");
44
+ tryToUpdatesHostsFile: true,
53
45
  });
54
46
  ```
55
47
 
56
- ## How to Use
57
-
58
- The following steps can be taken to start a local server in HTTPS:
59
-
60
- ### 1. Install the Root Certificate
48
+ 3 - Run with node
61
49
 
62
50
  ```console
63
- npx @jsenv/https-local install --trust
51
+ node ./install_certificate_authority.mjs
64
52
  ```
65
53
 
66
- This will install a root certificate valid for 20 years.
67
-
68
- - Re-executing this command will log the current root certificate validity and trust status
69
- - Re-executing this command 20 years later would reinstall a root certificate and re-trust it
70
-
71
- ### 2. Request Certificate for Your Server
72
-
73
- _start_dev_server.mjs_
54
+ 4 - Create _start_dev_server.mjs_
74
55
 
75
56
  ```js
57
+ /*
58
+ * This file uses "@jsenv/https-local" to obtain a certificate used to start a server in https.
59
+ * The certificate is valid for 1 year (396 days) and is issued by a certificate authority trusted on this machine.
60
+ * If the certificate authority was not installed before executing this file, an error is thrown
61
+ * explaining that certificate authority must be installed first.
62
+ *
63
+ * To install the certificate authority, you can use the following command
64
+ *
65
+ * > node ./install_certificate_authority.mjs
66
+ *
67
+ * Read more in https://github.com/jsenv/https-local#requestCertificate
68
+ */
69
+
76
70
  import { createServer } from "node:https";
77
71
  import { requestCertificate } from "@jsenv/https-local";
78
72
 
79
73
  const { certificate, privateKey } = requestCertificate();
74
+
80
75
  const server = createServer(
81
76
  {
82
77
  cert: certificate,
@@ -96,156 +91,31 @@ server.listen(8080);
96
91
  console.log(`Server listening at https://local.example:8080`);
97
92
  ```
98
93
 
99
- ### 3. Start the Server
94
+ 5 - Start server with node
100
95
 
101
96
  ```console
102
97
  node ./start_dev_server.mjs
103
98
  ```
104
99
 
105
- At this stage you have a server running in HTTPS.
100
+ At this stage you have a server running in https.
101
+ The rest of this documentation goes into more details.
106
102
 
107
- ## Certificate Expiration
103
+ # Certificate expiration
108
104
 
109
105
  | Certificate | Expires after | How to renew? |
110
106
  | ----------- | ------------- | ------------------------------------ |
111
107
  | server | 1 year | Re-run _requestCertificate_ |
112
- | authority | 20 years | Re-run _installCertificateAuthority_ |
108
+ | authority | 20 year | Re-run _installCertificateAuthority_ |
113
109
 
114
- The **server certificate** expires after one year, which is the maximum duration allowed by web browsers.
110
+ The **server certificate** expires after one year which is the maximum duration allowed by web browsers.
115
111
  In the unlikely scenario where a local server is running for more than a year without interruption, restart it to re-run requestCertificate.
116
112
 
117
- The **authority root certificate** expires after 20 years, which is close to the maximum allowed duration.
118
- 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.
119
-
120
- ## JavaScript API
121
-
122
- ### requestCertificate
123
-
124
- The `requestCertificate` function returns a certificate and private key that can be used to start a server in HTTPS.
125
-
126
- ```js
127
- import { createServer } from "node:https";
128
- import { requestCertificate } from "@jsenv/https-local";
129
-
130
- const { certificate, privateKey } = requestCertificate({
131
- altNames: ["localhost", "local.example"],
132
- });
133
- ```
134
-
135
- [installCertificateAuthority](#installcertificateauthority) must be called before this function.
136
-
137
- ### verifyHostsFile
138
-
139
- This function is not mandatory to obtain the HTTPS certificates, but it is useful to programmatically verify IP mappings that are important for your local server are present in hosts file.
140
-
141
- ```js
142
- import { verifyHostsFile } from "@jsenv/https-local";
143
-
144
- await verifyHostsFile({
145
- ipMappings: {
146
- "127.0.0.1": ["localhost", "local.example"],
147
- },
148
- });
149
- ```
150
-
151
- Find below logs written in terminal when this function is executed:
152
-
153
- <details>
154
- <summary>Mac and Linux output</summary>
155
-
156
- ```console
157
- > node ./verify_hosts.mjs
158
-
159
- Check hosts file content...
160
- ⚠ 1 mapping is missing in hosts file
161
- --- hosts file path ---
162
- /etc/hosts
163
- --- line(s) to add ---
164
- 127.0.0.1 localhost local.example
165
- ```
166
-
167
- </details>
168
-
169
- <details>
170
- <summary>Windows output</summary>
171
-
172
- ```console
173
- > node ./verify_hosts.mjs
174
-
175
- Check hosts file content...
176
- ⚠ 1 mapping is missing in hosts file
177
- --- hosts file path ---
178
- C:\\Windows\\System32\\Drivers\\etc\\hosts
179
- --- line(s) to add ---
180
- 127.0.0.1 localhost local.example
181
- ```
182
-
183
- </details>
184
-
185
- #### Auto Update Hosts
186
-
187
- It's possible to update hosts file programmatically using `tryToUpdateHostsFile`:
188
-
189
- ```js
190
- import { verifyHostsFile } from "@jsenv/https-local";
191
-
192
- await verifyHostsFile({
193
- ipMappings: {
194
- "127.0.0.1": ["localhost", "local.example"],
195
- },
196
- tryToUpdateHostsFile: true,
197
- });
198
- ```
199
-
200
- <details>
201
- <summary>Mac and Linux output</summary>
202
-
203
- ```console
204
- Check hosts file content...
205
- ℹ 1 mapping is missing in hosts file
206
- Adding 1 mapping(s) in hosts file...
207
- ❯ echo "127.0.0.1 local.example" | sudo tee -a /etc/hosts
208
- Password:
209
- ✔ mappings added to hosts file
210
- ```
211
-
212
- _Second execution logs_
213
-
214
- ```console
215
- > node ./verify_hosts.mjs
216
-
217
- Check hosts file content...
218
- ✔ all ip mappings found in hosts file
219
- ```
220
-
221
- </details>
222
-
223
- <details>
224
- <summary>Windows output</summary>
225
-
226
- ```console
227
- Check hosts file content...
228
- ℹ 1 mapping is missing in hosts file
229
- Adding 1 mapping(s) in hosts file...
230
- ❯ (echo 127.0.0.1 local.example) >> C:\\Windows\\System32\\Drivers\\etc\\hosts
231
- Password:
232
- ✔ mappings added to hosts file
233
- ```
234
-
235
- _Second execution logs_
113
+ The **authority root certificate** expires after 20 years which is close to the maximum allowed duration.
114
+ 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.
236
115
 
237
- ```console
238
- > node ./verify_hosts.mjs
116
+ # installCertificateAuthority
239
117
 
240
- Check hosts file content...
241
- ✔ all ip mappings found in hosts file
242
- ```
243
-
244
- </details>
245
-
246
- ### installCertificateAuthority
247
-
248
- The `installCertificateAuthority` function generates a certificate authority valid for 20 years.
118
+ _installCertificateAuthority_ function generates a certificate authority valid for 20 years.
249
119
  This certificate authority is needed to generate local certificates that will be trusted by the operating system and web browsers.
250
120
 
251
121
  ```js
@@ -254,10 +124,12 @@ import { installCertificateAuthority } from "@jsenv/https-local";
254
124
  await installCertificateAuthority();
255
125
  ```
256
126
 
257
- By default, trusting authority root certificate is a manual process. 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). This process can be done programmatically as explained in [Auto Trust](#auto-trust).
127
+ By default, trusting authority root certificate is a manual process. 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). This process can be done programmatically as explained in [Auto trust](#Auto-trust).
128
+
129
+ Find below logs written in terminal when this function is executed.
258
130
 
259
131
  <details>
260
- <summary>macOS output</summary>
132
+ <summary>mac</summary>
261
133
 
262
134
  ```console
263
135
  > node ./install_certificate_authority.mjs
@@ -269,7 +141,7 @@ Generating authority root certificate with a validity of 20 years...
269
141
  ℹ You should add root certificate to firefox
270
142
  ```
271
143
 
272
- _Second execution logs_
144
+ _second execution logs_
273
145
 
274
146
  ```console
275
147
  > node ./install_certificate_authority.mjs
@@ -288,7 +160,7 @@ Check if certificate is in firefox...
288
160
  </details>
289
161
 
290
162
  <details>
291
- <summary>Linux output</summary>
163
+ <summary>linux</summary>
292
164
 
293
165
  ```console
294
166
  > node ./install_certificate_authority.mjs
@@ -301,7 +173,7 @@ Generating authority root certificate with a validity of 20 years...
301
173
  ℹ You should add certificate to firefox
302
174
  ```
303
175
 
304
- _Second execution logs_
176
+ _second execution logs_
305
177
 
306
178
  ```console
307
179
  > node ./install_certificate_authority.mjs
@@ -322,7 +194,7 @@ Check if certificate is in firefox...
322
194
  </details>
323
195
 
324
196
  <details>
325
- <summary>Windows output</summary>
197
+ <summary>windows</summary>
326
198
 
327
199
  ```console
328
200
  > node ./install_certificate_authority.mjs
@@ -334,7 +206,7 @@ Generating authority root certificate with a validity of 20 years...
334
206
  ℹ You should add certificate to firefox
335
207
  ```
336
208
 
337
- _Second execution logs_
209
+ _second execution logs_
338
210
 
339
211
  ```console
340
212
  > node ./install_certificate_authority.mjs
@@ -352,9 +224,9 @@ Check if certificate is trusted by firefox...
352
224
 
353
225
  </details>
354
226
 
355
- #### Auto Trust
227
+ ## Auto trust
356
228
 
357
- It's possible to trust root certificate programmatically using `tryToTrust`:
229
+ It's possible to trust root certificate programmatically using _tryToTrust_
358
230
 
359
231
  ```js
360
232
  import { installCertificateAuthority } from "@jsenv/https-local";
@@ -365,7 +237,7 @@ await installCertificateAuthority({
365
237
  ```
366
238
 
367
239
  <details>
368
- <summary>macOS output</summary>
240
+ <summary>mac</summary>
369
241
 
370
242
  ```console
371
243
  > node ./install_certificate_authority.mjs
@@ -381,7 +253,7 @@ Adding certificate to firefox...
381
253
  ✔ certificate added to Firefox
382
254
  ```
383
255
 
384
- _Second execution logs_
256
+ _second execution logs_
385
257
 
386
258
  ```console
387
259
  > node ./install_certificate_authority.mjs
@@ -400,7 +272,7 @@ Check if certificate is in Firefox...
400
272
  </details>
401
273
 
402
274
  <details>
403
- <summary>Linux output</summary>
275
+ <summary>linux</summary>
404
276
 
405
277
  ```console
406
278
  > node ./install_certificate_authority.mjs
@@ -427,7 +299,7 @@ Adding certificate to firefox...
427
299
  ✔ certificate added to firefox
428
300
  ```
429
301
 
430
- _Second execution logs_
302
+ _second execution logs_
431
303
 
432
304
  ```console
433
305
  > node ./install_certificate_authority.mjs
@@ -448,7 +320,7 @@ Check if certificate is in firefox...
448
320
  </details>
449
321
 
450
322
  <details>
451
- <summary>Windows output</summary>
323
+ <summary>windows</summary>
452
324
 
453
325
  ```console
454
326
  > node ./install_certificate_authority.mjs
@@ -467,7 +339,7 @@ Check if certificate is trusted by firefox...
467
339
  ℹ unable to detect if certificate is trusted by firefox (not implemented on windows)
468
340
  ```
469
341
 
470
- _Second execution logs_
342
+ _second execution logs_
471
343
 
472
344
  ```console
473
345
  > node ./install_certificate_authority.mjs
@@ -484,3 +356,128 @@ Check if certificate is trusted by firefox...
484
356
  ```
485
357
 
486
358
  </details>
359
+
360
+ # requestCertificate
361
+
362
+ _requestCertificate_ function returns a certificate and private key that can be used to start a server in HTTPS.
363
+
364
+ ```js
365
+ import { createServer } from "node:https";
366
+ import { requestCertificate } from "@jsenv/https-local";
367
+
368
+ const { certificate, privateKey } = requestCertificate({
369
+ altNames: ["localhost", "local.example"],
370
+ });
371
+ ```
372
+
373
+ [installCertificateAuthority](#installCertificateAuthority) must be called before this function.
374
+
375
+ # verifyHostsFile
376
+
377
+ This function is not mandatory to obtain the https certificates.
378
+ But it is useful to programmatically verify ip mappings that are important for your local server are present in hosts file.
379
+
380
+ ```js
381
+ import { verifyHostsFile } from "@jsenv/https-local";
382
+
383
+ await verifyHostsFile({
384
+ ipMappings: {
385
+ "127.0.0.1": ["localhost", "local.example"],
386
+ },
387
+ });
388
+ ```
389
+
390
+ Find below logs written in terminal when this function is executed.
391
+
392
+ <details>
393
+ <summary>mac and linux</summary>
394
+
395
+ ```console
396
+ > node ./verify_hosts.mjs
397
+
398
+ Check hosts file content...
399
+ ⚠ 1 mapping is missing in hosts file
400
+ --- hosts file path ---
401
+ /etc/hosts
402
+ --- line(s) to add ---
403
+ 127.0.0.1 localhost local.example
404
+ ```
405
+
406
+ </details>
407
+
408
+ <details>
409
+ <summary>windows</summary>
410
+
411
+ ```console
412
+ > node ./verify_hosts.mjs
413
+
414
+ Check hosts file content...
415
+ ⚠ 1 mapping is missing in hosts file
416
+ --- hosts file path ---
417
+ C:\\Windows\\System32\\Drivers\\etc\\hosts
418
+ --- line(s) to add ---
419
+ 127.0.0.1 localhost local.example
420
+ ```
421
+
422
+ </details>
423
+
424
+ ## Auto update hosts
425
+
426
+ It's possible to update hosts file programmatically using _tryToUpdateHostsFile_.
427
+
428
+ ```js
429
+ import { verifyHostsFile } from "@jsenv/https-local";
430
+
431
+ await verifyHostsFile({
432
+ ipMappings: {
433
+ "127.0.0.1": ["localhost", "local.example"],
434
+ },
435
+ tryToUpdateHostsFile: true,
436
+ });
437
+ ```
438
+
439
+ <details>
440
+ <summary>mac and linux</summary>
441
+
442
+ ```console
443
+ Check hosts file content...
444
+ ℹ 1 mapping is missing in hosts file
445
+ Adding 1 mapping(s) in hosts file...
446
+ ❯ echo "127.0.0.1 local.example" | sudo tee -a /etc/hosts
447
+ Password:
448
+ ✔ mappings added to hosts file
449
+ ```
450
+
451
+ _Second execution logs_
452
+
453
+ ```console
454
+ > node ./verify_hosts.mjs
455
+
456
+ Check hosts file content...
457
+ ✔ all ip mappings found in hosts file
458
+ ```
459
+
460
+ </details>
461
+
462
+ <details>
463
+ <summary>windows</summary>
464
+
465
+ ```console
466
+ Check hosts file content...
467
+ ℹ 1 mapping is missing in hosts file
468
+ Adding 1 mapping(s) in hosts file...
469
+ ❯ (echo 127.0.0.1 local.example) >> C:\\Windows\\System32\\Drivers\\etc\\hosts
470
+ Password:
471
+ ✔ mappings added to hosts file
472
+ ```
473
+
474
+ _Second execution logs_
475
+
476
+ ```console
477
+ > node ./verify_hosts.mjs
478
+
479
+ Check hosts file content...
480
+ ✔ all ip mappings found in hosts file
481
+ ```
482
+
483
+ </details>
package/package.json CHANGED
@@ -1,57 +1,75 @@
1
1
  {
2
2
  "name": "@jsenv/https-local",
3
- "version": "3.2.43",
3
+ "version": "3.3.0",
4
+ "type": "module",
4
5
  "description": "A programmatic way to generate locally trusted certificates",
5
6
  "repository": {
6
7
  "type": "git",
7
- "url": "https://github.com/jsenv/core",
8
- "directory": "packages/tooling/https-local"
8
+ "url": "https://github.com/jsenv/https-local"
9
+ },
10
+ "author": {
11
+ "name": "dmail",
12
+ "email": "dmaillard06@gmail.com"
9
13
  },
10
14
  "license": "MIT",
11
- "type": "module",
15
+ "engines": {
16
+ "node": ">=25.0.0"
17
+ },
18
+ "main": "./src/main.js",
12
19
  "exports": {
13
20
  ".": {
14
21
  "import": "./src/main.js"
15
22
  },
16
23
  "./*": "./*"
17
24
  },
18
- "main": "./src/main.js",
19
- "bin": "./src/https_local_cli.mjs",
20
25
  "files": [
21
26
  "/src/"
22
27
  ],
23
28
  "scripts": {
29
+ "eslint": "npx eslint . --ext=.js,.mjs,.cjs",
30
+ "test": "node ./scripts/test/test.mjs",
31
+ "performance": "node --expose-gc ./scripts/performance/performance.mjs --local --log",
32
+ "test:start-node-server": "node ./scripts/certificate/start_node_server.mjs",
24
33
  "ca:install": "node ./scripts/certificate/install_ca.mjs",
25
34
  "ca:log-trust": "node ./scripts/certificate/log_root_certificate_trust.mjs",
26
35
  "ca:trust": "node ./scripts/certificate/trust_root_certificate.mjs",
27
- "ca:uninstall": "node ./scripts/certificate/uninstall_certificate_authority.mjs",
28
36
  "ca:untrust": "node ./scripts/certificate/untrust_root_certificate.mjs",
37
+ "ca:uninstall": "node ./scripts/certificate/uninstall_certificate_authority.mjs",
29
38
  "hosts:add-localhost-mappings": "node ./scripts/hosts/add_localhost_mappings.mjs",
30
- "hosts:ensure-localhost-mappings": "node ./scripts/hosts/ensure_localhost_mappings.mjs",
31
39
  "hosts:remove-localhost-mappings": "node ./scripts/hosts/remove_localhost_mappings.mjs",
32
40
  "hosts:verify-localhost-mappings": "node ./scripts/hosts/verify_localhost_mappings.mjs",
33
- "performance": "node --expose-gc ./scripts/performance/performance.mjs --local --log",
34
- "test:start-node-server": "node ./scripts/certificate/start_node_server.mjs"
41
+ "hosts:ensure-localhost-mappings": "node ./scripts/hosts/ensure_localhost_mappings.mjs",
42
+ "prettier": "prettier --write .",
43
+ "playwright:install": "npx playwright install-deps && npx playwright install"
35
44
  },
36
45
  "dependencies": {
37
- "@jsenv/filesystem": "4.15.14",
38
- "@jsenv/humanize": "1.7.5",
39
- "@jsenv/urls": "2.9.7",
46
+ "@jsenv/filesystem": "4.15.15",
47
+ "@jsenv/log": "3.5.2",
48
+ "@jsenv/urls": "2.9.8",
40
49
  "command-exists": "1.2.9",
41
- "node-forge": "1.3.3",
50
+ "node-forge": "1.4.0",
42
51
  "sudo-prompt": "9.2.1",
43
- "which": "6.0.0"
52
+ "which": "6.0.1"
44
53
  },
45
54
  "devDependencies": {
46
- "@jsenv/assert": "../assert",
47
- "@jsenv/https-local": "./",
48
- "@jsenv/performance-impact": "../performance-impact",
49
- "playwright": "1.58.1"
50
- },
51
- "engines": {
52
- "node": ">=20.0.0"
55
+ "@jsenv/assert": "4.5.6",
56
+ "@jsenv/eslint-config-relax": "1.8.5",
57
+ "@jsenv/github-release-package": "1.6.42",
58
+ "@jsenv/package-publish": "1.11.44",
59
+ "@jsenv/performance-impact": "4.4.42",
60
+ "@jsenv/test": "3.7.21",
61
+ "eslint": "9.39.2",
62
+ "playwright": "1.59.1",
63
+ "prettier": "3.8.3",
64
+ "prettier-plugin-embed": "0.5.1",
65
+ "prettier-plugin-organize-imports": "4.3.0",
66
+ "prettier-plugin-pkg": "0.22.1"
53
67
  },
54
68
  "publishConfig": {
55
69
  "access": "public"
70
+ },
71
+ "volta": {
72
+ "node": "25.8.1",
73
+ "npm": "11.6.2"
56
74
  }
57
75
  }
@@ -1,5 +1,6 @@
1
1
  import { readFile, removeEntry, writeFile } from "@jsenv/filesystem";
2
- import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/humanize";
2
+ import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/log";
3
+
3
4
  import { getAuthorityFileInfos } from "./internal/authority_file_infos.js";
4
5
  import { attributeDescriptionFromAttributeArray } from "./internal/certificate_data_converter.js";
5
6
  import { createAuthorityRootCertificate } from "./internal/certificate_generator.js";
@@ -212,7 +213,7 @@ export const installCertificateAuthority = async ({
212
213
  certificateValidityDurationInMs,
213
214
  },
214
215
  );
215
- if (rootCertificateDifferences.length) {
216
+ if (Object.keys(rootCertificateDifferences).length) {
216
217
  const paramNames = Object.keys(rootCertificateDifferences);
217
218
  logger.info(
218
219
  `${UNICODE.INFO} certificate attributes are outdated: ${paramNames}`,
@@ -326,13 +327,13 @@ export const uninstallCertificateAuthority = async ({
326
327
  const rootCertificateCommonName = attributeDescriptionFromAttributeArray(
327
328
  rootCertificateForgeObject.subject.attributes,
328
329
  ).commonName;
329
- const platformMethods = await importPlatformMethods();
330
- await platformMethods.executeTrustQuery({
330
+ const { removeCertificateFromTrustStores } =
331
+ await importPlatformMethods();
332
+ await removeCertificateFromTrustStores({
331
333
  logger,
332
- certificateCommonName: rootCertificateCommonName,
333
- certificateFileUrl: rootCertificateFileInfo.url,
334
334
  certificate: rootCertificate,
335
- verb: "REMOVE_TRUST",
335
+ certificateFileUrl: rootCertificateFileInfo.url,
336
+ certificateCommonName: rootCertificateCommonName,
336
337
  });
337
338
  }
338
339
  filesToRemove.push(rootCertificateFileInfo.url);
@@ -1,6 +1,7 @@
1
1
  import { writeFileSync } from "@jsenv/filesystem";
2
- import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/humanize";
2
+ import { UNICODE, createDetailedMessage, createLogger } from "@jsenv/log";
3
3
  import { readFileSync } from "node:fs";
4
+
4
5
  import { getAuthorityFileInfos } from "./internal/authority_file_infos.js";
5
6
  import { requestCertificateFromAuthority } from "./internal/certificate_generator.js";
6
7
  import { forge } from "./internal/forge.js";
@@ -46,9 +47,7 @@ export const requestCertificate = ({
46
47
  } = getAuthorityFileInfos();
47
48
  if (!rootCertificateFileInfo.exists) {
48
49
  throw new Error(
49
- `Certificate authority not found, "installCertificateAuthority" must be called before "requestServerCertificate".
50
- --- Suggested command to run ---
51
- npx @jsenv/https-local install --trust`,
50
+ `Certificate authority not found, "installCertificateAuthority" must be called before "requestServerCertificate"`,
52
51
  );
53
52
  }
54
53
  if (!rootCertificatePrivateKeyFileInfo.exists) {
@@ -85,6 +84,7 @@ npx @jsenv/https-local install --trust`,
85
84
  logger.debug(`Generating server certificate...`);
86
85
  const { certificateForgeObject, certificatePrivateKeyForgeObject } =
87
86
  requestCertificateFromAuthority({
87
+ logger,
88
88
  authorityCertificateForgeObject: rootCertificateForgeObject,
89
89
  auhtorityCertificatePrivateKeyForgeObject:
90
90
  rootCertificatePrivateKeyForgeObject,
@@ -1,4 +1,5 @@
1
- import { createDetailedMessage, createLogger, UNICODE } from "@jsenv/humanize";
1
+ import { createDetailedMessage, createLogger, UNICODE } from "@jsenv/log";
2
+
2
3
  import {
3
4
  HOSTS_FILE_PATH,
4
5
  parseHosts,
@@ -1,5 +1,6 @@
1
1
  import { existsSync } from "node:fs";
2
2
  import { fileURLToPath } from "node:url";
3
+
3
4
  import { getCertificateAuthorityFileUrls } from "./certificate_authority_file_urls.js";
4
5
 
5
6
  export const getAuthorityFileInfos = () => {
@@ -8,8 +8,9 @@ export const parseHosts = (
8
8
  const lines = [];
9
9
  hosts.split(/\r?\n/).forEach((line) => {
10
10
  const lineWithoutComments = line.replace(/#.*/, "");
11
- // eslint-disable-next-line regexp/no-super-linear-backtracking
12
- const matches = /^\s*?(.+?)\s+(.+?)\s*$/.exec(lineWithoutComments);
11
+ const matches = /^\s*(\S+)\s+(\S+(?:\s+\S+)*)\s*$/.exec(
12
+ lineWithoutComments,
13
+ );
13
14
  if (matches && matches.length === 3) {
14
15
  const [, ip, host] = matches;
15
16
  const hostnames = host.split(" ");
@@ -1,4 +1,5 @@
1
1
  import { readFile } from "@jsenv/filesystem";
2
+
2
3
  import { HOSTS_FILE_PATH } from "./hosts_utils.js";
3
4
 
4
5
  export const readHostsFile = async (hostsFilePath = HOSTS_FILE_PATH) => {
@@ -1,5 +1,7 @@
1
1
  import { createRequire } from "node:module";
2
+
2
3
  import { exec } from "../exec.js";
4
+
3
5
  import { HOSTS_FILE_PATH } from "./hosts_utils.js";
4
6
 
5
7
  export const writeHostsFile = async (
@@ -1,6 +1,8 @@
1
1
  import { readFile } from "@jsenv/filesystem";
2
2
  import { createRequire } from "node:module";
3
+
3
4
  import { exec } from "../exec.js";
5
+
4
6
  import { HOSTS_FILE_PATH } from "./hosts_utils.js";
5
7
 
6
8
  export const writeLineInHostsFile = async (
@@ -1,6 +1,7 @@
1
1
  import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
2
- import { UNICODE } from "@jsenv/humanize";
2
+ import { UNICODE } from "@jsenv/log";
3
3
  import { execSync } from "node:child_process";
4
+
4
5
  import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js";
5
6
  import {
6
7
  detectIfNSSIsInstalled,
@@ -1,6 +1,7 @@
1
1
  import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
2
- import { UNICODE } from "@jsenv/humanize";
2
+ import { UNICODE } from "@jsenv/log";
3
3
  import { execSync } from "node:child_process";
4
+
4
5
  import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js";
5
6
  import {
6
7
  detectIfNSSIsInstalled,
@@ -13,6 +13,7 @@ export const executeTrustQuery = async ({
13
13
  }) => {
14
14
  const linuxTrustInfo = await executeTrustQueryOnLinux({
15
15
  logger,
16
+ certificateCommonName,
16
17
  certificateFileUrl,
17
18
  certificateIsNew,
18
19
  certificate,
@@ -3,9 +3,10 @@
3
3
  */
4
4
 
5
5
  import { readFile } from "@jsenv/filesystem";
6
- import { createDetailedMessage, UNICODE } from "@jsenv/humanize";
6
+ import { createDetailedMessage, UNICODE } from "@jsenv/log";
7
7
  import { existsSync } from "node:fs";
8
8
  import { fileURLToPath } from "node:url";
9
+
9
10
  import { exec } from "../exec.js";
10
11
  import {
11
12
  VERB_ADD_TRUST,
@@ -1,6 +1,7 @@
1
1
  // https://github.com/FiloSottile/mkcert/issues/447
2
2
 
3
- import { UNICODE } from "@jsenv/humanize";
3
+ import { UNICODE } from "@jsenv/log";
4
+
4
5
  import { exec } from "../exec.js";
5
6
  import { memoize } from "../memoize.js";
6
7
 
@@ -1,5 +1,6 @@
1
- import { UNICODE } from "@jsenv/humanize";
1
+ import { UNICODE } from "@jsenv/log";
2
2
  import { existsSync } from "node:fs";
3
+
3
4
  import { memoize } from "../memoize.js";
4
5
 
5
6
  const REASON_CHROME_NOT_DETECTED = `Chrome not detected`;
@@ -1,6 +1,7 @@
1
1
  import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
2
- import { UNICODE, createTaskLog } from "@jsenv/humanize";
2
+ import { UNICODE, createTaskLog } from "@jsenv/log";
3
3
  import { execSync } from "node:child_process";
4
+
4
5
  import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js";
5
6
  import {
6
7
  detectIfNSSIsInstalled,
@@ -44,6 +44,7 @@ export const executeTrustQuery = async ({
44
44
  });
45
45
 
46
46
  const safariTrustInfo = await executeTrustQueryOnSafari({
47
+ logger,
47
48
  // safari needs macTrustInfo because it uses OS trust store
48
49
  macTrustInfo,
49
50
  });
@@ -1,7 +1,8 @@
1
1
  // https://ss64.com/osx/security.html
2
2
 
3
- import { createDetailedMessage, UNICODE } from "@jsenv/humanize";
3
+ import { createDetailedMessage, UNICODE } from "@jsenv/log";
4
4
  import { fileURLToPath } from "node:url";
5
+
5
6
  import { exec } from "../exec.js";
6
7
  import { searchCertificateInCommandOutput } from "../search_certificate_in_command_output.js";
7
8
  import {
@@ -1,6 +1,7 @@
1
1
  import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
2
- import { UNICODE } from "@jsenv/humanize";
2
+ import { UNICODE } from "@jsenv/log";
3
3
  import { fileURLToPath } from "node:url";
4
+
4
5
  import { commandExists } from "../command.js";
5
6
  import { exec } from "../exec.js";
6
7
  import { memoize } from "../memoize.js";
@@ -7,10 +7,11 @@ import {
7
7
  assertAndNormalizeDirectoryUrl,
8
8
  collectFiles,
9
9
  } from "@jsenv/filesystem";
10
- import { createDetailedMessage, UNICODE } from "@jsenv/humanize";
10
+ import { createDetailedMessage, UNICODE } from "@jsenv/log";
11
11
  import { urlToFilename } from "@jsenv/urls";
12
12
  import { existsSync } from "node:fs";
13
13
  import { fileURLToPath } from "node:url";
14
+
14
15
  import { detectBrowser } from "./browser_detection.js";
15
16
  import { exec } from "./exec.js";
16
17
  import { searchCertificateInCommandOutput } from "./search_certificate_in_command_output.js";
@@ -1,4 +1,4 @@
1
- import { UNICODE } from "@jsenv/humanize";
1
+ import { UNICODE } from "@jsenv/log";
2
2
 
3
3
  const platformTrustInfo = {
4
4
  status: "unknown",
@@ -1,6 +1,7 @@
1
- import { UNICODE } from "@jsenv/humanize";
1
+ import { UNICODE } from "@jsenv/log";
2
2
  import { existsSync } from "node:fs";
3
3
  import { createRequire } from "node:module";
4
+
4
5
  import { memoize } from "../memoize.js";
5
6
 
6
7
  const require = createRequire(import.meta.url);
@@ -3,9 +3,10 @@
3
3
  * - A way to install and use NSS command on windows to update firefox NSS dabatase file
4
4
  */
5
5
 
6
- import { UNICODE } from "@jsenv/humanize";
6
+ import { UNICODE } from "@jsenv/log";
7
7
  import { existsSync } from "node:fs";
8
8
  import { createRequire } from "node:module";
9
+
9
10
  import { memoize } from "../memoize.js";
10
11
 
11
12
  const require = createRequire(import.meta.url);
@@ -14,6 +14,7 @@ export const executeTrustQuery = async ({
14
14
  certificateCommonName,
15
15
  certificateFileUrl,
16
16
  certificateIsNew,
17
+ certificate,
17
18
  verb,
18
19
  }) => {
19
20
  const windowsTrustInfo = await executeTrustQueryOnWindows({
@@ -21,6 +22,7 @@ export const executeTrustQuery = async ({
21
22
  certificateCommonName,
22
23
  certificateFileUrl,
23
24
  certificateIsNew,
25
+ certificate,
24
26
  verb,
25
27
  });
26
28
 
@@ -3,8 +3,9 @@
3
3
  * https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil
4
4
  */
5
5
 
6
- import { createDetailedMessage, UNICODE } from "@jsenv/humanize";
6
+ import { createDetailedMessage, UNICODE } from "@jsenv/log";
7
7
  import { fileURLToPath } from "node:url";
8
+
8
9
  import { exec } from "../exec.js";
9
10
  import {
10
11
  VERB_ADD_TRUST,
package/src/main.js CHANGED
@@ -12,9 +12,12 @@ export {
12
12
  installCertificateAuthority,
13
13
  uninstallCertificateAuthority,
14
14
  } from "./certificate_authority.js";
15
- export { requestCertificate } from "./certificate_request.js";
16
- export { verifyHostsFile } from "./hosts_file_verif.js";
15
+
17
16
  export {
18
17
  createValidityDurationOfXDays,
19
18
  createValidityDurationOfXYears,
20
19
  } from "./validity_duration.js";
20
+
21
+ export { verifyHostsFile } from "./hosts_file_verif.js";
22
+
23
+ export { requestCertificate } from "./certificate_request.js";
@@ -1,89 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import {
4
- installCertificateAuthority,
5
- uninstallCertificateAuthority,
6
- verifyHostsFile,
7
- } from "@jsenv/https-local";
8
- import { parseArgs } from "node:util";
9
-
10
- const options = {
11
- help: {
12
- type: "boolean",
13
- },
14
- trust: {
15
- type: "boolean",
16
- },
17
- };
18
- const { values, positionals } = parseArgs({
19
- options,
20
- allowPositionals: true,
21
- });
22
-
23
- if (values.help || positionals.length === 0) {
24
- console.log(`https-local: Generate https certificates to use on your machine.
25
-
26
- Usage:
27
-
28
- npx @jsenv/https-local setup
29
- Install root certificate, try to trust it and ensure localhost is mapped to 127.0.0.1
30
-
31
- npx @jsenv/https-local install --trust
32
- Install root certificate on the filesystem
33
- - trust: Try to add root certificate to os and browser trusted stores.
34
-
35
- npx @jsenv/https-local uninstall
36
- Uninstall root certificate from the filesystem
37
-
38
- npx @jsenv/https-local localhost-mapping
39
- Ensure localhost mapping to 127.0.0.1 is set on the filesystem
40
-
41
- https://github.com/jsenv/core/tree/main/packages/tooling/https-local
42
-
43
- `);
44
-
45
- process.exit(0);
46
- }
47
-
48
- const commandHandlers = {
49
- setup: async () => {
50
- await installCertificateAuthority({
51
- tryToTrust: true,
52
- NSSDynamicInstall: true,
53
- });
54
- await verifyHostsFile({
55
- ipMappings: {
56
- "127.0.0.1": ["localhost"],
57
- },
58
- tryToUpdateHostsFile: true,
59
- });
60
- },
61
- install: async ({ trust }) => {
62
- await installCertificateAuthority({
63
- tryToTrust: trust,
64
- NSSDynamicInstall: trust,
65
- });
66
- },
67
- uninstall: async () => {
68
- await uninstallCertificateAuthority({
69
- tryToUntrust: true,
70
- });
71
- },
72
- ["localhost-mapping"]: async () => {
73
- await verifyHostsFile({
74
- ipMappings: {
75
- "127.0.0.1": ["localhost"],
76
- },
77
- tryToUpdateHostsFile: true,
78
- });
79
- },
80
- };
81
-
82
- const [command] = positionals;
83
- const commandHandler = commandHandlers[command];
84
- if (!commandHandler) {
85
- console.error(`Error: unknown command ${command}.`);
86
- process.exit(1);
87
- }
88
-
89
- await commandHandler(values);