@jsenv/https-local 1.0.10 → 2.0.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
@@ -67,13 +67,12 @@ node ./install_certificate_authority.mjs
67
67
  import { createServer } from "node:https"
68
68
  import { requestCertificateForLocalhost } from "@jsenv/https-local"
69
69
 
70
- const { serverCertificate, serverCertificatePrivateKey } =
71
- await requestCertificateForLocalhost()
70
+ const { certificate, privateKey } = requestCertificateForLocalhost()
72
71
 
73
72
  const server = createServer(
74
73
  {
75
- cert: serverCertificate,
76
- key: serverCertificatePrivateKey,
74
+ cert: certificate,
75
+ key: privateKey,
77
76
  },
78
77
  (request, response) => {
79
78
  const body = "Hello world"
@@ -361,10 +360,9 @@ _requestCertificateForLocalhost_ function returns a certificate and private key
361
360
  import { createServer } from "node:https"
362
361
  import { requestCertificateForLocalhost } from "@jsenv/https-local"
363
362
 
364
- const { serverCertificate, serverCertificatePrivateKey } =
365
- await requestCertificateForLocalhost({
366
- serverCertificateAltNames: ["localhost", "local.example"],
367
- })
363
+ const { certificate, privateKey } = requestCertificateForLocalhost({
364
+ altNames: ["localhost", "local.example"],
365
+ })
368
366
  ```
369
367
 
370
368
  [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.10",
3
+ "version": "2.0.0",
4
4
  "description": "A programmatic way to generate locally trusted certificates",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -13,7 +13,8 @@
13
13
  "url": "https://github.com/jsenv/https-local"
14
14
  },
15
15
  "publishConfig": {
16
- "access": "public"
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org"
17
18
  },
18
19
  "engines": {
19
20
  "node": ">=16.13.0"
@@ -21,14 +22,13 @@
21
22
  "type": "module",
22
23
  "exports": {
23
24
  ".": {
24
- "import": "./main.js"
25
+ "import": "./src/main.js"
25
26
  },
26
27
  "./*": "./*"
27
28
  },
28
- "main": "./main.js",
29
+ "main": "./src/main.js",
29
30
  "files": [
30
- "/src/",
31
- "/main.js"
31
+ "/src/"
32
32
  ],
33
33
  "scripts": {
34
34
  "eslint": "npx eslint . --ext=.js,.mjs,.cjs",
@@ -48,27 +48,25 @@
48
48
  "playwright-install": "npx playwright install-deps && npx playwright install"
49
49
  },
50
50
  "dependencies": {
51
- "@jsenv/eslint-import-resolver": "0.1.7",
52
- "@jsenv/filesystem": "3.2.2",
53
- "@jsenv/log": "1.6.0",
54
- "@jsenv/logger": "4.0.1",
51
+ "@jsenv/filesystem": "4.1.0",
52
+ "@jsenv/log": "2.0.1",
53
+ "@jsenv/urls": "1.2.6",
55
54
  "command-exists": "1.2.9",
56
55
  "node-forge": "1.3.1",
57
56
  "sudo-prompt": "9.2.1",
58
57
  "which": "2.0.2"
59
58
  },
60
59
  "devDependencies": {
61
- "@jsenv/assert": "2.5.4",
62
- "@jsenv/core": "27.0.0-alpha.61",
60
+ "@jsenv/assert": "2.6.0",
61
+ "@jsenv/core": "27.0.0-alpha.92",
63
62
  "@jsenv/eslint-config": "16.0.9",
63
+ "@jsenv/eslint-import-resolver": "0.3.0",
64
64
  "@jsenv/github-release-package": "1.4.0",
65
- "@jsenv/importmap-eslint-resolver": "5.2.5",
66
- "@jsenv/importmap-node-module": "5.1.3",
67
- "@jsenv/package-publish": "1.7.4",
68
- "@jsenv/performance-impact": "2.2.11",
69
- "eslint": "8.16.0",
65
+ "@jsenv/package-publish": "1.7.5",
66
+ "@jsenv/performance-impact": "2.3.0",
67
+ "eslint": "8.18.0",
70
68
  "eslint-plugin-import": "2.26.0",
71
69
  "playwright": "1.22.2",
72
- "prettier": "2.6.2"
70
+ "prettier": "2.7.1"
73
71
  }
74
- }
72
+ }
@@ -1,14 +1,13 @@
1
1
  import { readFile, writeFile, removeEntry } from "@jsenv/filesystem"
2
- import { createLogger, createDetailedMessage } from "@jsenv/logger"
3
- import { UNICODE } from "@jsenv/log"
2
+ import { UNICODE, createLogger, createDetailedMessage } from "@jsenv/log"
4
3
 
4
+ import { forge } from "./internal/forge.js"
5
5
  import { getAuthorityFileInfos } from "./internal/authority_file_infos.js"
6
6
  import { attributeDescriptionFromAttributeArray } from "./internal/certificate_data_converter.js"
7
7
  import {
8
8
  formatTimeDelta,
9
9
  formatDuration,
10
10
  } from "./internal/validity_formatting.js"
11
- import { importNodeForge } from "./internal/forge.js"
12
11
  import { createAuthorityRootCertificate } from "./internal/certificate_generator.js"
13
12
  import { importPlatformMethods } from "./internal/platform.js"
14
13
  import { jsenvParameters } from "./jsenvParameters.js"
@@ -79,7 +78,7 @@ export const installCertificateAuthority = async ({
79
78
  serialNumber: 0,
80
79
  })
81
80
 
82
- const { pki } = await importNodeForge()
81
+ const { pki } = forge
83
82
  const rootCertificate = pemAsFileContent(
84
83
  pki.certificateToPem(rootCertificateForgeObject),
85
84
  )
@@ -173,7 +172,7 @@ export const installCertificateAuthority = async ({
173
172
  const rootCertificate = await readFile(rootCertificateFileInfo.path, {
174
173
  as: "string",
175
174
  })
176
- const { pki } = await importNodeForge()
175
+ const { pki } = forge
177
176
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
178
177
 
179
178
  logger.info(`Checking certificate validity...`)
@@ -323,7 +322,7 @@ export const uninstallCertificateAuthority = async ({
323
322
  const rootCertificate = await readFile(rootCertificateFileInfo.url, {
324
323
  as: "string",
325
324
  })
326
- const { pki } = await importNodeForge()
325
+ const { pki } = forge
327
326
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
328
327
  const rootCertificateCommonName = attributeDescriptionFromAttributeArray(
329
328
  rootCertificateForgeObject.subject.attributes,
@@ -1,39 +1,38 @@
1
- import { readFile, writeFile } from "@jsenv/filesystem"
2
- import { createLogger, createDetailedMessage } from "@jsenv/logger"
3
- import { UNICODE } from "@jsenv/log"
1
+ import { readFileSync } from "node:fs"
2
+ import { writeFileSync } from "@jsenv/filesystem"
3
+ import { UNICODE, createLogger, createDetailedMessage } from "@jsenv/log"
4
4
 
5
+ import { forge } from "./internal/forge.js"
5
6
  import {
6
7
  createValidityDurationOfXDays,
7
8
  verifyServerCertificateValidityDuration,
8
9
  } from "./validity_duration.js"
9
10
  import { getAuthorityFileInfos } from "./internal/authority_file_infos.js"
10
- import { importNodeForge } from "./internal/forge.js"
11
11
  import { requestCertificateFromAuthority } from "./internal/certificate_generator.js"
12
12
  import { formatDuration } from "./internal/validity_formatting.js"
13
13
 
14
- export const requestCertificateForLocalhost = async ({
14
+ export const requestCertificateForLocalhost = ({
15
15
  logLevel,
16
16
  logger = createLogger({ logLevel }), // to be able to catch logs during unit tests
17
17
 
18
- serverCertificateAltNames = ["localhost"],
19
- serverCertificateCommonName = "https local server certificate",
20
- serverCertificateValidityDurationInMs = createValidityDurationOfXDays(396),
18
+ altNames = ["localhost"],
19
+ commonName = "https local server certificate",
20
+ validityDurationInMs = createValidityDurationOfXDays(396),
21
21
  } = {}) => {
22
- if (typeof serverCertificateValidityDurationInMs !== "number") {
22
+ if (typeof validityDurationInMs !== "number") {
23
23
  throw new TypeError(
24
- `serverCertificateValidityDurationInMs must be a number but received ${serverCertificateValidityDurationInMs}`,
24
+ `validityDurationInMs must be a number but received ${validityDurationInMs}`,
25
25
  )
26
26
  }
27
- if (serverCertificateValidityDurationInMs < 1) {
27
+ if (validityDurationInMs < 1) {
28
28
  throw new TypeError(
29
- `serverCertificateValidityDurationInMs must be > 0 but received ${serverCertificateValidityDurationInMs}`,
29
+ `validityDurationInMs must be > 0 but received ${validityDurationInMs}`,
30
30
  )
31
31
  }
32
- const validityDurationInfo = verifyServerCertificateValidityDuration(
33
- serverCertificateValidityDurationInMs,
34
- )
32
+ const validityDurationInfo =
33
+ verifyServerCertificateValidityDuration(validityDurationInMs)
35
34
  if (!validityDurationInfo.ok) {
36
- serverCertificateValidityDurationInMs = validityDurationInfo.maxAllowedValue
35
+ validityDurationInMs = validityDurationInfo.maxAllowedValue
37
36
  logger.warn(
38
37
  createDetailedMessage(validityDurationInfo.message, {
39
38
  details: validityDurationInfo.details,
@@ -59,19 +58,16 @@ export const requestCertificateForLocalhost = async ({
59
58
  }
60
59
 
61
60
  logger.debug(`Restoring certificate authority from filesystem...`)
62
- const { pki } = await importNodeForge()
63
- const rootCertificate = await readFile(rootCertificateFileInfo.url, {
64
- as: "string",
65
- })
66
- const rootCertificatePrivateKey = await readFile(
67
- rootCertificatePrivateKeyFileInfo.url,
68
- {
69
- as: "string",
70
- },
61
+ const { pki } = forge
62
+ const rootCertificate = String(
63
+ readFileSync(new URL(rootCertificateFileInfo.url)),
64
+ )
65
+ const rootCertificatePrivateKey = String(
66
+ readFileSync(new URL(rootCertificatePrivateKeyFileInfo.url)),
67
+ )
68
+ const certificateAuthorityData = JSON.parse(
69
+ String(readFileSync(new URL(authorityJsonFileInfo.url))),
71
70
  )
72
- const certificateAuthorityData = await readFile(authorityJsonFileInfo.url, {
73
- as: "json",
74
- })
75
71
  const rootCertificateForgeObject = pki.certificateFromPem(rootCertificate)
76
72
  const rootCertificatePrivateKeyForgeObject = pki.privateKeyFromPem(
77
73
  rootCertificatePrivateKey,
@@ -80,26 +76,26 @@ export const requestCertificateForLocalhost = async ({
80
76
 
81
77
  const serverCertificateSerialNumber =
82
78
  certificateAuthorityData.serialNumber + 1
83
- await writeFile(
79
+ writeFileSync(
84
80
  authorityJsonFileInfo.url,
85
81
  JSON.stringify({ serialNumber: serverCertificateSerialNumber }, null, " "),
86
82
  )
87
83
 
88
- if (!serverCertificateAltNames.includes("localhost")) {
89
- serverCertificateAltNames.push("localhost")
84
+ if (!altNames.includes("localhost")) {
85
+ altNames.push("localhost")
90
86
  }
91
87
 
92
88
  logger.debug(`Generating server certificate...`)
93
89
  const { certificateForgeObject, certificatePrivateKeyForgeObject } =
94
- await requestCertificateFromAuthority({
90
+ requestCertificateFromAuthority({
95
91
  logger,
96
92
  authorityCertificateForgeObject: rootCertificateForgeObject,
97
93
  auhtorityCertificatePrivateKeyForgeObject:
98
94
  rootCertificatePrivateKeyForgeObject,
99
95
  serialNumber: serverCertificateSerialNumber,
100
- altNames: serverCertificateAltNames,
101
- commonName: serverCertificateCommonName,
102
- validityDurationInMs: serverCertificateValidityDurationInMs,
96
+ altNames,
97
+ commonName,
98
+ validityDurationInMs,
103
99
  })
104
100
  const serverCertificate = pki.certificateToPem(certificateForgeObject)
105
101
  const serverCertificatePrivateKey = pki.privateKeyToPem(
@@ -109,13 +105,13 @@ export const requestCertificateForLocalhost = async ({
109
105
  `${
110
106
  UNICODE.OK
111
107
  } server certificate generated, it will be valid for ${formatDuration(
112
- serverCertificateValidityDurationInMs,
108
+ validityDurationInMs,
113
109
  )}`,
114
110
  )
115
111
 
116
112
  return {
117
- serverCertificate,
118
- serverCertificatePrivateKey,
113
+ certificate: serverCertificate,
114
+ privateKey: serverCertificatePrivateKey,
119
115
  rootCertificateFilePath: rootCertificateFileInfo.path,
120
116
  }
121
117
  }
@@ -1,5 +1,4 @@
1
- import { createDetailedMessage, createLogger } from "@jsenv/logger"
2
- import { UNICODE } from "@jsenv/log"
1
+ import { createDetailedMessage, createLogger, UNICODE } from "@jsenv/log"
3
2
 
4
3
  import {
5
4
  HOSTS_FILE_PATH,
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from "node:fs"
2
- import { urlToFileSystemPath } from "@jsenv/filesystem"
2
+ import { fileURLToPath } from "node:url"
3
3
 
4
4
  import { getCertificateAuthorityFileUrls } from "./certificate_authority_file_urls.js"
5
5
 
@@ -10,15 +10,13 @@ export const getAuthorityFileInfos = () => {
10
10
  rootCertificatePrivateKeyFileUrl,
11
11
  } = getCertificateAuthorityFileUrls()
12
12
 
13
- const authorityJsonFilePath = urlToFileSystemPath(
14
- certificateAuthorityJsonFileUrl,
15
- )
13
+ const authorityJsonFilePath = fileURLToPath(certificateAuthorityJsonFileUrl)
16
14
  const authorityJsonFileDetected = existsSync(authorityJsonFilePath)
17
15
 
18
- const rootCertificateFilePath = urlToFileSystemPath(rootCertificateFileUrl)
16
+ const rootCertificateFilePath = fileURLToPath(rootCertificateFileUrl)
19
17
  const rootCertificateFileDetected = existsSync(rootCertificateFilePath)
20
18
 
21
- const rootCertificatePrivateKeyFilePath = urlToFileSystemPath(
19
+ const rootCertificatePrivateKeyFilePath = fileURLToPath(
22
20
  rootCertificatePrivateKeyFileUrl,
23
21
  )
24
22
  const rootCertificatePrivateKeyFileDetected = existsSync(
@@ -1,8 +1,5 @@
1
- import {
2
- assertAndNormalizeDirectoryUrl,
3
- resolveUrl,
4
- urlToFilename,
5
- } from "@jsenv/filesystem"
1
+ import { urlToFilename } from "@jsenv/urls"
2
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
6
3
 
7
4
  export const getCertificateAuthorityFileUrls = () => {
8
5
  // we need a directory common to every instance of @jsenv/https-local
@@ -20,10 +17,10 @@ export const getCertificateAuthorityFileUrls = () => {
20
17
  applicationDirectoryUrl,
21
18
  )
22
19
 
23
- const rootCertificatePrivateKeyFileUrl = resolveUrl(
20
+ const rootCertificatePrivateKeyFileUrl = new URL(
24
21
  "./https_local_root_certificate.key",
25
22
  applicationDirectoryUrl,
26
- )
23
+ ).href
27
24
 
28
25
  return {
29
26
  certificateAuthorityJsonFileUrl,
@@ -37,18 +34,19 @@ export const getRootCertificateSymlinkUrls = ({
37
34
  rootPrivateKeyFileUrl,
38
35
  serverCertificateFileUrl,
39
36
  }) => {
40
- const serverCertificateDirectory = resolveUrl("./", serverCertificateFileUrl)
37
+ const serverCertificateDirectory = new URL("./", serverCertificateFileUrl)
38
+ .href
41
39
 
42
40
  const rootCertificateFilename = urlToFilename(rootCertificateFileUrl)
43
- const rootCertificateSymlinkUrl = resolveUrl(
41
+ const rootCertificateSymlinkUrl = new URL(
44
42
  rootCertificateFilename,
45
43
  serverCertificateDirectory,
46
- )
44
+ ).href
47
45
  const rootPrivateKeyFilename = urlToFilename(rootPrivateKeyFileUrl)
48
- const rootPrivateKeySymlinkUrl = resolveUrl(
46
+ const rootPrivateKeySymlinkUrl = new URL(
49
47
  rootPrivateKeyFilename,
50
48
  serverCertificateDirectory,
51
- )
49
+ ).href
52
50
 
53
51
  return {
54
52
  rootCertificateSymlinkUrl,
@@ -61,37 +59,37 @@ const getJsenvApplicationDirectoryUrl = () => {
61
59
  const { platform } = process
62
60
 
63
61
  if (platform === "darwin") {
64
- return resolveUrl(
62
+ return new URL(
65
63
  `./Library/Application Support/https_local/`,
66
64
  assertAndNormalizeDirectoryUrl(process.env.HOME),
67
- )
65
+ ).href
68
66
  }
69
67
 
70
68
  if (platform === "linux") {
71
69
  if (process.env.XDG_CONFIG_HOME) {
72
- return resolveUrl(
70
+ return new URL(
73
71
  `./https_local/`,
74
72
  assertAndNormalizeDirectoryUrl(process.env.XDG_CONFIG_HOME),
75
- )
73
+ ).href
76
74
  }
77
- return resolveUrl(
75
+ return new URL(
78
76
  `./.config/https_local/`,
79
77
  assertAndNormalizeDirectoryUrl(process.env.HOME),
80
- )
78
+ ).href
81
79
  }
82
80
 
83
81
  if (platform === "win32") {
84
82
  if (process.env.LOCALAPPDATA) {
85
- return resolveUrl(
83
+ return new URL(
86
84
  `./https_local/`,
87
85
  assertAndNormalizeDirectoryUrl(process.env.LOCALAPPDATA),
88
- )
86
+ ).href
89
87
  }
90
88
 
91
- return resolveUrl(
89
+ return new URL(
92
90
  `./Local Settings/Application Data/https_local/`,
93
91
  assertAndNormalizeDirectoryUrl(process.env.USERPROFILE),
94
- )
92
+ ).href
95
93
  }
96
94
 
97
95
  throw new Error(`platform not supported`)
@@ -1,7 +1,7 @@
1
1
  // https://github.com/digitalbazaar/forge/blob/master/examples/create-cert.js
2
2
  // https://github.com/digitalbazaar/forge/issues/660#issuecomment-467145103
3
3
 
4
- import { importNodeForge } from "./forge.js"
4
+ import { forge } from "./forge.js"
5
5
  import {
6
6
  attributeArrayFromAttributeDescription,
7
7
  attributeDescriptionFromAttributeArray,
@@ -23,7 +23,6 @@ export const createAuthorityRootCertificate = async ({
23
23
  throw new TypeError(`serial must be a number but received ${serialNumber}`)
24
24
  }
25
25
 
26
- const forge = await importNodeForge()
27
26
  const { pki } = forge
28
27
  const rootCertificateForgeObject = pki.createCertificate()
29
28
  const keyPair = pki.rsa.generateKeyPair(2048) // TODO: use async version https://github.com/digitalbazaar/forge#rsa
@@ -86,7 +85,7 @@ export const createAuthorityRootCertificate = async ({
86
85
  }
87
86
  }
88
87
 
89
- export const requestCertificateFromAuthority = async ({
88
+ export const requestCertificateFromAuthority = ({
90
89
  authorityCertificateForgeObject, // could be intermediate or root certificate authority
91
90
  auhtorityCertificatePrivateKeyForgeObject,
92
91
  serialNumber,
@@ -116,7 +115,6 @@ export const requestCertificateFromAuthority = async ({
116
115
  )
117
116
  }
118
117
 
119
- const forge = await importNodeForge()
120
118
  const { pki } = forge
121
119
  const certificateForgeObject = pki.createCertificate()
122
120
  const keyPair = pki.rsa.generateKeyPair(2048) // TODO: use async version https://github.com/digitalbazaar/forge#rsa
@@ -2,6 +2,4 @@ import { createRequire } from "node:module"
2
2
 
3
3
  const require = createRequire(import.meta.url)
4
4
 
5
- export const importNodeForge = async () => {
6
- return require("node-forge")
7
- }
5
+ export const forge = require("node-forge")
@@ -1,8 +1,9 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { execSync } from "node:child_process"
3
- import { resolveUrl, assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
4
-
3
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
5
4
  import { UNICODE } from "@jsenv/log"
5
+
6
+ import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
6
7
  import {
7
8
  nssCommandName,
8
9
  detectIfNSSIsInstalled,
@@ -10,8 +11,6 @@ import {
10
11
  getCertutilBinPath,
11
12
  } from "./nss_linux.js"
12
13
 
13
- import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
14
-
15
14
  export const executeTrustQueryOnChrome = ({
16
15
  logger,
17
16
  certificateCommonName,
@@ -48,10 +47,10 @@ export const executeTrustQueryOnChrome = ({
48
47
  logger.debug(`${UNICODE.INFO} Chrome not detected`)
49
48
  return false
50
49
  },
51
- browserNSSDBDirectoryUrl: resolveUrl(
50
+ browserNSSDBDirectoryUrl: new URL(
52
51
  ".pki/nssdb",
53
52
  assertAndNormalizeDirectoryUrl(process.env.HOME),
54
- ),
53
+ ).href,
55
54
  getBrowserClosedPromise: async () => {
56
55
  if (!isChromeOpen()) {
57
56
  return
@@ -1,8 +1,9 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { execSync } from "node:child_process"
3
- import { resolveUrl, assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
3
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
4
4
  import { UNICODE } from "@jsenv/log"
5
5
 
6
+ import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
6
7
  import {
7
8
  nssCommandName,
8
9
  detectIfNSSIsInstalled,
@@ -10,8 +11,6 @@ import {
10
11
  getCertutilBinPath,
11
12
  } from "./nss_linux.js"
12
13
 
13
- import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
14
-
15
14
  export const executeTrustQueryOnFirefox = ({
16
15
  logger,
17
16
  certificateCommonName,
@@ -48,10 +47,10 @@ export const executeTrustQueryOnFirefox = ({
48
47
  logger.debug(`${UNICODE.INFO} Firefox not detected`)
49
48
  return false
50
49
  },
51
- browserNSSDBDirectoryUrl: resolveUrl(
50
+ browserNSSDBDirectoryUrl: new URL(
52
51
  ".mozilla/firefox/",
53
52
  assertAndNormalizeDirectoryUrl(process.env.HOME),
54
- ),
53
+ ).href,
55
54
  getBrowserClosedPromise: async () => {
56
55
  if (!isFirefoxOpen()) {
57
56
  return
@@ -3,16 +3,16 @@
3
3
  */
4
4
 
5
5
  import { existsSync } from "node:fs"
6
- import { createDetailedMessage } from "@jsenv/logger"
7
- import { readFile, urlToFileSystemPath } from "@jsenv/filesystem"
8
- import { UNICODE } from "@jsenv/log"
6
+ import { fileURLToPath } from "node:url"
7
+ import { readFile } from "@jsenv/filesystem"
8
+ import { createDetailedMessage, UNICODE } from "@jsenv/log"
9
9
 
10
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
11
10
  import {
12
11
  VERB_CHECK_TRUST,
13
12
  VERB_ADD_TRUST,
14
13
  VERB_REMOVE_TRUST,
15
14
  } from "../trust_query.js"
15
+ import { exec } from "../exec.js"
16
16
 
17
17
  const REASON_NEW_AND_TRY_TO_TRUST_DISABLED =
18
18
  "certificate is new and tryToTrust is disabled"
@@ -50,7 +50,7 @@ export const executeTrustQueryOnLinux = async ({
50
50
  logger.debug(
51
51
  `Searching certificate file at ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}...`,
52
52
  )
53
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
53
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
54
54
  const certificateStatus = await getCertificateStatus({ certificate })
55
55
 
56
56
  if (certificateStatus === "missing" || certificateStatus === "outdated") {
@@ -1,7 +1,7 @@
1
1
  import { UNICODE } from "@jsenv/log"
2
2
 
3
- import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
4
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
3
+ import { memoize } from "../memoize.js"
4
+ import { exec } from "../exec.js"
5
5
 
6
6
  export const nssCommandName = "libnss3-tools"
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { UNICODE } from "@jsenv/log"
3
3
 
4
- import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
4
+ import { memoize } from "../memoize.js"
5
5
 
6
6
  const REASON_CHROME_NOT_DETECTED = `Chrome not detected`
7
7
 
@@ -1,6 +1,6 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { execSync } from "node:child_process"
3
- import { resolveUrl, assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
3
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
4
4
  import { UNICODE, createTaskLog } from "@jsenv/log"
5
5
 
6
6
  import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
@@ -47,10 +47,10 @@ export const executeTrustQueryOnFirefox = ({
47
47
  logger.debug(`${UNICODE.INFO} firefox not detected`)
48
48
  return false
49
49
  },
50
- browserNSSDBDirectoryUrl: resolveUrl(
50
+ browserNSSDBDirectoryUrl: new URL(
51
51
  `./Library/Application Support/Firefox/Profiles/`,
52
52
  assertAndNormalizeDirectoryUrl(process.env.HOME),
53
- ),
53
+ ).href,
54
54
  getBrowserClosedPromise: async () => {
55
55
  if (!isFirefoxOpen()) {
56
56
  return
@@ -1,11 +1,10 @@
1
1
  // https://ss64.com/osx/security.html
2
2
 
3
- import { urlToFileSystemPath } from "@jsenv/filesystem"
4
- import { createDetailedMessage } from "@jsenv/logger"
3
+ import { fileURLToPath } from "node:url"
4
+ import { createDetailedMessage, UNICODE } from "@jsenv/log"
5
5
 
6
- import { UNICODE } from "@jsenv/log"
7
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
8
- import { searchCertificateInCommandOutput } from "@jsenv/https-local/src/internal/search_certificate_in_command_output.js"
6
+ import { exec } from "../exec.js"
7
+ import { searchCertificateInCommandOutput } from "../search_certificate_in_command_output.js"
9
8
  import {
10
9
  VERB_CHECK_TRUST,
11
10
  VERB_ADD_TRUST,
@@ -62,7 +61,7 @@ export const executeTrustQueryOnMacKeychain = async ({
62
61
  }
63
62
  }
64
63
 
65
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
64
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
66
65
  // https://ss64.com/osx/security-cert.html
67
66
  const addTrustedCertCommand = `sudo security add-trusted-cert -d -r trustRoot -k ${systemKeychainPath} "${certificateFilePath}"`
68
67
  logger.info(`Adding certificate to mac keychain...`)
@@ -1,13 +1,10 @@
1
- import {
2
- assertAndNormalizeDirectoryUrl,
3
- resolveUrl,
4
- urlToFileSystemPath,
5
- } from "@jsenv/filesystem"
1
+ import { fileURLToPath } from "node:url"
2
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
6
3
  import { UNICODE } from "@jsenv/log"
7
4
 
8
- import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
9
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
10
- import { commandExists } from "@jsenv/https-local/src/internal/command.js"
5
+ import { memoize } from "../memoize.js"
6
+ import { exec } from "../exec.js"
7
+ import { commandExists } from "../command.js"
11
8
 
12
9
  export const nssCommandName = "nss"
13
10
 
@@ -31,8 +28,8 @@ export const getCertutilBinPath = memoize(async () => {
31
28
  const nssCommandDirectoryUrl = assertAndNormalizeDirectoryUrl(
32
29
  brewCommandOutput.trim(),
33
30
  )
34
- const certutilBinUrl = resolveUrl(`./bin/certutil`, nssCommandDirectoryUrl)
35
- const certutilBinPath = urlToFileSystemPath(certutilBinUrl)
31
+ const certutilBinUrl = new URL(`./bin/certutil`, nssCommandDirectoryUrl).href
32
+ const certutilBinPath = fileURLToPath(certutilBinUrl)
36
33
  return certutilBinPath
37
34
  })
38
35
 
@@ -4,18 +4,13 @@
4
4
  */
5
5
 
6
6
  import { existsSync } from "node:fs"
7
- import { createDetailedMessage } from "@jsenv/logger"
8
- import {
9
- assertAndNormalizeDirectoryUrl,
10
- collectFiles,
11
- resolveUrl,
12
- urlToFilename,
13
- urlToFileSystemPath,
14
- } from "@jsenv/filesystem"
15
- import { UNICODE } from "@jsenv/log"
7
+ import { fileURLToPath } from "node:url"
8
+ import { urlToFilename } from "@jsenv/urls"
9
+ import { createDetailedMessage, UNICODE } from "@jsenv/log"
10
+ import { assertAndNormalizeDirectoryUrl, collectFiles } from "@jsenv/filesystem"
16
11
 
17
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
18
- import { searchCertificateInCommandOutput } from "@jsenv/https-local/src/internal/search_certificate_in_command_output.js"
12
+ import { exec } from "./exec.js"
13
+ import { searchCertificateInCommandOutput } from "./search_certificate_in_command_output.js"
19
14
  import { VERB_CHECK_TRUST, VERB_ADD_TRUST } from "./trust_query.js"
20
15
 
21
16
  export const executeTrustQueryOnBrowserNSSDB = async ({
@@ -131,7 +126,7 @@ export const executeTrustQueryOnBrowserNSSDB = async ({
131
126
  }
132
127
  }
133
128
 
134
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
129
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
135
130
  const certutilBinPath = await getCertutilBinPath()
136
131
 
137
132
  const checkNSSDB = async ({ NSSDBFileUrl }) => {
@@ -288,7 +283,7 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
288
283
  }
289
284
 
290
285
  logger.debug(`Searching nss database files in directory...`)
291
- const NSSDBDirectoryPath = urlToFileSystemPath(NSSDBDirectoryUrl)
286
+ const NSSDBDirectoryPath = fileURLToPath(NSSDBDirectoryUrl)
292
287
  const NSSDBDirectoryExists = existsSync(NSSDBDirectoryPath)
293
288
  if (!NSSDBDirectoryExists) {
294
289
  logger.info(
@@ -300,13 +295,9 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
300
295
  NSSDBDirectoryUrl = assertAndNormalizeDirectoryUrl(NSSDBDirectoryUrl)
301
296
  const NSSDBFiles = await collectFiles({
302
297
  directoryUrl: NSSDBDirectoryUrl,
303
- structuredMetaMap: {
304
- isLegacyNSSDB: {
305
- "./**/cert8.db": true,
306
- },
307
- isModernNSSDB: {
308
- "./**/cert9.db": true,
309
- },
298
+ associations: {
299
+ isLegacyNSSDB: { "./**/cert8.db": true },
300
+ isModernNSSDB: { "./**/cert9.db": true },
310
301
  },
311
302
  predicate: ({ isLegacyNSSDB, isModernNSSDB }) =>
312
303
  isLegacyNSSDB || isModernNSSDB,
@@ -324,7 +315,7 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
324
315
  `${UNICODE.OK} found ${fileCount} nss database file in ${NSSDBDirectoryUrl}`,
325
316
  )
326
317
  const files = NSSDBFiles.map((file) => {
327
- return resolveUrl(file.relativeUrl, NSSDBDirectoryUrl)
318
+ return new URL(file.relativeUrl, NSSDBDirectoryUrl).href
328
319
  })
329
320
  NSSDirectoryCache[NSSDBDirectoryUrl] = files
330
321
  return files
@@ -332,8 +323,8 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
332
323
 
333
324
  const getDirectoryArgFromNSSDBFileUrl = (NSSDBFileUrl) => {
334
325
  const nssDBFilename = urlToFilename(NSSDBFileUrl)
335
- const nssDBDirectoryUrl = resolveUrl("./", NSSDBFileUrl)
336
- const nssDBDirectoryPath = urlToFileSystemPath(nssDBDirectoryUrl)
326
+ const nssDBDirectoryUrl = new URL("./", NSSDBFileUrl).href
327
+ const nssDBDirectoryPath = fileURLToPath(nssDBDirectoryUrl)
337
328
  return nssDBFilename === "cert8.db"
338
329
  ? `"${nssDBDirectoryPath}"`
339
330
  : `sql:"${nssDBDirectoryPath}"`
@@ -2,7 +2,7 @@ import { createRequire } from "node:module"
2
2
  import { existsSync } from "node:fs"
3
3
  import { UNICODE } from "@jsenv/log"
4
4
 
5
- import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
5
+ import { memoize } from "../memoize.js"
6
6
 
7
7
  const require = createRequire(import.meta.url)
8
8
 
@@ -7,7 +7,7 @@ import { createRequire } from "node:module"
7
7
  import { existsSync } from "node:fs"
8
8
  import { UNICODE } from "@jsenv/log"
9
9
 
10
- import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
10
+ import { memoize } from "../memoize.js"
11
11
 
12
12
  const require = createRequire(import.meta.url)
13
13
 
@@ -3,11 +3,10 @@
3
3
  * https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil
4
4
  */
5
5
 
6
- import { createDetailedMessage } from "@jsenv/logger"
7
- import { urlToFileSystemPath } from "@jsenv/filesystem"
8
- import { UNICODE } from "@jsenv/log"
6
+ import { fileURLToPath } from "node:url"
7
+ import { createDetailedMessage, UNICODE } from "@jsenv/log"
9
8
 
10
- import { exec } from "@jsenv/https-local/src/internal/exec.js"
9
+ import { exec } from "../exec.js"
11
10
  import {
12
11
  VERB_CHECK_TRUST,
13
12
  VERB_ADD_TRUST,
@@ -49,7 +48,7 @@ export const executeTrustQueryOnWindows = async ({
49
48
  const certutilListCommand = `certutil -store -user root`
50
49
  logger.debug(`${UNICODE.COMMAND} ${certutilListCommand}`)
51
50
  const certutilListCommandOutput = await exec(certutilListCommand)
52
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
51
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
53
52
 
54
53
  // it's not super accurate and do not take into account if the cert is different
55
54
  // but it's the best I could do with certutil command on windows
@@ -7,13 +7,13 @@
7
7
  export {
8
8
  installCertificateAuthority,
9
9
  uninstallCertificateAuthority,
10
- } from "./src/certificate_authority.js"
10
+ } from "./certificate_authority.js"
11
11
 
12
12
  export {
13
13
  createValidityDurationOfXYears,
14
14
  createValidityDurationOfXDays,
15
- } from "./src/validity_duration.js"
15
+ } from "./validity_duration.js"
16
16
 
17
- export { verifyHostsFile } from "./src/hosts_file_verif.js"
17
+ export { verifyHostsFile } from "./hosts_file_verif.js"
18
18
 
19
- export { requestCertificateForLocalhost } from "./src/certificate_for_localhost.js"
19
+ export { requestCertificateForLocalhost } from "./certificate_for_localhost.js"
@@ -3,7 +3,6 @@ const MILLISECONDS_PER_YEAR = MILLISECONDS_PER_DAY * 365
3
3
 
4
4
  export const verifyRootCertificateValidityDuration = (validityDurationInMs) => {
5
5
  const durationInYears = validityDurationInMs / MILLISECONDS_PER_YEAR
6
-
7
6
  if (durationInYears > 25) {
8
7
  return {
9
8
  ok: false,
@@ -13,26 +12,22 @@ export const verifyRootCertificateValidityDuration = (validityDurationInMs) => {
13
12
  "https://serverfault.com/questions/847190/in-theory-could-a-ca-make-a-certificate-that-is-valid-for-arbitrarily-long",
14
13
  }
15
14
  }
16
-
17
15
  return { ok: true }
18
16
  }
19
17
 
20
18
  export const verifyServerCertificateValidityDuration = (
21
- serverCertificateValidityDurationInMs,
19
+ validityDurationInMs,
22
20
  ) => {
23
- const serverCertificateValidityDurationInDays =
24
- serverCertificateValidityDurationInMs / MILLISECONDS_PER_DAY
25
-
26
- if (serverCertificateValidityDurationInDays > 397) {
21
+ const validityDurationInDays = validityDurationInMs / MILLISECONDS_PER_DAY
22
+ if (validityDurationInDays > 397) {
27
23
  return {
28
24
  ok: false,
29
25
  maxAllowedValue: MILLISECONDS_PER_DAY * 397,
30
- message: `certificate validity duration of ${serverCertificateValidityDurationInMs} days is too much, using the max recommended duration: 397 days`,
26
+ message: `certificate validity duration of ${validityDurationInMs} days is too much, using the max recommended duration: 397 days`,
31
27
  details:
32
28
  "https://www.globalsign.com/en/blog/maximum-ssltls-certificate-validity-now-one-year",
33
29
  }
34
30
  }
35
-
36
31
  return { ok: true }
37
32
  }
38
33