Improve credential redaction handling (#23265)

* redact credentials in config endpoint with sentinel

* backend test

* frontend

* apply widget for credential fields

* i18n
This commit is contained in:
Josh Hawkins
2026-05-20 15:59:01 -06:00
committed by GitHub
parent 5ef8b9b924
commit 68e8afd35c
12 changed files with 126 additions and 17 deletions
+28
View File
@@ -11,6 +11,7 @@ import isEqual from "lodash/isEqual";
import mergeWith from "lodash/mergeWith";
import set from "lodash/set";
import { isJsonObject } from "@/lib/utils";
import { REDACTED_CREDENTIAL_SENTINEL } from "@/lib/const";
import { applySchemaDefaults } from "@/lib/config-schema";
import { normalizeConfigValue } from "@/hooks/use-config-override";
import {
@@ -29,6 +30,33 @@ import type {
import type { SectionConfig } from "../components/config-form/sections/BaseSection";
import { sectionConfigs } from "../components/config-form/sectionConfigs";
/**
* Recursively strip any key whose value is the redaction sentinel from a
* config_data payload. Use just before sending to /config/set so untouched
* credential placeholder fields don't clobber the saved YAML value. Mutates
* and returns the input.
*/
export function stripRedactedCredentials<T>(value: T): T {
if (Array.isArray(value)) {
for (const item of value) {
stripRedactedCredentials(item);
}
return value;
}
if (value && typeof value === "object") {
const obj = value as Record<string, unknown>;
for (const key of Object.keys(obj)) {
const v = obj[key];
if (v === REDACTED_CREDENTIAL_SENTINEL) {
delete obj[key];
} else if (v && typeof v === "object") {
stripRedactedCredentials(v);
}
}
}
return value;
}
// ---------------------------------------------------------------------------
// cameraUpdateTopicMap — maps config section paths to MQTT/WS update topics
// ---------------------------------------------------------------------------