@knapsack/https
Version:
Automatically provisions and installs locally-trusted TLS certificates for Node.js https servers (including Express.js, etc.) using mkcert.
93 lines • 5.01 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.setupAndGetCert = setupAndGetCert;
const os_1 = __importDefault(require("os"));
const fs_extra_1 = __importDefault(require("fs-extra"));
const path_1 = __importDefault(require("path"));
const child_process_1 = __importDefault(require("child_process"));
const chalk_1 = __importDefault(require("chalk"));
const log_1 = require("../log");
const install_cert_util_1 = require("./install-cert-util");
const constants_1 = require("../constants");
const setup_local_cert_auth_1 = require("./setup-local-cert-auth");
const pre_install_mkcert_1 = require("./pre-install-mkcert");
async function setupAndGetCert() {
const mkcertBinary = path_1.default.join(constants_1.settingsPath, constants_1.binaryName);
const keyFilePath = path_1.default.join(constants_1.settingsPath, 'localhost-key.pem');
const certFilePath = path_1.default.join(constants_1.settingsPath, 'localhost.pem');
const rootCAKeyFilePath = path_1.default.join(constants_1.settingsPath, 'rootCA-key.pem');
const rootCACertFilePath = path_1.default.join(constants_1.settingsPath, 'rootCA.pem');
// if we failed to get the mkcert file downloaded by this point, exit early
// @todo: add even more CLI logging for each of these use cases
await (0, pre_install_mkcert_1.preInstallMkCert)();
if (!fs_extra_1.default.existsSync(mkcertBinary))
return null;
const mkcertBinarySize = fs_extra_1.default.statSync(mkcertBinary);
// exit early if the mkcert file size is 0 bytes (a bad download)
if (mkcertBinarySize.size === 0)
return null;
function allOK() {
return (fs_extra_1.default.existsSync(rootCACertFilePath) &&
fs_extra_1.default.existsSync(rootCAKeyFilePath) &&
fs_extra_1.default.existsSync(certFilePath) &&
fs_extra_1.default.existsSync(keyFilePath));
}
// Create certificates.
if (!allOK()) {
log_1.log.info(' 📜 ❨auto-encrypt-localhost❩ Setting up…');
// On Linux and on macOS, mkcert uses the Mozilla nss library.
// Try to install this automatically and warn the person if we can’t so
// that they can do it manually themselves.
await (0, install_cert_util_1.installCertutil)();
// Create the local certificate.
log_1.log.info(' 📜 ❨auto-encrypt-localhost❩ Creating local TLS certificates using mkcert…');
// Support all local interfaces so that the machine can be reached over the local network via IPv4.
// This is very useful for testing with multiple devices over the local area network without needing to expose
// the machine over the wide area network/Internet using a service like ngrok.
const localIPv4Addresses = Object.entries(os_1.default.networkInterfaces())
.map((iface) => {
var _a;
return (_a = iface[1]) === null || _a === void 0 ? void 0 : _a.filter((addresses) => addresses.family === 'IPv4').map((addresses) => addresses.address);
})
.flat();
const certificateDetails = [
`-key-file=${keyFilePath}`,
`-cert-file=${certFilePath}`,
'localhost',
].concat(localIPv4Addresses.filter((address) => address !== undefined));
child_process_1.default.execFileSync(mkcertBinary, certificateDetails, constants_1.mkcertProcessOptions);
log_1.log.info(' 📜 ❨auto-encrypt-localhost❩ Local TLS certificates created.');
const wasSuccessful = await (0, setup_local_cert_auth_1.setupLocalCertAuthority)({
certFilePath,
keyFilePath,
mkcertBinary,
});
if (!wasSuccessful) {
log_1.log.warn(chalk_1.default.yellow('Failed to auto-create a local certificate authority (local CA) so exiting early.'));
return null;
}
if (rootCACertFilePath) {
import('syswide-cas').then(async (syswidecas) => {
await syswidecas.addCAs(rootCACertFilePath);
});
}
if (!allOK()) {
log_1.log.warn('Ran into an unexpected issue setting up HTTPS. Exiting early');
return null;
}
// Add root store to Node to ensure Node recognises the certificates (e.g., when using https.get(), etc.)
return {
key: fs_extra_1.default.readFileSync(keyFilePath, 'utf-8'),
cert: fs_extra_1.default.readFileSync(certFilePath, 'utf-8'),
};
}
log_1.log.info(' 📜 ❨auto-encrypt-localhost❩ Local development TLS certificate exists.');
return {
key: fs_extra_1.default.readFileSync(keyFilePath, 'utf-8'),
cert: fs_extra_1.default.readFileSync(certFilePath, 'utf-8'),
};
}
//# sourceMappingURL=auto-encrypt-localhost.js.map