This commit is contained in:
2025-11-18 19:37:06 +00:00
parent 11142b9cb0
commit 76bfcf6a73
3 changed files with 141 additions and 1 deletions

View File

@@ -519,6 +519,146 @@ export class OneboxHttpServer {
}
}
private async handleGetDomainsRequest(): Promise<Response> {
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<Response> {
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<Response> {
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
*/