@jsenv/https-local 1.0.1 → 1.0.6
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 +49 -58
- package/package.json +27 -33
- package/src/certificate_authority.js +68 -29
- package/src/certificate_for_localhost.js +26 -10
- package/src/hosts_file_verif.js +13 -6
- package/src/internal/authority_file_infos.js +9 -3
- package/src/internal/certificate_authority_file_urls.js +21 -5
- package/src/internal/certificate_data_converter.js +6 -2
- package/src/internal/certificate_generator.js +21 -7
- package/src/internal/command.js +2 -1
- package/src/internal/exec.js +4 -1
- package/src/internal/hosts/parse_hosts.js +15 -5
- package/src/internal/hosts/write_hosts.js +23 -11
- package/src/internal/hosts/write_line_hosts.js +28 -12
- package/src/internal/linux/chrome_linux.js +8 -2
- package/src/internal/linux/firefox_linux.js +8 -2
- package/src/internal/linux/linux_trust_store.js +41 -16
- package/src/internal/linux/nss_linux.js +10 -4
- package/src/internal/mac/firefox_mac.js +8 -2
- package/src/internal/mac/mac_keychain.js +29 -12
- package/src/internal/mac/nss_mac.js +14 -6
- package/src/internal/nssdb_browser.js +17 -10
- package/src/internal/search_certificate_in_command_output.js +4 -1
- package/src/internal/unsupported_platform/unsupported_platform.js +3 -1
- package/src/internal/validity_formatting.js +3 -1
- package/src/internal/windows/chrome_windows.js +12 -10
- package/src/internal/windows/firefox_windows.js +12 -10
- package/src/internal/windows/windows_certutil.js +38 -16
- package/src/validity_duration.js +7 -3
|
@@ -64,15 +64,15 @@ export const executeTrustQueryOnBrowserNSSDB = async ({
|
|
|
64
64
|
const cannotCheckMessage = `${failureSign} cannot check if certificate is in ${browserName}`
|
|
65
65
|
if (!nssIsInstalled) {
|
|
66
66
|
if (verb === VERB_ADD_TRUST) {
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
if (!nssIsInstallable) {
|
|
67
|
+
const nssDynamicInstallInfo = await getNSSDynamicInstallInfo({ logger })
|
|
68
|
+
if (!nssDynamicInstallInfo.isInstallable) {
|
|
70
69
|
const reason = `"${nssCommandName}" is not installed and not cannot be installed`
|
|
71
70
|
logger.warn(
|
|
72
71
|
createDetailedMessage(cannotCheckMessage, {
|
|
73
72
|
reason,
|
|
74
|
-
"reason it cannot be installed":
|
|
75
|
-
|
|
73
|
+
"reason it cannot be installed":
|
|
74
|
+
nssDynamicInstallInfo.notInstallableReason,
|
|
75
|
+
"suggested solution": nssDynamicInstallInfo.suggestion,
|
|
76
76
|
}),
|
|
77
77
|
)
|
|
78
78
|
return {
|
|
@@ -96,7 +96,7 @@ export const executeTrustQueryOnBrowserNSSDB = async ({
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
try {
|
|
99
|
-
await
|
|
99
|
+
await nssDynamicInstallInfo.install()
|
|
100
100
|
} catch (e) {
|
|
101
101
|
logger.error(
|
|
102
102
|
createDetailedMessage(cannotCheckMessage, {
|
|
@@ -314,16 +314,21 @@ const findNSSDBFiles = async ({ logger, NSSDBDirectoryUrl }) => {
|
|
|
314
314
|
"./**/cert9.db": true,
|
|
315
315
|
},
|
|
316
316
|
},
|
|
317
|
-
predicate: ({ isLegacyNSSDB, isModernNSSDB }) =>
|
|
317
|
+
predicate: ({ isLegacyNSSDB, isModernNSSDB }) =>
|
|
318
|
+
isLegacyNSSDB || isModernNSSDB,
|
|
318
319
|
})
|
|
319
320
|
const fileCount = NSSDBFiles.length
|
|
320
321
|
if (fileCount === 0) {
|
|
321
|
-
logger.warn(
|
|
322
|
+
logger.warn(
|
|
323
|
+
`${warningSign} could not find nss database file in ${NSSDBDirectoryUrl}`,
|
|
324
|
+
)
|
|
322
325
|
NSSDirectoryCache[NSSDBDirectoryUrl] = []
|
|
323
326
|
return []
|
|
324
327
|
}
|
|
325
328
|
|
|
326
|
-
logger.debug(
|
|
329
|
+
logger.debug(
|
|
330
|
+
`${okSign} found ${fileCount} nss database file in ${NSSDBDirectoryUrl}`,
|
|
331
|
+
)
|
|
327
332
|
const files = NSSDBFiles.map((file) => {
|
|
328
333
|
return resolveUrl(file.relativeUrl, NSSDBDirectoryUrl)
|
|
329
334
|
})
|
|
@@ -335,7 +340,9 @@ const getDirectoryArgFromNSSDBFileUrl = (NSSDBFileUrl) => {
|
|
|
335
340
|
const nssDBFilename = urlToFilename(NSSDBFileUrl)
|
|
336
341
|
const nssDBDirectoryUrl = resolveUrl("./", NSSDBFileUrl)
|
|
337
342
|
const nssDBDirectoryPath = urlToFileSystemPath(nssDBDirectoryUrl)
|
|
338
|
-
return nssDBFilename === "cert8.db"
|
|
343
|
+
return nssDBFilename === "cert8.db"
|
|
344
|
+
? `"${nssDBDirectoryPath}"`
|
|
345
|
+
: `sql:"${nssDBDirectoryPath}"`
|
|
339
346
|
}
|
|
340
347
|
|
|
341
348
|
const execCertutilCommmand = async (command) => {
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
export const searchCertificateInCommandOutput = (
|
|
1
|
+
export const searchCertificateInCommandOutput = (
|
|
2
|
+
commandOutput,
|
|
3
|
+
certificateAsPEM,
|
|
4
|
+
) => {
|
|
2
5
|
commandOutput = commandOutput.replace(/\r\n/g, "\n").trim()
|
|
3
6
|
certificateAsPEM = certificateAsPEM.replace(/\r\n/g, "\n").trim()
|
|
4
7
|
return commandOutput.includes(certificateAsPEM)
|
|
@@ -6,7 +6,9 @@ const platformTrustInfo = {
|
|
|
6
6
|
}
|
|
7
7
|
|
|
8
8
|
export const executeTrustQuery = ({ logger }) => {
|
|
9
|
-
logger.warn(
|
|
9
|
+
logger.warn(
|
|
10
|
+
`${warningSign} platform not supported, cannot execute trust query`,
|
|
11
|
+
)
|
|
10
12
|
return {
|
|
11
13
|
platform: platformTrustInfo,
|
|
12
14
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export const formatStillValid = ({ certificateName, validityRemainingMs }) => {
|
|
2
|
-
return `${certificateName} still valid for ${formatDuration(
|
|
2
|
+
return `${certificateName} still valid for ${formatDuration(
|
|
3
|
+
validityRemainingMs,
|
|
4
|
+
)}`
|
|
3
5
|
}
|
|
4
6
|
|
|
5
7
|
export const formatAboutToExpire = ({
|
|
@@ -40,16 +40,18 @@ const detectChrome = memoize(({ logger }) => {
|
|
|
40
40
|
`${process.env.ProgramFiles}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
41
41
|
`${process.env["ProgramFiles(x86)"]}\\Google\\Chrome\\Application\\chrome.exe`,
|
|
42
42
|
]
|
|
43
|
-
const someExecutableFound = executableCandidates.some(
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
43
|
+
const someExecutableFound = executableCandidates.some(
|
|
44
|
+
(chromeExecutablePathCandidate) => {
|
|
45
|
+
if (existsSync(chromeExecutablePathCandidate)) {
|
|
46
|
+
return true
|
|
47
|
+
}
|
|
48
|
+
try {
|
|
49
|
+
which.sync(chromeExecutablePathCandidate)
|
|
50
|
+
return true
|
|
51
|
+
} catch (e) {}
|
|
52
|
+
return false
|
|
53
|
+
},
|
|
54
|
+
)
|
|
53
55
|
if (someExecutableFound) {
|
|
54
56
|
logger.debug(`${okSign} Chrome detected`)
|
|
55
57
|
return true
|
|
@@ -58,16 +58,18 @@ const detectFirefox = memoize(({ logger }) => {
|
|
|
58
58
|
`${process.env.ProgramFiles}\\Mozilla Firefox\\firefox.exe`,
|
|
59
59
|
`${process.env["ProgramFiles(x86)"]}\\Mozilla Firefox\\firefox.exe`,
|
|
60
60
|
]
|
|
61
|
-
const someExecutableFound = executableCandidates.some(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
61
|
+
const someExecutableFound = executableCandidates.some(
|
|
62
|
+
(firefoxExecutablePathCandidate) => {
|
|
63
|
+
if (existsSync(firefoxExecutablePathCandidate)) {
|
|
64
|
+
return true
|
|
65
|
+
}
|
|
66
|
+
try {
|
|
67
|
+
which.sync(firefoxExecutablePathCandidate)
|
|
68
|
+
return true
|
|
69
|
+
} catch (e) {}
|
|
70
|
+
return false
|
|
71
|
+
},
|
|
72
|
+
)
|
|
71
73
|
if (someExecutableFound) {
|
|
72
74
|
logger.debug(`${okSign} Firefox detected`)
|
|
73
75
|
return true
|
|
@@ -6,17 +6,31 @@
|
|
|
6
6
|
import { createDetailedMessage } from "@jsenv/logger"
|
|
7
7
|
import { urlToFileSystemPath } from "@jsenv/filesystem"
|
|
8
8
|
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
commandSign,
|
|
11
|
+
okSign,
|
|
12
|
+
infoSign,
|
|
13
|
+
failureSign,
|
|
14
|
+
} from "@jsenv/https-local/src/internal/logs.js"
|
|
10
15
|
import { exec } from "@jsenv/https-local/src/internal/exec.js"
|
|
11
|
-
import {
|
|
16
|
+
import {
|
|
17
|
+
VERB_CHECK_TRUST,
|
|
18
|
+
VERB_ADD_TRUST,
|
|
19
|
+
VERB_REMOVE_TRUST,
|
|
20
|
+
} from "../trust_query.js"
|
|
12
21
|
|
|
13
|
-
const REASON_NEW_AND_TRY_TO_TRUST_DISABLED =
|
|
22
|
+
const REASON_NEW_AND_TRY_TO_TRUST_DISABLED =
|
|
23
|
+
"certificate is new and tryToTrust is disabled"
|
|
14
24
|
const REASON_NOT_FOUND_IN_WINDOWS = "not found in windows store"
|
|
15
25
|
const REASON_FOUND_IN_WINDOWS = "found in windows store"
|
|
16
|
-
const REASON_ADD_COMMAND_FAILED =
|
|
17
|
-
|
|
18
|
-
const
|
|
19
|
-
|
|
26
|
+
const REASON_ADD_COMMAND_FAILED =
|
|
27
|
+
"command to add certificate to windows store failed"
|
|
28
|
+
const REASON_ADD_COMMAND_COMPLETED =
|
|
29
|
+
"command to add certificate to windows store completed"
|
|
30
|
+
const REASON_DELETE_COMMAND_FAILED =
|
|
31
|
+
"command to remove certificate from windows store failed"
|
|
32
|
+
const REASON_DELETE_COMMAND_COMPLETED =
|
|
33
|
+
"command to remove certificate from windows store completed"
|
|
20
34
|
|
|
21
35
|
export const executeTrustQueryOnWindows = async ({
|
|
22
36
|
logger,
|
|
@@ -44,7 +58,9 @@ export const executeTrustQueryOnWindows = async ({
|
|
|
44
58
|
|
|
45
59
|
// it's not super accurate and do not take into account if the cert is different
|
|
46
60
|
// but it's the best I could do with certutil command on windows
|
|
47
|
-
const certificateInStore = certutilListCommandOutput.includes(
|
|
61
|
+
const certificateInStore = certutilListCommandOutput.includes(
|
|
62
|
+
certificateCommonName,
|
|
63
|
+
)
|
|
48
64
|
if (!certificateInStore) {
|
|
49
65
|
logger.info(`${infoSign} certificate not found in windows`)
|
|
50
66
|
if (verb === VERB_CHECK_TRUST || verb === VERB_REMOVE_TRUST) {
|
|
@@ -67,10 +83,13 @@ export const executeTrustQueryOnWindows = async ({
|
|
|
67
83
|
}
|
|
68
84
|
} catch (e) {
|
|
69
85
|
logger.error(
|
|
70
|
-
createDetailedMessage(
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
86
|
+
createDetailedMessage(
|
|
87
|
+
`${failureSign} Failed to add certificate to windows`,
|
|
88
|
+
{
|
|
89
|
+
"error stack": e.stack,
|
|
90
|
+
"certificate file": certificateFilePath,
|
|
91
|
+
},
|
|
92
|
+
),
|
|
74
93
|
)
|
|
75
94
|
return {
|
|
76
95
|
status: "not_trusted",
|
|
@@ -100,10 +119,13 @@ export const executeTrustQueryOnWindows = async ({
|
|
|
100
119
|
}
|
|
101
120
|
} catch (e) {
|
|
102
121
|
logger.error(
|
|
103
|
-
createDetailedMessage(
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
122
|
+
createDetailedMessage(
|
|
123
|
+
`${failureSign} failed to remove certificate from windows`,
|
|
124
|
+
{
|
|
125
|
+
"error stack": e.stack,
|
|
126
|
+
"certificate file": certificateFilePath,
|
|
127
|
+
},
|
|
128
|
+
),
|
|
107
129
|
)
|
|
108
130
|
return {
|
|
109
131
|
status: "unknown", // maybe it was not trusted?
|
package/src/validity_duration.js
CHANGED
|
@@ -17,7 +17,9 @@ export const verifyRootCertificateValidityDuration = (validityDurationInMs) => {
|
|
|
17
17
|
return { ok: true }
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
export const verifyServerCertificateValidityDuration = (
|
|
20
|
+
export const verifyServerCertificateValidityDuration = (
|
|
21
|
+
serverCertificateValidityDurationInMs,
|
|
22
|
+
) => {
|
|
21
23
|
const serverCertificateValidityDurationInDays =
|
|
22
24
|
serverCertificateValidityDurationInMs / MILLISECONDS_PER_DAY
|
|
23
25
|
|
|
@@ -34,6 +36,8 @@ export const verifyServerCertificateValidityDuration = (serverCertificateValidit
|
|
|
34
36
|
return { ok: true }
|
|
35
37
|
}
|
|
36
38
|
|
|
37
|
-
export const createValidityDurationOfXYears = (years) =>
|
|
39
|
+
export const createValidityDurationOfXYears = (years) =>
|
|
40
|
+
MILLISECONDS_PER_YEAR * years + 5000
|
|
38
41
|
|
|
39
|
-
export const createValidityDurationOfXDays = (days) =>
|
|
42
|
+
export const createValidityDurationOfXDays = (days) =>
|
|
43
|
+
MILLISECONDS_PER_DAY * days + 5000
|