feat: integrate toast notifications in settings and layout components

- Added ToastService for managing toast notifications.
- Replaced alert in settings component with toast notifications for success and error messages.
- Included ToastComponent in layout for displaying notifications.
- Created loading spinner component for better user experience.
- Implemented domain detail component with detailed views for certificates, requirements, and services.
- Added functionality to manage and display SSL certificates and their statuses.
- Introduced a registry manager class for handling Docker registry operations.
This commit is contained in:
2025-11-24 01:31:15 +00:00
parent b6ac4f209a
commit c9beae93c8
23 changed files with 2475 additions and 130 deletions

View File

@@ -22,6 +22,8 @@ export class OneboxDaemon {
private monitoringInterval: number | null = null;
private metricsInterval = 60000; // 1 minute
private pidFilePath: string = PID_FILE_PATH;
private lastDomainSync = 0; // Timestamp of last Cloudflare domain sync
private domainSyncInterval = 6 * 60 * 60 * 1000; // 6 hours
constructor(oneboxRef: Onebox) {
this.oneboxRef = oneboxRef;
@@ -211,6 +213,18 @@ export class OneboxDaemon {
// Check SSL certificate expiration
await this.checkSSLExpiration();
// Process pending certificate requirements
await this.processCertRequirements();
// Check for certificate renewal (every tick)
await this.checkCertificateRenewal();
// Clean up old certificates (every tick, but cleanup has built-in 90-day threshold)
await this.cleanupOldCertificates();
// Sync Cloudflare domains (less frequently - every 6 hours)
await this.syncCloudflareDomainsIfNeeded();
// Check service health (TODO: implement health checks)
logger.debug('Monitoring tick complete');
@@ -267,6 +281,62 @@ export class OneboxDaemon {
}
}
/**
* Process pending certificate requirements
*/
private async processCertRequirements(): Promise<void> {
try {
await this.oneboxRef.certRequirementManager.processPendingRequirements();
} catch (error) {
logger.error(`Failed to process cert requirements: ${error.message}`);
}
}
/**
* Check certificates for renewal (30-day threshold)
*/
private async checkCertificateRenewal(): Promise<void> {
try {
await this.oneboxRef.certRequirementManager.checkCertificateRenewal();
} catch (error) {
logger.error(`Failed to check certificate renewal: ${error.message}`);
}
}
/**
* Clean up old invalid certificates (90+ days old)
*/
private async cleanupOldCertificates(): Promise<void> {
try {
await this.oneboxRef.certRequirementManager.cleanupOldCertificates();
} catch (error) {
logger.error(`Failed to cleanup old certificates: ${error.message}`);
}
}
/**
* Sync Cloudflare domains if needed (every 6 hours)
*/
private async syncCloudflareDomainsIfNeeded(): Promise<void> {
try {
const now = Date.now();
// Check if it's time to sync (every 6 hours)
if (now - this.lastDomainSync < this.domainSyncInterval) {
return;
}
if (!this.oneboxRef.cloudflareDomainSync.isConfigured()) {
return;
}
await this.oneboxRef.cloudflareDomainSync.syncZones();
this.lastDomainSync = now;
} catch (error) {
logger.error(`Failed to sync Cloudflare domains: ${error.message}`);
}
}
/**
* Keep process alive
*/