@jsenv/https-local 1.0.11 → 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 +10 -9
- package/src/internal/authority_file_infos.js +4 -6
- package/src/internal/certificate_authority_file_urls.js +20 -22
- package/src/internal/linux/chrome_linux.js +3 -3
- package/src/internal/linux/firefox_linux.js +3 -3
- package/src/internal/linux/linux_trust_store.js +3 -2
- package/src/internal/mac/firefox_mac.js +3 -3
- package/src/internal/mac/mac_keychain.js +2 -2
- package/src/internal/mac/nss_mac.js +4 -7
- package/src/internal/nssdb_browser.js +11 -19
- package/src/internal/windows/windows_certutil.js +2 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jsenv/https-local",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "A programmatic way to generate locally trusted certificates",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": {
|
|
@@ -48,10 +48,10 @@
|
|
|
48
48
|
"playwright-install": "npx playwright install-deps && npx playwright install"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@jsenv/
|
|
52
|
-
"@jsenv/
|
|
53
|
-
"@jsenv/
|
|
54
|
-
"@jsenv/
|
|
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",
|
|
@@ -59,16 +59,17 @@
|
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@jsenv/assert": "2.5.4",
|
|
62
|
-
"@jsenv/core": "27.0.0-alpha.
|
|
62
|
+
"@jsenv/core": "27.0.0-alpha.69",
|
|
63
63
|
"@jsenv/eslint-config": "16.0.9",
|
|
64
|
+
"@jsenv/eslint-import-resolver": "0.1.11",
|
|
64
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.
|
|
68
|
+
"@jsenv/package-publish": "1.7.5",
|
|
68
69
|
"@jsenv/performance-impact": "2.2.11",
|
|
69
|
-
"eslint": "8.
|
|
70
|
+
"eslint": "8.17.0",
|
|
70
71
|
"eslint-plugin-import": "2.26.0",
|
|
71
72
|
"playwright": "1.22.2",
|
|
72
|
-
"prettier": "2.
|
|
73
|
+
"prettier": "2.7.0"
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { existsSync } from "node:fs"
|
|
2
|
-
import {
|
|
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 =
|
|
14
|
-
certificateAuthorityJsonFileUrl,
|
|
15
|
-
)
|
|
13
|
+
const authorityJsonFilePath = fileURLToPath(certificateAuthorityJsonFileUrl)
|
|
16
14
|
const authorityJsonFileDetected = existsSync(authorityJsonFilePath)
|
|
17
15
|
|
|
18
|
-
const rootCertificateFilePath =
|
|
16
|
+
const rootCertificateFilePath = fileURLToPath(rootCertificateFileUrl)
|
|
19
17
|
const rootCertificateFileDetected = existsSync(rootCertificateFilePath)
|
|
20
18
|
|
|
21
|
-
const rootCertificatePrivateKeyFilePath =
|
|
19
|
+
const rootCertificatePrivateKeyFilePath = fileURLToPath(
|
|
22
20
|
rootCertificatePrivateKeyFileUrl,
|
|
23
21
|
)
|
|
24
22
|
const rootCertificatePrivateKeyFileDetected = existsSync(
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
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 =
|
|
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 =
|
|
37
|
+
const serverCertificateDirectory = new URL("./", serverCertificateFileUrl)
|
|
38
|
+
.href
|
|
41
39
|
|
|
42
40
|
const rootCertificateFilename = urlToFilename(rootCertificateFileUrl)
|
|
43
|
-
const rootCertificateSymlinkUrl =
|
|
41
|
+
const rootCertificateSymlinkUrl = new URL(
|
|
44
42
|
rootCertificateFilename,
|
|
45
43
|
serverCertificateDirectory,
|
|
46
|
-
)
|
|
44
|
+
).href
|
|
47
45
|
const rootPrivateKeyFilename = urlToFilename(rootPrivateKeyFileUrl)
|
|
48
|
-
const rootPrivateKeySymlinkUrl =
|
|
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
|
|
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
|
|
70
|
+
return new URL(
|
|
73
71
|
`./https_local/`,
|
|
74
72
|
assertAndNormalizeDirectoryUrl(process.env.XDG_CONFIG_HOME),
|
|
75
|
-
)
|
|
73
|
+
).href
|
|
76
74
|
}
|
|
77
|
-
return
|
|
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
|
|
83
|
+
return new URL(
|
|
86
84
|
`./https_local/`,
|
|
87
85
|
assertAndNormalizeDirectoryUrl(process.env.LOCALAPPDATA),
|
|
88
|
-
)
|
|
86
|
+
).href
|
|
89
87
|
}
|
|
90
88
|
|
|
91
|
-
return
|
|
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 {
|
|
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:
|
|
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 {
|
|
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:
|
|
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
|
|
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 =
|
|
54
|
+
const certificateFilePath = fileURLToPath(certificateFileUrl)
|
|
54
55
|
const certificateStatus = await getCertificateStatus({ certificate })
|
|
55
56
|
|
|
56
57
|
if (certificateStatus === "missing" || certificateStatus === "outdated") {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync } from "node:fs"
|
|
2
2
|
import { execSync } from "node:child_process"
|
|
3
|
-
import {
|
|
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:
|
|
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,6 +1,6 @@
|
|
|
1
1
|
// https://ss64.com/osx/security.html
|
|
2
2
|
|
|
3
|
-
import {
|
|
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 =
|
|
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
|
-
|
|
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 =
|
|
35
|
-
const certutilBinPath =
|
|
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
|
-
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
304
|
-
isLegacyNSSDB: {
|
|
305
|
-
|
|
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
|
|
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 =
|
|
336
|
-
const nssDBDirectoryPath =
|
|
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 =
|
|
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
|