@jsenv/https-local 1.0.8 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/https-local",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "A programmatic way to generate locally trusted certificates",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -12,12 +12,12 @@
12
12
  "type": "git",
13
13
  "url": "https://github.com/jsenv/https-local"
14
14
  },
15
- "engines": {
16
- "node": ">=16.13.0"
17
- },
18
15
  "publishConfig": {
19
16
  "access": "public"
20
17
  },
18
+ "engines": {
19
+ "node": ">=16.13.0"
20
+ },
21
21
  "type": "module",
22
22
  "exports": {
23
23
  ".": {
@@ -31,44 +31,45 @@
31
31
  "/main.js"
32
32
  ],
33
33
  "scripts": {
34
- "eslint": "npx eslint . --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",
34
+ "eslint": "npx eslint . --ext=.js,.mjs,.cjs",
35
+ "test": "node ./scripts/test/test.mjs",
36
+ "performance": "node --expose-gc ./scripts/performance/performance.mjs --local --log",
38
37
  "test-with-coverage": "npm run test -- --coverage",
39
- "start-node-server": "node ./script/certificate/start_node_server.mjs",
40
- "log-root-certificate-trust": "node ./script/certificate/log_root_certificate_trust.mjs",
41
- "trust-root-certificate": "node ./script/certificate/trust_root_certificate.mjs",
42
- "untrust-root-certificate": "node ./script/certificate/untrust_root_certificate.mjs",
43
- "uninstall-certificate-authority": "node ./script/certificate/uninstall_certificate_authority.mjs",
44
- "add-localhost-mappings": "node ./script/hosts/add_localhost_mappings.mjs",
45
- "remove-localhost-mappings": "node ./script/hosts/remove_localhost_mappings.mjs",
46
- "verify-localhost-mappings": "node ./script/hosts/verify_localhost_mappings.mjs",
47
- "ensure-localhost-mappings": "node ./script/hosts/ensure_localhost_mappings.mjs",
38
+ "start-node-server": "node ./scripts/certificate/start_node_server.mjs",
39
+ "log-root-certificate-trust": "node ./scripts/certificate/log_root_certificate_trust.mjs",
40
+ "trust-root-certificate": "node ./scripts/certificate/trust_root_certificate.mjs",
41
+ "untrust-root-certificate": "node ./scripts/certificate/untrust_root_certificate.mjs",
42
+ "uninstall-certificate-authority": "node ./scripts/certificate/uninstall_certificate_authority.mjs",
43
+ "add-localhost-mappings": "node ./scripts/hosts/add_localhost_mappings.mjs",
44
+ "remove-localhost-mappings": "node ./scripts/hosts/remove_localhost_mappings.mjs",
45
+ "verify-localhost-mappings": "node ./scripts/hosts/verify_localhost_mappings.mjs",
46
+ "ensure-localhost-mappings": "node ./scripts/hosts/ensure_localhost_mappings.mjs",
48
47
  "prettier": "prettier --write .",
49
48
  "playwright-install": "npx playwright install-deps && npx playwright install"
50
49
  },
51
50
  "dependencies": {
52
- "@jsenv/filesystem": "3.1.0",
53
- "@jsenv/log": "1.5.1",
54
- "@jsenv/logger": "4.0.1",
51
+ "@jsenv/filesystem": "4.0.2",
52
+ "@jsenv/log": "1.6.3",
53
+ "@jsenv/logger": "4.1.1",
54
+ "@jsenv/urls": "1.1.2",
55
55
  "command-exists": "1.2.9",
56
56
  "node-forge": "1.3.1",
57
57
  "sudo-prompt": "9.2.1",
58
58
  "which": "2.0.2"
59
59
  },
60
60
  "devDependencies": {
61
- "@jsenv/assert": "2.5.3",
62
- "@jsenv/core": "26.0.1",
61
+ "@jsenv/assert": "2.5.4",
62
+ "@jsenv/core": "27.0.0-alpha.69",
63
63
  "@jsenv/eslint-config": "16.0.9",
64
- "@jsenv/github-release-package": "1.3.5",
64
+ "@jsenv/eslint-import-resolver": "0.1.11",
65
+ "@jsenv/github-release-package": "1.4.0",
65
66
  "@jsenv/importmap-eslint-resolver": "5.2.5",
66
67
  "@jsenv/importmap-node-module": "5.1.3",
67
- "@jsenv/package-publish": "1.7.2",
68
- "@jsenv/performance-impact": "2.2.8",
69
- "eslint": "8.12.0",
68
+ "@jsenv/package-publish": "1.7.5",
69
+ "@jsenv/performance-impact": "2.2.11",
70
+ "eslint": "8.17.0",
70
71
  "eslint-plugin-import": "2.26.0",
71
- "playwright": "1.20.2",
72
- "prettier": "2.6.2"
72
+ "playwright": "1.22.2",
73
+ "prettier": "2.7.0"
73
74
  }
74
75
  }
