/** * Main Onebox coordinator class * * Coordinates all components and provides the main API */ import { logger } from './onebox.logging.ts'; import { OneboxDatabase } from './onebox.classes.database.ts'; import { OneboxDockerManager } from './onebox.classes.docker.ts'; import { OneboxServicesManager } from './onebox.classes.services.ts'; import { OneboxRegistriesManager } from './onebox.classes.registries.ts'; import { OneboxNginxManager } from './onebox.classes.nginx.ts'; import { OneboxDnsManager } from './onebox.classes.dns.ts'; import { OneboxSslManager } from './onebox.classes.ssl.ts'; import { OneboxDaemon } from './onebox.classes.daemon.ts'; import { OneboxHttpServer } from './onebox.classes.httpserver.ts'; export class Onebox { public database: OneboxDatabase; public docker: OneboxDockerManager; public services: OneboxServicesManager; public registries: OneboxRegistriesManager; public nginx: OneboxNginxManager; public dns: OneboxDnsManager; public ssl: OneboxSslManager; public daemon: OneboxDaemon; public httpServer: OneboxHttpServer; private initialized = false; constructor() { // Initialize database first this.database = new OneboxDatabase(); // Initialize managers (passing reference to main Onebox instance) this.docker = new OneboxDockerManager(); this.services = new OneboxServicesManager(this); this.registries = new OneboxRegistriesManager(this); this.nginx = new OneboxNginxManager(this); this.dns = new OneboxDnsManager(this); this.ssl = new OneboxSslManager(this); this.daemon = new OneboxDaemon(this); this.httpServer = new OneboxHttpServer(this); } /** * Initialize all components */ async init(): Promise { try { logger.info('Initializing Onebox...'); // Initialize database await this.database.init(); // Ensure default admin user exists await this.ensureDefaultUser(); // Initialize Docker await this.docker.init(); // Initialize Nginx await this.nginx.init(); // Initialize DNS (non-critical) try { await this.dns.init(); } catch (error) { logger.warn('DNS initialization failed - DNS features will be disabled'); } // Initialize SSL (non-critical) try { await this.ssl.init(); } catch (error) { logger.warn('SSL initialization failed - SSL features will be limited'); } // Login to all registries await this.registries.loginToAllRegistries(); this.initialized = true; logger.success('Onebox initialized successfully'); } catch (error) { logger.error(`Failed to initialize Onebox: ${error.message}`); throw error; } } /** * Ensure default admin user exists */ private async ensureDefaultUser(): Promise { try { const adminUser = this.database.getUserByUsername('admin'); if (!adminUser) { logger.info('Creating default admin user...'); // Hash default password 'admin' const passwordHash = await Deno.readTextFile('/dev/urandom').then((data) => // Simple hash for now - should use bcrypt btoa('admin') ); await this.database.createUser({ username: 'admin', passwordHash: btoa('admin'), // Simple encoding for now role: 'admin', createdAt: Date.now(), updatedAt: Date.now(), }); logger.warn('Default admin user created with username: admin, password: admin'); logger.warn('IMPORTANT: Change the default password immediately!'); } } catch (error) { logger.error(`Failed to create default user: ${error.message}`); } } /** * Check if Onebox is initialized */ isInitialized(): boolean { return this.initialized; } /** * Get system status */ async getSystemStatus() { try { const dockerRunning = await this.docker.isDockerRunning(); const nginxStatus = await this.nginx.getStatus(); const dnsConfigured = this.dns.isConfigured(); const sslConfigured = this.ssl.isConfigured(); const services = this.services.listServices(); const runningServices = services.filter((s) => s.status === 'running').length; const totalServices = services.length; return { docker: { running: dockerRunning, version: dockerRunning ? await this.docker.getDockerVersion() : null, }, nginx: { status: nginxStatus, installed: await this.nginx.isInstalled(), }, dns: { configured: dnsConfigured, }, ssl: { configured: sslConfigured, certbotInstalled: await this.ssl.isCertbotInstalled(), }, services: { total: totalServices, running: runningServices, stopped: totalServices - runningServices, }, }; } catch (error) { logger.error(`Failed to get system status: ${error.message}`); throw error; } } /** * Start daemon mode */ async startDaemon(): Promise { await this.daemon.start(); } /** * Stop daemon mode */ async stopDaemon(): Promise { await this.daemon.stop(); } /** * Start HTTP server */ async startHttpServer(port?: number): Promise { await this.httpServer.start(port); } /** * Stop HTTP server */ async stopHttpServer(): Promise { await this.httpServer.stop(); } /** * Shutdown Onebox gracefully */ async shutdown(): Promise { try { logger.info('Shutting down Onebox...'); // Stop daemon if running await this.daemon.stop(); // Stop HTTP server if running await this.httpServer.stop(); // Close database this.database.close(); logger.success('Onebox shutdown complete'); } catch (error) { logger.error(`Error during shutdown: ${error.message}`); } } }