fix: yaml settings UI mask rsa_keys and jwt_secret

This commit is contained in:
Ruben Fiszel
2026-02-17 08:54:58 +00:00
parent 830254b69c
commit 99c3883364
2 changed files with 36 additions and 4 deletions
+22 -2
View File
@@ -335,10 +335,18 @@ impl GlobalSettings {
// including `extra` into a single map. skip_serializing_if ensures
// None fields are omitted.
let value = serde_json::to_value(self).expect("GlobalSettings serialization cannot fail");
match value {
let mut map: BTreeMap<String, serde_json::Value> = match value {
serde_json::Value::Object(map) => map.into_iter().collect(),
_ => unreachable!(),
};
// Strip runtime-only `databases` sub-field from custom_instance_pg_databases.
// It contains setup status/logs managed by the setup endpoint, not configuration.
if let Some(pg) = map.get_mut("custom_instance_pg_databases") {
if let Some(obj) = pg.as_object_mut() {
obj.remove("databases");
}
}
map
}
}
@@ -941,11 +949,23 @@ pub fn diff_global_settings(
);
continue;
}
let value = if key == "retention_period_secs" {
let mut value = if key == "retention_period_secs" {
clamp_retention_period(desired_value.clone())
} else {
desired_value.clone()
};
// Preserve the runtime-only `databases` sub-field inside
// `custom_instance_pg_databases` so that config sync never wipes
// setup status/logs that are managed by the setup endpoint.
if key == "custom_instance_pg_databases" {
if let Some(existing) = current.get(key) {
if let Some(databases) = existing.get("databases") {
if let Some(obj) = value.as_object_mut() {
obj.entry("databases").or_insert_with(|| databases.clone());
}
}
}
}
match current.get(key) {
Some(existing) if *existing == value => {
unchanged_count += 1;
@@ -556,7 +556,7 @@
.filter((s) => s.fieldType === 'password' || s.fieldType === 'license_key')
.map((s) => s.key),
'ducklake_user_pg_pwd',
'rsa_keys'
'jwt_secret'
])
// Settings that should never appear in YAML export/import
@@ -568,7 +568,8 @@
smtp_settings: ['smtp_password'],
secret_backend: ['token'],
object_store_cache_config: ['secret_key', 'serviceAccountKey'],
custom_instance_pg_databases: ['user_pwd']
custom_instance_pg_databases: ['user_pwd'],
rsa_keys: ['private_key']
}
/** Returns SENSITIVE_UNCHANGED if the value is non-empty and matches the initial */
@@ -636,6 +637,11 @@
if (opts.normalize && normalizeValue(merged[key], key) === undefined) continue
obj[key] = merged[key]
}
// Strip runtime-only `databases` sub-field from custom_instance_pg_databases
if (obj['custom_instance_pg_databases']?.databases) {
obj['custom_instance_pg_databases'] = { ...obj['custom_instance_pg_databases'] }
delete obj['custom_instance_pg_databases'].databases
}
return YAML.stringify(opts.mask ? maskSensitive(obj) : obj)
}
@@ -706,6 +712,12 @@
}
}
// Preserve runtime-only `databases` sub-field in custom_instance_pg_databases
const existingDatabases = initialValues?.['custom_instance_pg_databases']?.databases
if (existingDatabases && parsed['custom_instance_pg_databases']) {
parsed['custom_instance_pg_databases'].databases = existingDatabases
}
$values = parsed
applyFormDefaults($values)