UNPKG

navy

Version:

Quick and powerful development environments using Docker and Docker Compose

161 lines (159 loc) 6.32 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = _default; var _path = _interopRequireDefault(require("path")); var _chalk = _interopRequireDefault(require("chalk")); var _errors = require("../errors"); var _navy = require("../navy"); var _config = require("../config"); var _httpProxy = require("../http-proxy"); var _https = require("../util/https"); var _installRootCa = require("../util/install-root-ca"); var _fs = _interopRequireDefault(require("fs")); function normaliseServiceArgs(services) { if (services == null) { return []; } if (Array.isArray(services)) { const result = []; for (const s of services) { if (typeof s === 'string' && s !== '') { result.push(s); } } return result; } if (typeof services === 'string') { return services ? [services] : []; } return []; } async function issueHttpsForServices(navy, serviceNames, availableServices) { const httpsReadyServices = []; for (const service of serviceNames) { if (!availableServices.includes(service)) { console.log(`❌ ${service} not found, skipping`); continue; } const serviceUrl = await navy.url(service); try { await (0, _https.createCert)({ serviceUrl }); httpsReadyServices.push(service); } catch (error) { console.log(error); throw new _errors.NavyError(`Could not generate TLS cert for ${service}`); } } return httpsReadyServices; } async function _default(services, opts) { const tlsRootCaDir = (0, _config.getConfig)().tlsRootCaDir || _config.DEFAULT_TLS_ROOT_CA_DIR; const configDir = (0, _config.getConfigDir)(); const serviceList = normaliseServiceArgs(services); const hasIssue = Boolean(opts.issue); if (opts.disable && (opts.setup || opts.all || hasIssue)) { throw new _errors.NavyError('`--disable` cannot be combined with `--setup`, `--all`, or `--issue`.'); } if ([opts.setup, opts.all, hasIssue].filter(Boolean).length > 1) { throw new _errors.NavyError('Use only one of `--setup`, `--all`, or `--issue`.'); } if (opts.disable) { await (0, _https.removeCert)(opts); // Guard isInitialised so `--disable` still works when the navy has // never been launched (otherwise getNavyFile throws). const navy = await (0, _navy.getNavy)(opts.navy); const navyFile = (await navy.isInitialised()) ? await navy.getNavyFile() : undefined; await (0, _httpProxy.reconfigureHTTPProxy)({ restart: true, navyFile }); console.log(); console.log(_chalk.default.green(`✅ HTTPS for service ${opts.disable} is now disabled`)); console.log(); return; } if (opts.setup) { if (serviceList.length > 0) { throw new _errors.NavyError('`navy https --setup` does not take service names. Run `navy https <service>…` separately to issue service certificates.'); } await (0, _https.generateRootCa)(); const caCrt = _path.default.join(tlsRootCaDir, 'ca.crt'); (0, _installRootCa.installRootCaToTrustStore)(caCrt); console.log(); console.log(_chalk.default.green('✅ Navy root CA is installed in your trust store (where supported).')); console.log(_chalk.default.dim('Browsers that use their own NSS store (e.g. Firefox) may still need the CA imported there.')); console.log(); return; } if (opts.all) { if (serviceList.length > 0) { throw new _errors.NavyError('`navy https --all` does not take service names. Omit them, or name services without `--all`.'); } if (!_fs.default.existsSync(`${tlsRootCaDir}/ca.crt`) || !_fs.default.existsSync(`${tlsRootCaDir}/ca.key`)) { await (0, _https.generateRootCa)(); } const navy = await (0, _navy.getNavy)(opts.navy); await navy.ensurePluginsLoaded(); const availableServices = await navy.getAvailableServiceNames(); if (availableServices.length === 0) { console.log(); console.log(_chalk.default.yellow('No services found in this navy; nothing to enable HTTPS for.')); console.log(); return; } const httpsReadyServices = await issueHttpsForServices(navy, availableServices, availableServices); await (0, _httpProxy.reconfigureHTTPProxy)({ restart: true, navyFile: await navy.getNavyFile() }); console.log(); console.log(_chalk.default.green(`✅ Service(s) ${httpsReadyServices.join(', ')} now accessible via HTTPS🔒`)); console.log(); return; } if (hasIssue) { if (serviceList.length > 0) { throw new _errors.NavyError('`navy https --issue` does not take service names.'); } const outDir = opts.issueOut ? _path.default.resolve(opts.issueOut) : process.cwd(); const paths = await (0, _https.issueLeafCertForUrl)(String(opts.issue), outDir); console.log(); console.log(_chalk.default.green('✅ TLS certificate issued for use outside Navy:')); console.log(` ${paths.certPath}`); console.log(` ${paths.keyPath}`); console.log(` ${paths.caCopyPath} (root CA; configure clients to trust this or append as a chain file)`); console.log(); return; } if (serviceList.length === 0) { if (!_fs.default.existsSync(`${configDir}/tls-certs`)) return; const files = _fs.default.readdirSync(`${configDir}/tls-certs`); const urls = files.filter(file => file.endsWith('.crt')).map(crt => { return `https://${crt.replace('.crt', '')}`; }); for (const url of urls) { console.log(`${url}`); } return; } if (!_fs.default.existsSync(`${tlsRootCaDir}/ca.crt`) || !_fs.default.existsSync(`${tlsRootCaDir}/ca.key`)) { await (0, _https.generateRootCa)(); } const navy = await (0, _navy.getNavy)(opts.navy); await navy.ensurePluginsLoaded(); const availableServices = await navy.getAvailableServiceNames(); const httpsReadyServices = await issueHttpsForServices(navy, serviceList, availableServices); await (0, _httpProxy.reconfigureHTTPProxy)({ restart: true, navyFile: await navy.getNavyFile() }); console.log(); console.log(_chalk.default.green(`✅ Service(s) ${httpsReadyServices.join(', ')} now accessible via HTTPS🔒`)); console.log(); } module.exports = exports.default;