From 9257071ca1aa518d7aaebcc01410fea148a87fce Mon Sep 17 00:00:00 2001 From: rcourtman Date: Fri, 7 Nov 2025 08:36:55 +0000 Subject: [PATCH] Add encryption status to notification health endpoint (P2) Backend: - Add IsEncryptionEnabled() method to ConfigPersistence - Include encryption status in /api/notifications/health response - Allows frontend to warn when credentials are stored in plaintext Frontend: - Update NotificationHealth type to include encryption.enabled field - Frontend can now display warnings when encryption is disabled This addresses the P2 requirement for encryption visibility, allowing operators to know when notification credentials are not encrypted at rest. --- frontend-modern/src/api/notifications.ts | 3 +++ internal/api/notifications.go | 3 +++ internal/config/persistence.go | 7 +++++++ 3 files changed, 13 insertions(+) diff --git a/frontend-modern/src/api/notifications.ts b/frontend-modern/src/api/notifications.ts index 456c905b2..3f5c32447 100644 --- a/frontend-modern/src/api/notifications.ts +++ b/frontend-modern/src/api/notifications.ts @@ -238,6 +238,9 @@ export class NotificationsAPI { total: number; enabled: number; }; + encryption: { + enabled: boolean; + }; healthy: boolean; }> { return apiFetchJSON(`${this.baseUrl}/health`); diff --git a/internal/api/notifications.go b/internal/api/notifications.go index 48cd0e3d1..9fb2ea383 100644 --- a/internal/api/notifications.go +++ b/internal/api/notifications.go @@ -640,6 +640,9 @@ func (h *NotificationHandlers) GetNotificationHealth(w http.ResponseWriter, r *h "total": len(webhooks), "enabled": countEnabledWebhooks(webhooks), }, + "encryption": map[string]interface{}{ + "enabled": h.monitor.GetConfigPersistence().IsEncryptionEnabled(), + }, "overall_healthy": queueStats["healthy"] == true, } diff --git a/internal/config/persistence.go b/internal/config/persistence.go index e228e975c..beef2ab7b 100644 --- a/internal/config/persistence.go +++ b/internal/config/persistence.go @@ -1371,6 +1371,13 @@ func (c *ConfigPersistence) updateEnvFile(envFile string, settings SystemSetting return os.Rename(tempFile, envFile) } +// IsEncryptionEnabled returns whether the config persistence has encryption enabled +func (c *ConfigPersistence) IsEncryptionEnabled() bool { + c.mu.RLock() + defer c.mu.RUnlock() + return c.crypto != nil +} + // cleanupOldBackups removes old backup files, keeping only the most recent N backups func (c *ConfigPersistence) cleanupOldBackups(pattern string) { // Use filepath.Glob to find all backup files matching the pattern