From 76bfcf6a730f9cdc2dd0bd57459ebe4c377d6478 Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Tue, 18 Nov 2025 19:37:06 +0000 Subject: [PATCH] update --- .gitignore | 1 + dist/binaries/.gitkeep | 1 - ts/classes/httpserver.ts | 140 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 1 deletion(-) delete mode 100644 dist/binaries/.gitkeep diff --git a/.gitignore b/.gitignore index fe5f1f6..c11517e 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,4 @@ logs/ *.log .playwright-mcp +./dist/ diff --git a/dist/binaries/.gitkeep b/dist/binaries/.gitkeep deleted file mode 100644 index f627a00..0000000 --- a/dist/binaries/.gitkeep +++ /dev/null @@ -1 +0,0 @@ -# Keep this directory in git diff --git a/ts/classes/httpserver.ts b/ts/classes/httpserver.ts index f290a5f..d576b76 100644 --- a/ts/classes/httpserver.ts +++ b/ts/classes/httpserver.ts @@ -519,6 +519,146 @@ export class OneboxHttpServer { } } + private async handleGetDomainsRequest(): Promise { + try { + const domains = this.oneboxRef.database.getAllDomains(); + const certManager = this.oneboxRef.certRequirementManager; + + // Build domain views with certificate and service information + const domainViews = domains.map((domain) => { + const certificates = this.oneboxRef.database.getCertificatesByDomain(domain.id!); + const requirements = this.oneboxRef.database.getCertRequirementsByDomain(domain.id!); + + // Count services using this domain + const allServices = this.oneboxRef.database.getAllServices(); + const serviceCount = allServices.filter((service) => { + if (!service.domain) return false; + // Extract base domain from service domain + const baseDomain = service.domain.split('.').slice(-2).join('.'); + return baseDomain === domain.domain; + }).length; + + // Determine certificate status + let certificateStatus: 'valid' | 'expiring-soon' | 'expired' | 'pending' | 'none' = + 'none'; + let daysRemaining: number | null = null; + + const validCerts = certificates.filter((cert) => cert.isValid && cert.expiryDate > Date.now()); + if (validCerts.length > 0) { + // Find cert with furthest expiry + const latestCert = validCerts.reduce((latest, cert) => + cert.expiryDate > latest.expiryDate ? cert : latest + ); + + daysRemaining = Math.floor((latestCert.expiryDate - Date.now()) / (24 * 60 * 60 * 1000)); + + if (daysRemaining <= 30) { + certificateStatus = 'expiring-soon'; + } else { + certificateStatus = 'valid'; + } + } else if (certificates.some((cert) => !cert.isValid)) { + certificateStatus = 'expired'; + } else if (requirements.some((req) => req.status === 'pending')) { + certificateStatus = 'pending'; + } + + return { + domain, + certificates, + requirements, + serviceCount, + certificateStatus, + daysRemaining, + }; + }); + + return this.jsonResponse({ success: true, data: domainViews }); + } catch (error) { + logger.error(`Failed to get domains: ${error.message}`); + return this.jsonResponse({ + success: false, + error: error.message || 'Failed to get domains', + }, 500); + } + } + + private async handleSyncDomainsRequest(): Promise { + try { + if (!this.oneboxRef.cloudflareDomainSync) { + return this.jsonResponse({ + success: false, + error: 'Cloudflare domain sync not configured', + }, 400); + } + + await this.oneboxRef.cloudflareDomainSync.syncZones(); + + return this.jsonResponse({ + success: true, + message: 'Cloudflare zones synced successfully', + }); + } catch (error) { + logger.error(`Failed to sync Cloudflare zones: ${error.message}`); + return this.jsonResponse({ + success: false, + error: error.message || 'Failed to sync Cloudflare zones', + }, 500); + } + } + + private async handleGetDomainDetailRequest(domainName: string): Promise { + try { + const domain = this.oneboxRef.database.getDomainByName(domainName); + + if (!domain) { + return this.jsonResponse({ success: false, error: 'Domain not found' }, 404); + } + + const certificates = this.oneboxRef.database.getCertificatesByDomain(domain.id!); + const requirements = this.oneboxRef.database.getCertRequirementsByDomain(domain.id!); + + // Get services using this domain + const allServices = this.oneboxRef.database.getAllServices(); + const services = allServices.filter((service) => { + if (!service.domain) return false; + const baseDomain = service.domain.split('.').slice(-2).join('.'); + return baseDomain === domain.domain; + }); + + // Build detailed view + const domainDetail = { + domain, + certificates: certificates.map((cert) => ({ + ...cert, + isExpired: cert.expiryDate <= Date.now(), + daysRemaining: Math.floor((cert.expiryDate - Date.now()) / (24 * 60 * 60 * 1000)), + })), + requirements: requirements.map((req) => { + const service = allServices.find((s) => s.id === req.serviceId); + return { + ...req, + serviceName: service?.name || 'Unknown', + }; + }), + services: services.map((s) => ({ + id: s.id, + name: s.name, + domain: s.domain, + status: s.status, + })), + }; + + return this.jsonResponse({ success: true, data: domainDetail }); + } catch (error) { + logger.error(`Failed to get domain detail for ${domainName}: ${error.message}`); + return this.jsonResponse({ + success: false, + error: error.message || 'Failed to get domain detail', + }, 500); + } + } + /** * Handle WebSocket upgrade */