fix: Preserve nested structure when redacting secrets

The secrets endpoint was flattening nested maps (e.g., cloudflare.apiToken)
to a single "********" string. The UI checks for nested keys to determine
if credentials are configured, so the structure must be preserved.

Now redactSecrets() recursively walks the map and only redacts leaf values.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-09 04:40:47 +00:00
parent 4cafe68064
commit d9c152f044

View File

@@ -331,9 +331,7 @@ func (api *API) GetGlobalSecrets(w http.ResponseWriter, r *http.Request) {
showRaw := r.URL.Query().Get("raw") == "true" showRaw := r.URL.Query().Get("raw") == "true"
if !showRaw { if !showRaw {
for key := range secretsMap { redactSecrets(secretsMap)
secretsMap[key] = "********"
}
} }
respondJSON(w, http.StatusOK, secretsMap) respondJSON(w, http.StatusOK, secretsMap)
@@ -464,6 +462,18 @@ func (api *API) NetworkResolveHandler(w http.ResponseWriter, r *http.Request) {
}) })
} }
// redactSecrets replaces leaf string values with "********" while preserving
// map structure so the UI can check which keys exist.
func redactSecrets(m map[string]any) {
for key, val := range m {
if nested, ok := val.(map[string]any); ok {
redactSecrets(nested)
} else {
m[key] = "********"
}
}
}
// getCloudflareToken reads the Cloudflare API token from global secrets // getCloudflareToken reads the Cloudflare API token from global secrets
func (api *API) getCloudflareToken() string { func (api *API) getCloudflareToken() string {
secretsPath := filepath.Join(api.dataDir, "secrets.yaml") secretsPath := filepath.Join(api.dataDir, "secrets.yaml")