Fix dark mode toggle wiping API tokens (related to #685)

Root cause: SaveSystemSettings calls updateEnvFile which rewrites .env on
any setting change, triggering the config watcher. The watcher sees API_TOKEN
in .env and replaces all UI-created tokens with "Environment token" records,
wiping out host-agent scoped tokens.

Fix: updateEnvFile now compares the new content with existing content and
skips the write if nothing changed. Since dark mode (and other UI settings)
are stored in system.json, not .env, toggling theme no longer triggers
unnecessary .env rewrites.

This prevents the config watcher from being triggered unnecessarily and
preserves UI-created API tokens when changing cosmetic settings.

Future improvement: Deprecate API_TOKEN/API_TOKENS from .env entirely and
make api_tokens.json the single source of truth (requires migration logic).
This commit is contained in:
rcourtman 2025-11-11 00:11:41 +00:00
parent bb6ea3b23c
commit 5d99fc2f2d

View file

@ -1342,6 +1342,12 @@ func (c *ConfigPersistence) updateEnvFile(envFile string, settings SystemSetting
return nil
}
// Read the existing .env file content
existingContent, err := os.ReadFile(envFile)
if err != nil {
return err
}
// Read the existing .env file
file, err := os.Open(envFile)
if err != nil {
@ -1377,12 +1383,20 @@ func (c *ConfigPersistence) updateEnvFile(envFile string, settings SystemSetting
// Note: POLLING_INTERVAL is deprecated and no longer written
// Write the updated content back atomically
// Build the new content
content := strings.Join(lines, "\n")
if len(lines) > 0 && !strings.HasSuffix(content, "\n") {
content += "\n"
}
// Only write if content actually changed
// This prevents unnecessary .env rewrites that trigger the config watcher,
// which can cause API tokens to be overwritten (related to #685)
if string(existingContent) == content {
log.Debug().Str("file", envFile).Msg("Skipping .env update - content unchanged")
return nil
}
// Write to temp file first
tempFile := envFile + ".tmp"
if err := os.WriteFile(tempFile, []byte(content), 0644); err != nil {