dont show depreciated, do show premium.key

This commit is contained in:
Anthony Stirling 2025-07-28 13:56:22 +01:00
parent 13a7dbbf9e
commit 76764e3179
2 changed files with 25 additions and 9 deletions

View File

@ -61,7 +61,10 @@ public class ApplicationProperties {
private Mail mail = new Mail(); private Mail mail = new Mail();
private Premium premium = new Premium(); private Premium premium = new Premium();
@JsonIgnore // Deprecated - completely hidden from JSON serialization
private EnterpriseEdition enterpriseEdition = new EnterpriseEdition(); private EnterpriseEdition enterpriseEdition = new EnterpriseEdition();
private AutoPipeline autoPipeline = new AutoPipeline(); private AutoPipeline autoPipeline = new AutoPipeline();
private ProcessExecutor processExecutor = new ProcessExecutor(); private ProcessExecutor processExecutor = new ProcessExecutor();

View File

@ -61,10 +61,11 @@ public class AdminSettingsController {
"clientsecret", "apisecret", "secret", "clientsecret", "apisecret", "secret",
// API tokens // API tokens
"apikey", "accesstoken", "refreshtoken", "token", "apikey", "accesstoken", "refreshtoken", "token",
// Specific secret keys (not all keys) // Specific secret keys (not all keys, and excluding premium.key)
"key", // automaticallyGenerated.key "key", // automaticallyGenerated.key
"enterprisekey", "licensekey" "enterprisekey", "licensekey"
)); ));
@GetMapping @GetMapping
@Operation( @Operation(
@ -519,21 +520,27 @@ public class AdminSettingsController {
} }
/** /**
* Recursively mask sensitive fields in a settings map. * Recursively mask sensitive fields in settings map.
* Sensitive fields are replaced with a status indicator showing if they're configured. * Sensitive fields are replaced with a status indicator showing if they're configured.
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Map<String, Object> maskSensitiveFields(Map<String, Object> settings) { private Map<String, Object> maskSensitiveFields(Map<String, Object> settings) {
return maskSensitiveFieldsWithPath(settings, "");
}
@SuppressWarnings("unchecked")
private Map<String, Object> maskSensitiveFieldsWithPath(Map<String, Object> settings, String path) {
Map<String, Object> masked = new HashMap<>(); Map<String, Object> masked = new HashMap<>();
for (Map.Entry<String, Object> entry : settings.entrySet()) { for (Map.Entry<String, Object> entry : settings.entrySet()) {
String key = entry.getKey(); String key = entry.getKey();
Object value = entry.getValue(); Object value = entry.getValue();
String currentPath = path.isEmpty() ? key : path + "." + key;
if (value instanceof Map) { if (value instanceof Map) {
// Recursively mask nested objects // Recursively mask nested objects
masked.put(key, maskSensitiveFields((Map<String, Object>) value)); masked.put(key, maskSensitiveFieldsWithPath((Map<String, Object>) value, currentPath));
} else if (isSensitiveField(key)) { } else if (isSensitiveFieldWithPath(key, currentPath)) {
// Mask sensitive fields with status indicator // Mask sensitive fields with status indicator
masked.put(key, createMaskedValue(value)); masked.put(key, createMaskedValue(value));
} else { } else {
@ -546,27 +553,33 @@ public class AdminSettingsController {
} }
/** /**
* Check if a field name indicates sensitive data (actual secrets, not identifiers) * Check if a field name indicates sensitive data with full path context
*/ */
private boolean isSensitiveField(String fieldName) { private boolean isSensitiveFieldWithPath(String fieldName, String fullPath) {
String lowerField = fieldName.toLowerCase(); String lowerField = fieldName.toLowerCase();
String lowerPath = fullPath.toLowerCase();
// Don't mask premium.key specifically
if (lowerField.equals("key") && lowerPath.equals("premium.key")) {
return false;
}
// Direct match with sensitive field names // Direct match with sensitive field names
if (SENSITIVE_FIELD_NAMES.contains(lowerField)) { if (SENSITIVE_FIELD_NAMES.contains(lowerField)) {
return true; return true;
} }
// Check for fields containing 'password' or 'secret' (but not 'key' as that's too broad) // Check for fields containing 'password' or 'secret'
return lowerField.contains("password") || lowerField.contains("secret"); return lowerField.contains("password") || lowerField.contains("secret");
} }
/** /**
* Create a masked representation showing if the field is configured * Create a masked representation for sensitive fields
*/ */
private Object createMaskedValue(Object originalValue) { private Object createMaskedValue(Object originalValue) {
if (originalValue == null || if (originalValue == null ||
(originalValue instanceof String && ((String) originalValue).trim().isEmpty())) { (originalValue instanceof String && ((String) originalValue).trim().isEmpty())) {
return "[NOT_CONFIGURED]"; return originalValue; // Keep empty/null values as-is
} else { } else {
return "[CONFIGURED - " + originalValue.getClass().getSimpleName().toUpperCase() + "]"; return "[CONFIGURED - " + originalValue.getClass().getSimpleName().toUpperCase() + "]";
} }