@jsenv/https-local 3.0.6 → 3.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/README.md +160 -192
- package/package.json +19 -38
- package/src/certificate_authority.js +111 -110
- package/src/certificate_request.js +34 -35
- package/src/hosts_file_verif.js +34 -35
- package/src/https_local_cli.mjs +74 -0
- package/src/internal/authority_file_infos.js +12 -13
- package/src/internal/browser_detection.js +4 -4
- package/src/internal/certificate_authority_file_urls.js +23 -23
- package/src/internal/certificate_data_converter.js +39 -39
- package/src/internal/certificate_generator.js +39 -39
- package/src/internal/command.js +6 -6
- package/src/internal/exec.js +10 -10
- package/src/internal/forge.js +3 -3
- package/src/internal/hosts/hosts_utils.js +2 -2
- package/src/internal/hosts/parse_hosts.js +67 -66
- package/src/internal/hosts/read_hosts.js +5 -6
- package/src/internal/hosts/write_hosts.js +29 -31
- package/src/internal/hosts/write_line_hosts.js +30 -32
- package/src/internal/hosts.js +5 -5
- package/src/internal/linux/chrome_linux.js +21 -20
- package/src/internal/linux/firefox_linux.js +23 -20
- package/src/internal/linux/linux.js +8 -8
- package/src/internal/linux/linux_trust_store.js +58 -59
- package/src/internal/linux/nss_linux.js +21 -20
- package/src/internal/mac/chrome_mac.js +15 -16
- package/src/internal/mac/firefox_mac.js +20 -21
- package/src/internal/mac/mac.js +10 -10
- package/src/internal/mac/mac_keychain.js +46 -47
- package/src/internal/mac/nss_mac.js +29 -30
- package/src/internal/mac/safari.js +2 -2
- package/src/internal/memoize.js +14 -14
- package/src/internal/nssdb_browser.js +150 -145
- package/src/internal/platform.js +6 -6
- package/src/internal/search_certificate_in_command_output.js +4 -4
- package/src/internal/trust_query.js +4 -4
- package/src/internal/unsupported_platform/unsupported_platform.js +5 -5
- package/src/internal/validity_formatting.js +32 -32
- package/src/internal/windows/chrome_windows.js +26 -27
- package/src/internal/windows/edge.js +2 -2
- package/src/internal/windows/firefox_windows.js +31 -32
- package/src/internal/windows/windows.js +10 -10
- package/src/internal/windows/windows_certutil.js +41 -42
- package/src/jsenvParameters.js +2 -2
- package/src/main.js +5 -8
- package/src/validity_duration.js +12 -12
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
|
|
1
|
+
import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
|
|
2
|
+
import { UNICODE } from "@jsenv/humanize";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js";
|
|
6
5
|
import {
|
|
7
|
-
nssCommandName,
|
|
8
6
|
detectIfNSSIsInstalled,
|
|
9
|
-
getNSSDynamicInstallInfo,
|
|
10
7
|
getCertutilBinPath,
|
|
11
|
-
|
|
8
|
+
getNSSDynamicInstallInfo,
|
|
9
|
+
nssCommandName,
|
|
10
|
+
} from "./nss_linux.js";
|
|
12
11
|
|
|
13
12
|
export const executeTrustQueryOnFirefox = ({
|
|
14
13
|
logger,
|
|
@@ -45,6 +44,10 @@ export const executeTrustQueryOnFirefox = ({
|
|
|
45
44
|
".mozilla/firefox/",
|
|
46
45
|
assertAndNormalizeDirectoryUrl(process.env.HOME),
|
|
47
46
|
),
|
|
47
|
+
new URL(
|
|
48
|
+
"/.mozilla/firefox-trunk/",
|
|
49
|
+
assertAndNormalizeDirectoryUrl(process.env.HOME),
|
|
50
|
+
),
|
|
48
51
|
new URL(
|
|
49
52
|
"/snap/firefox/common/.mozilla/firefox/",
|
|
50
53
|
assertAndNormalizeDirectoryUrl(process.env.HOME),
|
|
@@ -52,29 +55,29 @@ export const executeTrustQueryOnFirefox = ({
|
|
|
52
55
|
],
|
|
53
56
|
getBrowserClosedPromise: async () => {
|
|
54
57
|
if (!isFirefoxOpen()) {
|
|
55
|
-
return
|
|
58
|
+
return;
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
logger.warn(
|
|
59
62
|
`${UNICODE.WARNING} waiting for you to close Firefox before resuming...`,
|
|
60
|
-
)
|
|
63
|
+
);
|
|
61
64
|
const next = async () => {
|
|
62
|
-
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
65
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
63
66
|
if (isFirefoxOpen()) {
|
|
64
|
-
await next()
|
|
67
|
+
await next();
|
|
65
68
|
} else {
|
|
66
|
-
logger.info(`${UNICODE.OK} Firefox closed, resuming`)
|
|
69
|
+
logger.info(`${UNICODE.OK} Firefox closed, resuming`);
|
|
67
70
|
// wait 50ms more to ensure firefox has time to cleanup
|
|
68
71
|
// othrwise sometimes there is an SEC_ERROR_REUSED_ISSUER_AND_SERIAL error
|
|
69
72
|
// because we updated nss database file while firefox is not fully closed
|
|
70
|
-
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
73
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
71
74
|
}
|
|
72
|
-
}
|
|
73
|
-
await next()
|
|
75
|
+
};
|
|
76
|
+
await next();
|
|
74
77
|
},
|
|
75
|
-
})
|
|
76
|
-
}
|
|
78
|
+
});
|
|
79
|
+
};
|
|
77
80
|
|
|
78
81
|
const isFirefoxOpen = () => {
|
|
79
|
-
return execSync("ps aux").includes("firefox")
|
|
80
|
-
}
|
|
82
|
+
return execSync("ps aux").includes("firefox");
|
|
83
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { executeTrustQueryOnChrome } from "./chrome_linux.js";
|
|
2
|
+
import { executeTrustQueryOnFirefox } from "./firefox_linux.js";
|
|
3
|
+
import { executeTrustQueryOnLinux } from "./linux_trust_store.js";
|
|
4
4
|
|
|
5
5
|
export const executeTrustQuery = async ({
|
|
6
6
|
logger,
|
|
@@ -18,7 +18,7 @@ export const executeTrustQuery = async ({
|
|
|
18
18
|
certificateIsNew,
|
|
19
19
|
certificate,
|
|
20
20
|
verb,
|
|
21
|
-
})
|
|
21
|
+
});
|
|
22
22
|
|
|
23
23
|
const chromeTrustInfo = await executeTrustQueryOnChrome({
|
|
24
24
|
logger,
|
|
@@ -28,7 +28,7 @@ export const executeTrustQuery = async ({
|
|
|
28
28
|
certificate,
|
|
29
29
|
verb,
|
|
30
30
|
NSSDynamicInstall,
|
|
31
|
-
})
|
|
31
|
+
});
|
|
32
32
|
|
|
33
33
|
const firefoxTrustInfo = await executeTrustQueryOnFirefox({
|
|
34
34
|
logger,
|
|
@@ -38,11 +38,11 @@ export const executeTrustQuery = async ({
|
|
|
38
38
|
certificate,
|
|
39
39
|
verb,
|
|
40
40
|
NSSDynamicInstall,
|
|
41
|
-
})
|
|
41
|
+
});
|
|
42
42
|
|
|
43
43
|
return {
|
|
44
44
|
linux: linuxTrustInfo,
|
|
45
45
|
chrome: chromeTrustInfo,
|
|
46
46
|
firefox: firefoxTrustInfo,
|
|
47
|
-
}
|
|
48
|
-
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -2,34 +2,33 @@
|
|
|
2
2
|
* see https://github.com/davewasmer/devcert/blob/master/src/platforms/linux.ts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
5
|
+
import { readFile } from "@jsenv/filesystem";
|
|
6
|
+
import { createDetailedMessage, UNICODE } from "@jsenv/humanize";
|
|
7
|
+
import { existsSync } from "node:fs";
|
|
8
|
+
import { fileURLToPath } from "node:url";
|
|
9
|
+
import { exec } from "../exec.js";
|
|
10
10
|
import {
|
|
11
|
-
VERB_CHECK_TRUST,
|
|
12
11
|
VERB_ADD_TRUST,
|
|
12
|
+
VERB_CHECK_TRUST,
|
|
13
13
|
VERB_ENSURE_TRUST,
|
|
14
14
|
VERB_REMOVE_TRUST,
|
|
15
|
-
} from "../trust_query.js"
|
|
16
|
-
import { exec } from "../exec.js"
|
|
15
|
+
} from "../trust_query.js";
|
|
17
16
|
|
|
18
17
|
const REASON_NEW_AND_TRY_TO_TRUST_DISABLED =
|
|
19
|
-
"certificate is new and tryToTrust is disabled"
|
|
20
|
-
const REASON_NOT_FOUND_IN_LINUX = `not found in linux store
|
|
21
|
-
const REASON_OUTDATED_IN_LINUX = "certificate in linux store is outdated"
|
|
22
|
-
const REASON_FOUND_IN_LINUX = "found in linux store"
|
|
23
|
-
const REASON_ADD_COMMAND_FAILED = "command to add certificate to linux failed"
|
|
18
|
+
"certificate is new and tryToTrust is disabled";
|
|
19
|
+
const REASON_NOT_FOUND_IN_LINUX = `not found in linux store`;
|
|
20
|
+
const REASON_OUTDATED_IN_LINUX = "certificate in linux store is outdated";
|
|
21
|
+
const REASON_FOUND_IN_LINUX = "found in linux store";
|
|
22
|
+
const REASON_ADD_COMMAND_FAILED = "command to add certificate to linux failed";
|
|
24
23
|
const REASON_ADD_COMMAND_COMPLETED =
|
|
25
|
-
"command to add certificate to linux completed"
|
|
24
|
+
"command to add certificate to linux completed";
|
|
26
25
|
const REASON_REMOVE_COMMAND_FAILED =
|
|
27
|
-
"command to remove certificate from linux failed"
|
|
26
|
+
"command to remove certificate from linux failed";
|
|
28
27
|
const REASON_REMOVE_COMMAND_COMPLETED =
|
|
29
|
-
"command to remove certificate from linux completed"
|
|
28
|
+
"command to remove certificate from linux completed";
|
|
30
29
|
|
|
31
|
-
const LINUX_CERTIFICATE_AUTHORITIES_DIRECTORY_PATH = `/usr/local/share/ca-certificates
|
|
32
|
-
const JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH = `${LINUX_CERTIFICATE_AUTHORITIES_DIRECTORY_PATH}https_local_root_certificate.crt
|
|
30
|
+
const LINUX_CERTIFICATE_AUTHORITIES_DIRECTORY_PATH = `/usr/local/share/ca-certificates/`;
|
|
31
|
+
const JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH = `${LINUX_CERTIFICATE_AUTHORITIES_DIRECTORY_PATH}https_local_root_certificate.crt`;
|
|
33
32
|
|
|
34
33
|
export const executeTrustQueryOnLinux = async ({
|
|
35
34
|
logger,
|
|
@@ -40,25 +39,25 @@ export const executeTrustQueryOnLinux = async ({
|
|
|
40
39
|
verb,
|
|
41
40
|
}) => {
|
|
42
41
|
if (verb === VERB_CHECK_TRUST && certificateIsNew) {
|
|
43
|
-
logger.info(`${UNICODE.INFO} You should add certificate to linux`)
|
|
42
|
+
logger.info(`${UNICODE.INFO} You should add certificate to linux`);
|
|
44
43
|
return {
|
|
45
44
|
status: "not_trusted",
|
|
46
45
|
reason: REASON_NEW_AND_TRY_TO_TRUST_DISABLED,
|
|
47
|
-
}
|
|
46
|
+
};
|
|
48
47
|
}
|
|
49
48
|
|
|
50
|
-
logger.info(`Check if certificate is in linux...`)
|
|
49
|
+
logger.info(`Check if certificate is in linux...`);
|
|
51
50
|
logger.debug(
|
|
52
51
|
`Searching certificate file at ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}...`,
|
|
53
|
-
)
|
|
54
|
-
const certificateFilePath = fileURLToPath(certificateFileUrl)
|
|
55
|
-
const certificateStatus = await getCertificateStatus({ certificate })
|
|
52
|
+
);
|
|
53
|
+
const certificateFilePath = fileURLToPath(certificateFileUrl);
|
|
54
|
+
const certificateStatus = await getCertificateStatus({ certificate });
|
|
56
55
|
|
|
57
56
|
if (certificateStatus === "missing" || certificateStatus === "outdated") {
|
|
58
57
|
if (certificateStatus === "missing") {
|
|
59
|
-
logger.info(`${UNICODE.INFO} certificate not in linux`)
|
|
58
|
+
logger.info(`${UNICODE.INFO} certificate not in linux`);
|
|
60
59
|
} else {
|
|
61
|
-
logger.info(`${UNICODE.INFO} certificate in linux is outdated`)
|
|
60
|
+
logger.info(`${UNICODE.INFO} certificate in linux is outdated`);
|
|
62
61
|
}
|
|
63
62
|
if (verb === VERB_CHECK_TRUST || verb === VERB_REMOVE_TRUST) {
|
|
64
63
|
return {
|
|
@@ -67,24 +66,24 @@ export const executeTrustQueryOnLinux = async ({
|
|
|
67
66
|
certificateStatus === "missing"
|
|
68
67
|
? REASON_NOT_FOUND_IN_LINUX
|
|
69
68
|
: REASON_OUTDATED_IN_LINUX,
|
|
70
|
-
}
|
|
69
|
+
};
|
|
71
70
|
}
|
|
72
71
|
|
|
73
|
-
const copyCertificateCommand = `sudo /bin/cp -f "${certificateFilePath}" ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}
|
|
74
|
-
const updateCertificateCommand = `sudo update-ca-certificates
|
|
75
|
-
logger.info(`Adding certificate to linux...`)
|
|
72
|
+
const copyCertificateCommand = `sudo /bin/cp -f "${certificateFilePath}" ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}`;
|
|
73
|
+
const updateCertificateCommand = `sudo update-ca-certificates`;
|
|
74
|
+
logger.info(`Adding certificate to linux...`);
|
|
76
75
|
try {
|
|
77
|
-
logger.info(`${UNICODE.COMMAND} ${copyCertificateCommand}`)
|
|
78
|
-
await exec(copyCertificateCommand)
|
|
79
|
-
logger.info(`${UNICODE.COMMAND} ${updateCertificateCommand}`)
|
|
80
|
-
await exec(updateCertificateCommand)
|
|
81
|
-
logger.info(`${UNICODE.OK} certificate added to linux`)
|
|
76
|
+
logger.info(`${UNICODE.COMMAND} ${copyCertificateCommand}`);
|
|
77
|
+
await exec(copyCertificateCommand);
|
|
78
|
+
logger.info(`${UNICODE.COMMAND} ${updateCertificateCommand}`);
|
|
79
|
+
await exec(updateCertificateCommand);
|
|
80
|
+
logger.info(`${UNICODE.OK} certificate added to linux`);
|
|
82
81
|
return {
|
|
83
82
|
status: "trusted",
|
|
84
83
|
reason: REASON_ADD_COMMAND_COMPLETED,
|
|
85
|
-
}
|
|
84
|
+
};
|
|
86
85
|
} catch (e) {
|
|
87
|
-
console.error(e)
|
|
86
|
+
console.error(e);
|
|
88
87
|
logger.error(
|
|
89
88
|
createDetailedMessage(
|
|
90
89
|
`${UNICODE.FAILURE} failed to add certificate to linux`,
|
|
@@ -92,15 +91,15 @@ export const executeTrustQueryOnLinux = async ({
|
|
|
92
91
|
"certificate file": certificateFilePath,
|
|
93
92
|
},
|
|
94
93
|
),
|
|
95
|
-
)
|
|
94
|
+
);
|
|
96
95
|
return {
|
|
97
96
|
status: "not_trusted",
|
|
98
97
|
reason: REASON_ADD_COMMAND_FAILED,
|
|
99
|
-
}
|
|
98
|
+
};
|
|
100
99
|
}
|
|
101
100
|
}
|
|
102
101
|
|
|
103
|
-
logger.info(`${UNICODE.OK} certificate found in linux`)
|
|
102
|
+
logger.info(`${UNICODE.OK} certificate found in linux`);
|
|
104
103
|
if (
|
|
105
104
|
verb === VERB_CHECK_TRUST ||
|
|
106
105
|
verb === VERB_ADD_TRUST ||
|
|
@@ -109,22 +108,22 @@ export const executeTrustQueryOnLinux = async ({
|
|
|
109
108
|
return {
|
|
110
109
|
status: "trusted",
|
|
111
110
|
reason: REASON_FOUND_IN_LINUX,
|
|
112
|
-
}
|
|
111
|
+
};
|
|
113
112
|
}
|
|
114
113
|
|
|
115
|
-
logger.info(`Removing certificate from linux...`)
|
|
116
|
-
const removeCertificateCommand = `sudo rm ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}
|
|
117
|
-
const updateCertificateCommand = `sudo update-ca-certificates
|
|
114
|
+
logger.info(`Removing certificate from linux...`);
|
|
115
|
+
const removeCertificateCommand = `sudo rm ${JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH}`;
|
|
116
|
+
const updateCertificateCommand = `sudo update-ca-certificates`;
|
|
118
117
|
try {
|
|
119
|
-
logger.info(`${UNICODE.COMMAND} ${removeCertificateCommand}`)
|
|
120
|
-
await exec(removeCertificateCommand)
|
|
121
|
-
logger.info(`${UNICODE.COMMAND} ${updateCertificateCommand}`)
|
|
122
|
-
await exec(updateCertificateCommand)
|
|
123
|
-
logger.info(`${UNICODE.OK} certificate removed from linux`)
|
|
118
|
+
logger.info(`${UNICODE.COMMAND} ${removeCertificateCommand}`);
|
|
119
|
+
await exec(removeCertificateCommand);
|
|
120
|
+
logger.info(`${UNICODE.COMMAND} ${updateCertificateCommand}`);
|
|
121
|
+
await exec(updateCertificateCommand);
|
|
122
|
+
logger.info(`${UNICODE.OK} certificate removed from linux`);
|
|
124
123
|
return {
|
|
125
124
|
status: "not_trusted",
|
|
126
125
|
reason: REASON_REMOVE_COMMAND_COMPLETED,
|
|
127
|
-
}
|
|
126
|
+
};
|
|
128
127
|
} catch (e) {
|
|
129
128
|
logger.error(
|
|
130
129
|
createDetailedMessage(
|
|
@@ -134,25 +133,25 @@ export const executeTrustQueryOnLinux = async ({
|
|
|
134
133
|
"certificate file": JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH,
|
|
135
134
|
},
|
|
136
135
|
),
|
|
137
|
-
)
|
|
136
|
+
);
|
|
138
137
|
return {
|
|
139
138
|
status: "unknown",
|
|
140
139
|
reason: REASON_REMOVE_COMMAND_FAILED,
|
|
141
|
-
}
|
|
140
|
+
};
|
|
142
141
|
}
|
|
143
|
-
}
|
|
142
|
+
};
|
|
144
143
|
|
|
145
144
|
const getCertificateStatus = async ({ certificate }) => {
|
|
146
|
-
const certificateInStore = existsSync(JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH)
|
|
145
|
+
const certificateInStore = existsSync(JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH);
|
|
147
146
|
if (!certificateInStore) {
|
|
148
|
-
return "missing"
|
|
147
|
+
return "missing";
|
|
149
148
|
}
|
|
150
149
|
const certificateInLinuxStore = await readFile(
|
|
151
150
|
JSENV_AUTHORITY_ROOT_CERTIFICATE_PATH,
|
|
152
151
|
{ as: "string" },
|
|
153
|
-
)
|
|
152
|
+
);
|
|
154
153
|
if (certificateInLinuxStore !== certificate) {
|
|
155
|
-
return "outdated"
|
|
154
|
+
return "outdated";
|
|
156
155
|
}
|
|
157
|
-
return "found"
|
|
158
|
-
}
|
|
156
|
+
return "found";
|
|
157
|
+
};
|
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
|
|
1
|
+
// https://github.com/FiloSottile/mkcert/issues/447
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
import { exec } from "../exec.js"
|
|
3
|
+
import { UNICODE } from "@jsenv/humanize";
|
|
4
|
+
import { exec } from "../exec.js";
|
|
5
|
+
import { memoize } from "../memoize.js";
|
|
5
6
|
|
|
6
|
-
export const nssCommandName = "libnss3-tools"
|
|
7
|
+
export const nssCommandName = "libnss3-tools";
|
|
7
8
|
|
|
8
9
|
export const detectIfNSSIsInstalled = memoize(async ({ logger }) => {
|
|
9
|
-
logger.debug(`Detect if nss installed....`)
|
|
10
|
+
logger.debug(`Detect if nss installed....`);
|
|
10
11
|
|
|
11
|
-
const aptCommand = `apt list libnss3-tools --installed
|
|
12
|
-
logger.debug(`${UNICODE.COMMAND} ${aptCommand}`)
|
|
13
|
-
const aptCommandOutput = await exec(aptCommand)
|
|
12
|
+
const aptCommand = `apt list libnss3-tools --installed`;
|
|
13
|
+
logger.debug(`${UNICODE.COMMAND} ${aptCommand}`);
|
|
14
|
+
const aptCommandOutput = await exec(aptCommand);
|
|
14
15
|
|
|
15
16
|
if (aptCommandOutput.includes("libnss3-tools")) {
|
|
16
|
-
logger.debug(`${UNICODE.OK} libnss3-tools is installed`)
|
|
17
|
-
return true
|
|
17
|
+
logger.debug(`${UNICODE.OK} libnss3-tools is installed`);
|
|
18
|
+
return true;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
logger.debug(`${UNICODE.INFO} libnss3-tools not installed`)
|
|
21
|
-
return false
|
|
22
|
-
})
|
|
21
|
+
logger.debug(`${UNICODE.INFO} libnss3-tools not installed`);
|
|
22
|
+
return false;
|
|
23
|
+
});
|
|
23
24
|
|
|
24
|
-
export const getCertutilBinPath = () => "certutil"
|
|
25
|
+
export const getCertutilBinPath = () => "certutil";
|
|
25
26
|
|
|
26
27
|
export const getNSSDynamicInstallInfo = ({ logger }) => {
|
|
27
28
|
return {
|
|
28
29
|
isInstallable: true,
|
|
29
30
|
install: async () => {
|
|
30
|
-
const aptInstallCommand = `sudo apt install libnss3-tools
|
|
31
|
+
const aptInstallCommand = `sudo apt install libnss3-tools`;
|
|
31
32
|
logger.info(
|
|
32
33
|
`"libnss3-tools" is not installed, trying to install "libnss3-tools"`,
|
|
33
|
-
)
|
|
34
|
-
logger.info(`${UNICODE.COMMAND} ${aptInstallCommand}`)
|
|
35
|
-
await exec(aptInstallCommand)
|
|
34
|
+
);
|
|
35
|
+
logger.info(`${UNICODE.COMMAND} ${aptInstallCommand}`);
|
|
36
|
+
await exec(aptInstallCommand);
|
|
36
37
|
},
|
|
37
|
-
}
|
|
38
|
-
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { UNICODE } from "@jsenv/humanize";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { memoize } from "../memoize.js";
|
|
3
4
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
const REASON_CHROME_NOT_DETECTED = `Chrome not detected`
|
|
5
|
+
const REASON_CHROME_NOT_DETECTED = `Chrome not detected`;
|
|
7
6
|
|
|
8
7
|
export const executeTrustQueryOnChrome = ({ logger, macTrustInfo }) => {
|
|
9
|
-
const chromeDetected = detectChrome({ logger })
|
|
8
|
+
const chromeDetected = detectChrome({ logger });
|
|
10
9
|
if (!chromeDetected) {
|
|
11
10
|
return {
|
|
12
11
|
status: "other",
|
|
13
12
|
reason: REASON_CHROME_NOT_DETECTED,
|
|
14
|
-
}
|
|
13
|
+
};
|
|
15
14
|
}
|
|
16
15
|
|
|
17
16
|
return {
|
|
18
17
|
status: macTrustInfo.status,
|
|
19
18
|
reason: macTrustInfo.reason,
|
|
20
|
-
}
|
|
21
|
-
}
|
|
19
|
+
};
|
|
20
|
+
};
|
|
22
21
|
|
|
23
22
|
const detectChrome = memoize(({ logger }) => {
|
|
24
|
-
logger.debug(`Detecting Chrome...`)
|
|
25
|
-
const chromeDetected = existsSync("/Applications/Google Chrome.app")
|
|
23
|
+
logger.debug(`Detecting Chrome...`);
|
|
24
|
+
const chromeDetected = existsSync("/Applications/Google Chrome.app");
|
|
26
25
|
|
|
27
26
|
if (chromeDetected) {
|
|
28
|
-
logger.debug(`${UNICODE.OK} Chrome detected`)
|
|
29
|
-
return true
|
|
27
|
+
logger.debug(`${UNICODE.OK} Chrome detected`);
|
|
28
|
+
return true;
|
|
30
29
|
}
|
|
31
30
|
|
|
32
|
-
logger.debug(`${UNICODE.INFO} Chrome not detected`)
|
|
33
|
-
return false
|
|
34
|
-
})
|
|
31
|
+
logger.debug(`${UNICODE.INFO} Chrome not detected`);
|
|
32
|
+
return false;
|
|
33
|
+
});
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js"
|
|
1
|
+
import { assertAndNormalizeDirectoryUrl } from "@jsenv/filesystem";
|
|
2
|
+
import { UNICODE, createTaskLog } from "@jsenv/humanize";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { executeTrustQueryOnBrowserNSSDB } from "../nssdb_browser.js";
|
|
6
5
|
import {
|
|
7
|
-
nssCommandName,
|
|
8
6
|
detectIfNSSIsInstalled,
|
|
9
7
|
getCertutilBinPath,
|
|
10
8
|
getNSSDynamicInstallInfo,
|
|
11
|
-
|
|
9
|
+
nssCommandName,
|
|
10
|
+
} from "./nss_mac.js";
|
|
12
11
|
|
|
13
12
|
export const executeTrustQueryOnFirefox = ({
|
|
14
13
|
logger,
|
|
@@ -48,31 +47,31 @@ export const executeTrustQueryOnFirefox = ({
|
|
|
48
47
|
],
|
|
49
48
|
getBrowserClosedPromise: async () => {
|
|
50
49
|
if (!isFirefoxOpen()) {
|
|
51
|
-
return
|
|
50
|
+
return;
|
|
52
51
|
}
|
|
53
52
|
|
|
54
53
|
logger.warn(
|
|
55
54
|
`${UNICODE.WARNING} firefox is running, it must be stopped before resuming...`,
|
|
56
|
-
)
|
|
57
|
-
const closeFirefoxTask = createTaskLog("waiting for firefox to close")
|
|
55
|
+
);
|
|
56
|
+
const closeFirefoxTask = createTaskLog("waiting for firefox to close");
|
|
58
57
|
const next = async () => {
|
|
59
|
-
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
58
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
60
59
|
if (isFirefoxOpen()) {
|
|
61
|
-
await next()
|
|
60
|
+
await next();
|
|
62
61
|
} else {
|
|
63
|
-
closeFirefoxTask.done()
|
|
62
|
+
closeFirefoxTask.done();
|
|
64
63
|
// wait 50ms more to ensure firefox has time to cleanup
|
|
65
64
|
// othrwise sometimes there is an SEC_ERROR_REUSED_ISSUER_AND_SERIAL error
|
|
66
65
|
// because we updated nss database file while firefox is not fully closed
|
|
67
|
-
await new Promise((resolve) => setTimeout(resolve, 50))
|
|
66
|
+
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
68
67
|
}
|
|
69
|
-
}
|
|
70
|
-
await next()
|
|
68
|
+
};
|
|
69
|
+
await next();
|
|
71
70
|
},
|
|
72
|
-
})
|
|
73
|
-
}
|
|
71
|
+
});
|
|
72
|
+
};
|
|
74
73
|
|
|
75
74
|
const isFirefoxOpen = () => {
|
|
76
|
-
const psAux = execSync("ps aux")
|
|
77
|
-
return psAux.includes("Firefox.app")
|
|
78
|
-
}
|
|
75
|
+
const psAux = execSync("ps aux");
|
|
76
|
+
return psAux.includes("Firefox.app");
|
|
77
|
+
};
|
package/src/internal/mac/mac.js
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* - https://www.unix.com/man-page/mojave/1/security/
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import { executeTrustQueryOnSafari } from "./safari.js"
|
|
7
|
+
import { executeTrustQueryOnChrome } from "./chrome_mac.js";
|
|
8
|
+
import { executeTrustQueryOnFirefox } from "./firefox_mac.js";
|
|
9
|
+
import { executeTrustQueryOnMacKeychain } from "./mac_keychain.js";
|
|
10
|
+
import { executeTrustQueryOnSafari } from "./safari.js";
|
|
11
11
|
|
|
12
12
|
export const executeTrustQuery = async ({
|
|
13
13
|
logger,
|
|
@@ -25,13 +25,13 @@ export const executeTrustQuery = async ({
|
|
|
25
25
|
certificateIsNew,
|
|
26
26
|
certificate,
|
|
27
27
|
verb,
|
|
28
|
-
})
|
|
28
|
+
});
|
|
29
29
|
|
|
30
30
|
const chromeTrustInfo = await executeTrustQueryOnChrome({
|
|
31
31
|
logger,
|
|
32
32
|
// chrome needs macTrustInfo because it uses OS trust store
|
|
33
33
|
macTrustInfo,
|
|
34
|
-
})
|
|
34
|
+
});
|
|
35
35
|
|
|
36
36
|
const firefoxTrustInfo = await executeTrustQueryOnFirefox({
|
|
37
37
|
logger,
|
|
@@ -41,18 +41,18 @@ export const executeTrustQuery = async ({
|
|
|
41
41
|
certificate,
|
|
42
42
|
verb,
|
|
43
43
|
NSSDynamicInstall,
|
|
44
|
-
})
|
|
44
|
+
});
|
|
45
45
|
|
|
46
46
|
const safariTrustInfo = await executeTrustQueryOnSafari({
|
|
47
47
|
logger,
|
|
48
48
|
// safari needs macTrustInfo because it uses OS trust store
|
|
49
49
|
macTrustInfo,
|
|
50
|
-
})
|
|
50
|
+
});
|
|
51
51
|
|
|
52
52
|
return {
|
|
53
53
|
mac: macTrustInfo,
|
|
54
54
|
chrome: chromeTrustInfo,
|
|
55
55
|
firefox: firefoxTrustInfo,
|
|
56
56
|
safari: safariTrustInfo,
|
|
57
|
-
}
|
|
58
|
-
}
|
|
57
|
+
};
|
|
58
|
+
};
|