@@ -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,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
 
5
5
  import { UNICODE } from "@jsenv/log"
6
6
  import {
@@ -48,10 +48,10 @@ export const executeTrustQueryOnChrome = ({
48
48
  logger.debug(`${UNICODE.INFO} Chrome not detected`)
49
49
  return false
50
50
  },
51
- browserNSSDBDirectoryUrl: resolveUrl(
51
+ browserNSSDBDirectoryUrl: new URL(
52
52
  ".pki/nssdb",
53
53
  assertAndNormalizeDirectoryUrl(process.env.HOME),
54
- ),
54
+ ).href,
55
55
  getBrowserClosedPromise: async () => {
56
56
  if (!isChromeOpen()) {
57
57
  return
@@ -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 } from "@jsenv/log"
5
5
 
6
6
  import {
@@ -48,10 +48,10 @@ export const executeTrustQueryOnFirefox = ({
48
48
  logger.debug(`${UNICODE.INFO} Firefox not detected`)
49
49
  return false
50
50
  },
51
- browserNSSDBDirectoryUrl: resolveUrl(
51
+ browserNSSDBDirectoryUrl: new URL(
52
52
  ".mozilla/firefox/",
53
53
  assertAndNormalizeDirectoryUrl(process.env.HOME),
54
- ),
54
+ ).href,
55
55
  getBrowserClosedPromise: async () => {
56
56
  if (!isFirefoxOpen()) {
57
57
  return
@@ -3,8 +3,9 @@
3
3
  */
4
4
 
5
5
  import { existsSync } from "node:fs"
6
+ import { fileURLToPath } from "node:url"
6
7
  import { createDetailedMessage } from "@jsenv/logger"
7
- import { readFile, urlToFileSystemPath } from "@jsenv/filesystem"
8
+ import { readFile } from "@jsenv/filesystem"
8
9
  import { UNICODE } from "@jsenv/log"
9
10
 
10
11
  import { exec } from "@jsenv/https-local/src/internal/exec.js"
@@ -50,7 +51,7 @@ export const executeTrustQueryOnLinux = async ({
50
51
  logger.debug(
51
52
  `Searching certificate file at ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}...`,
52
53
  )
53
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
54
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
54
55
  const certificateStatus = await getCertificateStatus({ certificate })
55
56
 
56
57
  if (certificateStatus === "missing" || certificateStatus === "outdated") {
@@ -1,7 +1,7 @@
1
1
  import { existsSync } from "node:fs"
2
2
  import { execSync } from "node:child_process"
3
- import { resolveUrl, assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
4
- import { UNICODE } from "@jsenv/log"
3
+ import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem"
4
+ import { UNICODE, createTaskLog } from "@jsenv/log"
5
5
 
6
6
  import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
7
7
  import {
@@ -47,24 +47,25 @@ 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
57
57
  }
58
58
 
59
59
  logger.warn(
60
- `${UNICODE.WARNING} waiting for you to close firefox before resuming...`,
60
+ `${UNICODE.WARNING} firefox is running, it must be stopped before resuming...`,
61
61
  )
62
+ const closeFirefoxTask = createTaskLog("waiting for firefox to close")
62
63
  const next = async () => {
63
64
  await new Promise((resolve) => setTimeout(resolve, 50))
64
65
  if (isFirefoxOpen()) {
65
66
  await next()
66
67
  } else {
67
- logger.info(`${UNICODE.OK} firefox closed, resuming`)
68
+ closeFirefoxTask.done()
68
69
  // wait 50ms more to ensure firefox has time to cleanup
69
70
  // othrwise sometimes there is an SEC_ERROR_REUSED_ISSUER_AND_SERIAL error
70
71
  // because we updated nss database file while firefox is not fully closed
@@ -1,6 +1,6 @@
1
1
  // https://ss64.com/osx/security.html
2
2
 
3
- import { urlToFileSystemPath } from "@jsenv/filesystem"
3
+ import { fileURLToPath } from "node:url"
4
4
  import { createDetailedMessage } from "@jsenv/logger"
5
5
 
6
6
  import { UNICODE } from "@jsenv/log"
@@ -62,7 +62,7 @@ export const executeTrustQueryOnMacKeychain = async ({
62
62
  }
63
63
  }
64
64
 
65
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
65
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
66
66
  // https://ss64.com/osx/security-cert.html
67
67
  const addTrustedCertCommand = `sudo security add-trusted-cert -d -r trustRoot -k ${systemKeychainPath} "${certificateFilePath}"`
68
68
  logger.info(`Adding certificate to mac keychain...`)
@@ -1,8 +1,5 @@
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
5
  import { memoize } from "@jsenv/https-local/src/internal/memoize.js"
@@ -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,14 +4,10 @@
4
4
  */
5
5
 
6
6
  import { existsSync } from "node:fs"
7
+ import { fileURLToPath } from "node:url"
7
8
  import { createDetailedMessage } from "@jsenv/logger"
8
- import {
9
- assertAndNormalizeDirectoryUrl,
10
- collectFiles,
11
- resolveUrl,
12
- urlToFilename,
13
- urlToFileSystemPath,
14
- } from "@jsenv/filesystem"
9
+ import { urlToFilename } from "@jsenv/urls"
10
+ import { assertAndNormalizeDirectoryUrl, collectFiles } from "@jsenv/filesystem"
15
11
  import { UNICODE } from "@jsenv/log"
16
12
 
17
13
  import { exec } from "@jsenv/https-local/src/internal/exec.js"
@@ -131,7 +127,7 @@ export const executeTrustQueryOnBrowserNSSDB = async ({
131
127
  }
132
128
  }
133
129
 
134
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
130
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
135
131
  const certutilBinPath = await getCertutilBinPath()
136
132
 
137
133
  const checkNSSDB = async ({ NSSDBFileUrl }) => {
@@ -288,7 +284,7 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
288
284
  }
289
285
 
290
286
  logger.debug(`Searching nss database files in directory...`)
291
- const NSSDBDirectoryPath = urlToFileSystemPath(NSSDBDirectoryUrl)
287
+ const NSSDBDirectoryPath = fileURLToPath(NSSDBDirectoryUrl)
292
288
  const NSSDBDirectoryExists = existsSync(NSSDBDirectoryPath)
293
289
  if (!NSSDBDirectoryExists) {
294
290
  logger.info(
@@ -300,13 +296,9 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
300
296
  NSSDBDirectoryUrl = assertAndNormalizeDirectoryUrl(NSSDBDirectoryUrl)
301
297
  const NSSDBFiles = await collectFiles({
302
298
  directoryUrl: NSSDBDirectoryUrl,
303
- structuredMetaMap: {
304
- isLegacyNSSDB: {
305
- "./**/cert8.db": true,
306
- },
307
- isModernNSSDB: {
308
- "./**/cert9.db": true,
309
- },
299
+ associations: {
300
+ isLegacyNSSDB: { "./**/cert8.db": true },
301
+ isModernNSSDB: { "./**/cert9.db": true },
310
302
  },
311
303
  predicate: ({ isLegacyNSSDB, isModernNSSDB }) =>
312
304
  isLegacyNSSDB || isModernNSSDB,
@@ -324,7 +316,7 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
324
316
  `${UNICODE.OK} found ${fileCount} nss database file in ${NSSDBDirectoryUrl}`,
325
317
  )
326
318
  const files = NSSDBFiles.map((file) => {
327
- return resolveUrl(file.relativeUrl, NSSDBDirectoryUrl)
319
+ return new URL(file.relativeUrl, NSSDBDirectoryUrl).href
328
320
  })
329
321
  NSSDirectoryCache[NSSDBDirectoryUrl] = files
330
322
  return files
@@ -332,8 +324,8 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
332
324
 
333
325
  const getDirectoryArgFromNSSDBFileUrl = (NSSDBFileUrl) => {
334
326
  const nssDBFilename = urlToFilename(NSSDBFileUrl)
335
- const nssDBDirectoryUrl = resolveUrl("./", NSSDBFileUrl)
336
- const nssDBDirectoryPath = urlToFileSystemPath(nssDBDirectoryUrl)
327
+ const nssDBDirectoryUrl = new URL("./", NSSDBFileUrl).href
328
+ const nssDBDirectoryPath = fileURLToPath(nssDBDirectoryUrl)
337
329
  return nssDBFilename === "cert8.db"
338
330
  ? `"${nssDBDirectoryPath}"`
339
331
  : `sql:"${nssDBDirectoryPath}"`
@@ -3,8 +3,8 @@
3
3
  * https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/certutil
4
4
  */
5
5
 
6
+ import { fileURLToPath } from "node:url"
6
7
  import { createDetailedMessage } from "@jsenv/logger"
7
- import { urlToFileSystemPath } from "@jsenv/filesystem"
8
8
  import { UNICODE } from "@jsenv/log"
9
9
 
10
10
  import { exec } from "@jsenv/https-local/src/internal/exec.js"
@@ -49,7 +49,7 @@ export const executeTrustQueryOnWindows = async ({
49
49
  const certutilListCommand = `certutil -store -user root`
50
50
  logger.debug(`${UNICODE.COMMAND} ${certutilListCommand}`)
51
51
  const certutilListCommandOutput = await exec(certutilListCommand)
52
- const certificateFilePath = urlToFileSystemPath(certificateFileUrl)
52
+ const certificateFilePath = fileURLToPath(certificateFileUrl)
53
53
 
54
54
  // it's not super accurate and do not take into account if the cert is different
55
55
  // but it's the best I could do with certutil command on windows