UNPKG

@axlotl-lab/navigrator

Version:

A powerful local domain manager for development environments. Navigrator helps you manage local domains and SSL certificates with a simple web interface.

340 lines (339 loc) 14.5 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CAInstaller = void 0; const child_process_1 = require("child_process"); const fs = __importStar(require("fs")); const os = __importStar(require("os")); const path = __importStar(require("path")); const util_1 = require("util"); const ca_generator_1 = require("./ca-generator"); const execAsync = (0, util_1.promisify)(child_process_1.exec); class CAInstaller { constructor(certsDir) { const rootDir = certsDir || path.join(os.homedir(), '.navigrator', 'certs'); const caDir = path.join(rootDir, 'ca'); this.caPath = path.join(caDir, 'rootCA.crt'); this.caKeyPath = path.join(caDir, 'rootCA.key'); this.caGenerator = new ca_generator_1.CAGenerator(rootDir); } /** * Check if the CA certificate exists */ checkCAExists() { return __awaiter(this, void 0, void 0, function* () { try { yield fs.promises.access(this.caPath); yield fs.promises.access(this.caKeyPath); return true; } catch (error) { return false; } }); } /** * Generate and install the CA certificate */ generateAndInstallCA() { return __awaiter(this, void 0, void 0, function* () { try { // First check if OpenSSL is installed const hasOpenSSL = yield this.caGenerator.checkOpenSSLInstalled(); if (!hasOpenSSL) { return { success: false, message: 'OpenSSL is not installed or not available in the PATH. Please install OpenSSL to continue.' }; } // Initialize directories yield this.caGenerator.initialize(); // Generate the CA if it doesn't exist yield this.caGenerator.generateCA(); // Install the CA return yield this.installCA(); } catch (error) { return { success: false, message: `Error generating and installing CA: ${error === null || error === void 0 ? void 0 : error.message}` }; } }); } /** * Install the CA certificate based on the platform */ installCA() { return __awaiter(this, void 0, void 0, function* () { // First check if the CA exists const caExists = yield this.checkCAExists(); if (!caExists) { return { success: false, message: 'CA certificate not found. Please run "navigrator init-ca" first to generate it.' }; } const platform = os.platform(); try { if (platform === 'win32') { return yield this.installOnWindows(); } else if (platform === 'darwin') { return yield this.installOnMacOS(); } else if (platform === 'linux') { return yield this.installOnLinux(); } else { return { success: false, message: `Unsupported platform: ${platform}. Please install the CA manually.` }; } } catch (error) { return { success: false, message: `Error installing CA: ${error === null || error === void 0 ? void 0 : error.message}` }; } }); } /** * Install CA on Windows using certutil */ installOnWindows() { return __awaiter(this, void 0, void 0, function* () { var _a; try { // Check if certutil is available yield execAsync('certutil -?'); // Install the certificate to the Trusted Root CA store yield execAsync(`certutil -addstore -f "ROOT" "${this.caPath}"`); return { success: true, message: 'CA certificate has been installed in the Windows Trusted Root CA store.' }; } catch (error) { if ((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('Access is denied')) { return { success: false, message: 'Administrator privileges required. Please run the command as administrator.' }; } throw error; } }); } /** * Install CA on macOS using the security command */ installOnMacOS() { return __awaiter(this, void 0, void 0, function* () { var _a; try { // Add to system keychain yield execAsync(`sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain "${this.caPath}"`); // Also add to Firefox if installed (Firefox uses its own certificate store) yield this.installOnFirefox(); return { success: true, message: 'CA certificate has been installed in the macOS System Keychain. You may need to restart browsers for changes to take effect.' }; } catch (error) { if ((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('password')) { return { success: false, message: 'Sudo privileges required. Please run with sudo: sudo navigrator install-ca' }; } throw error; } }); } /** * Install CA on Linux */ installOnLinux() { return __awaiter(this, void 0, void 0, function* () { var _a, _b; try { // Try to determine the distribution type const hasApt = yield this.commandExists('apt'); const hasYum = yield this.commandExists('yum'); const hasDnf = yield this.commandExists('dnf'); const hasUpdateCACerts = yield this.commandExists('update-ca-certificates'); const hasUpdateCATrust = yield this.commandExists('update-ca-trust'); if (hasApt || hasUpdateCACerts) { // Debian/Ubuntu style yield execAsync(`sudo cp "${this.caPath}" /usr/local/share/ca-certificates/navigrator-root-ca.crt`); yield execAsync('sudo update-ca-certificates'); } else if (hasYum || hasDnf || hasUpdateCATrust) { // RHEL/Fedora style yield execAsync(`sudo cp "${this.caPath}" /etc/pki/ca-trust/source/anchors/navigrator-root-ca.crt`); yield execAsync('sudo update-ca-trust'); } else { return { success: false, message: 'Could not determine Linux distribution. Please install the CA certificate manually.' }; } // Also add to Firefox if installed yield this.installOnFirefox(); // Chrome on Linux typically uses the system store so no additional steps needed return { success: true, message: 'CA certificate has been installed in the system certificate store. You may need to restart browsers for changes to take effect.' }; } catch (error) { if (((_a = error === null || error === void 0 ? void 0 : error.message) === null || _a === void 0 ? void 0 : _a.includes('sudo')) || ((_b = error === null || error === void 0 ? void 0 : error.message) === null || _b === void 0 ? void 0 : _b.includes('permission'))) { return { success: false, message: 'Sudo privileges required. Please run with sudo: sudo navigrator install-ca' }; } throw error; } }); } /** * Install CA in Firefox (all platforms) * This is a complex process as Firefox uses its own certificate store */ installOnFirefox() { return __awaiter(this, void 0, void 0, function* () { try { // Check if Firefox is installed let firefoxPath = ''; const platform = os.platform(); if (platform === 'win32') { const programFiles = process.env['ProgramFiles'] || 'C:\\Program Files'; const programFilesX86 = process.env['ProgramFiles(x86)'] || 'C:\\Program Files (x86)'; const possiblePaths = [ path.join(programFiles, 'Mozilla Firefox', 'firefox.exe'), path.join(programFilesX86, 'Mozilla Firefox', 'firefox.exe') ]; for (const p of possiblePaths) { try { yield fs.promises.access(p); firefoxPath = p; break; } catch (e) { // Path doesn't exist } } } else if (platform === 'darwin') { const possiblePaths = [ '/Applications/Firefox.app/Contents/MacOS/firefox' ]; for (const p of possiblePaths) { try { yield fs.promises.access(p); firefoxPath = p; break; } catch (e) { // Path doesn't exist } } } else if (platform === 'linux') { // Check if Firefox is in PATH try { yield execAsync('which firefox'); firefoxPath = 'firefox'; } catch (e) { // Firefox not in PATH } } if (!firefoxPath) { // Firefox not found or not supported on this platform return; } // Firefox installation detected, but we won't attempt to modify its cert store // as it's complex and requires restarting Firefox or creating a new profile console.log('Firefox detected. Please import the CA certificate manually in Firefox:\n' + '1. Open Firefox and go to Settings/Preferences\n' + '2. Search for "certificates" and click "View Certificates"\n' + '3. Go to the "Authorities" tab and click "Import"\n' + `4. Select the certificate file at: ${this.caPath}\n` + '5. Check "Trust this CA to identify websites" and click OK'); } catch (error) { // Ignore errors with Firefox detection/installation console.log('Note: Could not detect Firefox installation.'); } }); } /** * Check if a command exists in the PATH */ commandExists(command) { return __awaiter(this, void 0, void 0, function* () { try { const platform = os.platform(); if (platform === 'win32') { yield execAsync(`where ${command}`); } else { yield execAsync(`which ${command}`); } return true; } catch (error) { return false; } }); } } exports.CAInstaller = CAInstaller;