diff --git a/README.md b/README.md
index 2bb505c..d68af03 100644
--- a/README.md
+++ b/README.md
@@ -98,7 +98,7 @@ Checkout the updated list [here](https://github.com/FiloSottile/mkcert/blob/mast
## Troubleshooting
### Node.js version
https-localhost requires Node.js 8 or higher.
-If you need compatibility with previously Node.js versions let me know, I'll try to rearrange the code.
+If you need compatibility with previously Node.js versions let me know, we'll try to rearrange the code.
### root required
- **At first run** this tool generate a trusted certificate. The sudo password may be required. If you cannot provide the sudo password generate a `localhost.key` and `localhost.crt` and specify its path with `CERT_PATH=/diractory/containing/certificates/ serve ~/myproj`.
@@ -123,6 +123,13 @@ It should be present only with `NODE_ENV=production`, hence the easiest fix is t
I've tried to reproduce this error without any success (checkout the [Travis build logs](https://travis-ci.org/daquinoaldo/https-localhost)). If you can help please open an issue and describe as better as you can how to reproduce it, I'll be happy to help you.
+### ERR_SSL_PROTOCOL_ERROR
+And in general all the cases when the script runs but the connection is marked as untrusted.
+
+Force a reinstall of the certificate with `REINSTALL=true serve`. `sudo` may be required on linux and MacOS.
+
+If the problem is solved you should be able to use https-localhost also as module.
+
## Contributing
Each contribute is welcome!
diff --git a/certs.js b/certs.js
index 927f50f..04c879e 100644
--- a/certs.js
+++ b/certs.js
@@ -6,9 +6,36 @@ const exec = require("child_process").exec
const https = require("https")
const getAppDataPath = require("appdata-path")
-const MKCERT_VERSION = "v1.3.0"
+const MKCERT_VERSION = "v1.4.0"
const CERT_PATH = getAppDataPath("https-localhost")
+// check for updates
+/* istanbul ignore next: cannot test pkg */
+function checkUpdates() {
+ try {
+ const options = {
+ host: "api.github.com",
+ path: "/repos/daquinoaldo/https-localhost/releases/latest",
+ method: "GET",
+ headers: { "User-Agent": "node.js" }
+ }
+ https.request(options, res => {
+ let body = ""
+ res.on("data", chunk => { body += chunk.toString("utf8") })
+ res.on("end", () => {
+ const currentVersion = JSON.parse(fs.readFileSync(
+ path.resolve(__dirname, "package.json"))).version
+ const latestVersion = JSON.parse(body).tag_name.replace("v", "")
+ if (currentVersion !== latestVersion)
+ console.warn("[https-localhost] New update available.")
+ })
+ }).end()
+ } catch (e) {
+ // Just catch everything, this is not a critic part and can fail.
+ // It is important to not affect the script behavior.
+ }
+}
+
// get the executable name
function getExe() {
/* istanbul ignore next: tested on all platform on travis */
@@ -71,6 +98,8 @@ function mkcert(appDataPath, exe) {
async function generate(appDataPath = CERT_PATH) {
console.info("Generating certificates...")
+ console.log("Certificates path: " + appDataPath +
+ ". Never modify nor share this files.")
// mkdir if not exists
/* istanbul ignore else: not relevant */
if (!fs.existsSync(appDataPath))
@@ -91,12 +120,20 @@ async function generate(appDataPath = CERT_PATH) {
async function getCerts() {
const certPath = process.env.CERT_PATH || CERT_PATH
+ // check for updates if running as executable
+ /* istanbul ignore if: cannot test pkg */
+ if (process.pkg) checkUpdates()
+ // check if a reinstall is forced or needed by a mkcert update
+ if (process.env.REINSTALL ||
+ !fs.existsSync(path.join(certPath, getExe())))
+ await generate(certPath)
try {
return {
key: fs.readFileSync(path.join(certPath, "localhost.key")),
cert: fs.readFileSync(path.join(certPath, "localhost.crt"))
}
} catch (e) {
+ /* istanbul ignore else: should never occur */
if (certPath !== CERT_PATH) {
console.error("Cannot find localhost.key and localhost.crt in the" +
" specified path: " + certPath)
diff --git a/package-lock.json b/package-lock.json
index 7f40058..fcd9ac4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "https-localhost",
- "version": "4.1.3",
+ "version": "4.2.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -173,9 +173,9 @@
}
},
"@sinonjs/samsam": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.1.tgz",
- "integrity": "sha512-wRSfmyd81swH0hA1bxJZJ57xr22kC07a1N4zuIL47yTS04bDk6AoCkczcqHEjcRPmJ+FruGJ9WBQiJwMtIElFw==",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.2.tgz",
+ "integrity": "sha512-ILO/rR8LfAb60Y1Yfp9vxfYAASK43NFC2mLzpvLUbCQY/Qu8YwReboseu8aheCEkyElZF2L2T9mHcR2bgdvZyA==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.0.2",
@@ -864,9 +864,9 @@
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"coveralls": {
- "version": "3.0.5",
- "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.5.tgz",
- "integrity": "sha512-/KD7PGfZv/tjKB6LoW97jzIgFqem0Tu9tZL9/iwBnBd8zkIZp7vT1ZSHNvnr0GSQMV/LTMxUstWg8WcDDUVQKg==",
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/coveralls/-/coveralls-3.0.6.tgz",
+ "integrity": "sha512-Pgh4v3gCI4T/9VijVrm8Ym5v0OgjvGLKj3zTUwkvsCiwqae/p6VLzpsFNjQS2i6ewV7ef+DjFJ5TSKxYt/mCrA==",
"dev": true,
"requires": {
"growl": "~> 1.10.0",
@@ -2878,9 +2878,9 @@
}
},
"lolex": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.0.1.tgz",
- "integrity": "sha512-UHuOBZ5jjsKuzbB/gRNNW8Vg8f00Emgskdq2kvZxgBJCS0aqquAuXai/SkWORlKeZEiNQWZjFZOqIUcH9LqKCw==",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lolex/-/lolex-4.2.0.tgz",
+ "integrity": "sha512-gKO5uExCXvSm6zbF562EvM+rd1kQDnB9AZBbiQVzf1ZmdDpxUSvpnAaVOP83N/31mRK8Ml8/VE8DMvsAZQ+7wg==",
"dev": true
},
"lru-cache": {
@@ -3296,15 +3296,15 @@
"dev": true
},
"nise": {
- "version": "1.4.10",
- "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz",
- "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/nise/-/nise-1.5.1.tgz",
+ "integrity": "sha512-edFWm0fsFG2n318rfEnKlTZTkjlbVOFF9XIA+fj+Ed+Qz1laYW2lobwavWoMzGrYDHH1EpiNJgDfvGnkZztR/g==",
"dev": true,
"requires": {
- "@sinonjs/formatio": "^3.1.0",
+ "@sinonjs/formatio": "^3.2.1",
"@sinonjs/text-encoding": "^0.7.1",
"just-extend": "^4.0.2",
- "lolex": "^2.3.2",
+ "lolex": "^4.1.0",
"path-to-regexp": "^1.7.0"
},
"dependencies": {
@@ -3314,12 +3314,6 @@
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
- "lolex": {
- "version": "2.7.5",
- "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz",
- "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==",
- "dev": true
- },
"path-to-regexp": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz",
@@ -3422,7 +3416,7 @@
"dependencies": {
"find-up": {
"version": "3.0.0",
- "resolved": false,
+ "resolved": "",
"integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
"dev": true,
"requires": {
@@ -3431,7 +3425,7 @@
},
"locate-path": {
"version": "3.0.0",
- "resolved": false,
+ "resolved": "",
"integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
"dev": true,
"requires": {
@@ -3450,7 +3444,7 @@
},
"p-locate": {
"version": "3.0.0",
- "resolved": false,
+ "resolved": "",
"integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
"dev": true,
"requires": {
@@ -4270,17 +4264,17 @@
"dev": true
},
"sinon": {
- "version": "7.3.2",
- "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.3.2.tgz",
- "integrity": "sha512-thErC1z64BeyGiPvF8aoSg0LEnptSaWE7YhdWWbWXgelOyThent7uKOnnEh9zBxDbKixtr5dEko+ws1sZMuFMA==",
+ "version": "7.4.1",
+ "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.4.1.tgz",
+ "integrity": "sha512-7s9buHGHN/jqoy/v4bJgmt0m1XEkCEd/tqdHXumpBp0JSujaT4Ng84JU5wDdK4E85ZMq78NuDe0I3NAqXY8TFg==",
"dev": true,
"requires": {
"@sinonjs/commons": "^1.4.0",
"@sinonjs/formatio": "^3.2.1",
- "@sinonjs/samsam": "^3.3.1",
+ "@sinonjs/samsam": "^3.3.2",
"diff": "^3.5.0",
- "lolex": "^4.0.1",
- "nise": "^1.4.10",
+ "lolex": "^4.2.0",
+ "nise": "^1.5.1",
"supports-color": "^5.5.0"
}
},
diff --git a/package.json b/package.json
index 4d6ace9..478166e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "https-localhost",
- "version": "4.1.3",
+ "version": "4.2.0",
"description": "HTTPS server running on localhost",
"main": "index.js",
"scripts": {
@@ -51,7 +51,7 @@
"spdy": "^4.0.1"
},
"devDependencies": {
- "coveralls": "^3.0.5",
+ "coveralls": "^3.0.6",
"eslint": "^6.1.0",
"eslint-config-standard": "^13.0.1",
"eslint-plugin-import": "^2.18.2",
@@ -61,6 +61,6 @@
"mocha": "^6.2.0",
"nyc": "^14.1.1",
"pkg": "^4.4.0",
- "sinon": "^7.3.2"
+ "sinon": "^7.4.1"
}
}
diff --git a/test/test.js b/test/test.js
index 71a2030..33619cb 100644
--- a/test/test.js
+++ b/test/test.js
@@ -72,11 +72,34 @@ describe("Testing certs", function() {
})()
})
+ it("can be installed in custom folder", function(done) {
+ // inner async function
+ (async() => {
+ // set a custom cert path
+ process.env.CERT_PATH = "test/custom-folder"
+ // prepare the server with a mock response
+ app.get("/test/module", (req, res) => res.send("TEST"))
+ // start the server
+ await app.listen(HTTPS_PORT)
+ // make the request and check the output
+ await makeRequest("/test/module")
+ .then(res => assert(res.data === "TEST"))
+ // close the server
+ app.server.close()
+ // restore the CERT_PATH to undefined
+ delete process.env.CERT_PATH
+ done()
+ })()
+ })
+
it("crashes if certs doesn't exists in custom folder", function(done) {
// inner async function
(async() => {
- // set a non-existent custom cert path
- process.env.CERT_PATH = "does-not-exist"
+ // set a custom cert path
+ process.env.CERT_PATH = "test/custom-folder"
+ // remove the certificates
+ fs.unlinkSync("test/custom-folder/localhost.crt")
+ fs.unlinkSync("test/custom-folder/localhost.key")
// stub the exit function
sinon.stub(process, "exit")
// listen
@@ -86,6 +109,8 @@ describe("Testing certs", function() {
process.exit.restore()
// close the server
app.server.close()
+ // delete the custom folder
+ certs.remove(process.env.CERT_PATH)
// restore the CERT_PATH to undefined
delete process.env.CERT_PATH
done()