From 1ad80b5219378aafbc77cd1ee1c6b356a41adc52 Mon Sep 17 00:00:00 2001 From: Aldo D'Aquino Date: Sun, 18 Aug 2019 10:34:32 +0200 Subject: [PATCH] v4.2.0 Catilina support, check for updates, bug fix (#19) - Update to mkcert v1.4.0: macOS Catalina compatibility and more. https://github.com/FiloSottile/mkcert/releases/tag/v1.4.0 - Add `REINSTALL=true serve` env variable to force reinstall certs. - Check for updates if running as compiled executable (downloaded from GitHub releases). - Update dependencies. - Add troubleshooting for #13. --- README.md | 9 +++++++- certs.js | 39 +++++++++++++++++++++++++++++++++- package-lock.json | 54 +++++++++++++++++++++-------------------------- package.json | 6 +++--- test/test.js | 29 +++++++++++++++++++++++-- 5 files changed, 100 insertions(+), 37 deletions(-) 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()