feat(church-profile): masked-read + leave-unchanged write for AI keys
This commit is contained in:
@@ -19,6 +19,11 @@ public class ChurchProfileService : IChurchProfileService
|
||||
Website = p.Website, Address = p.Address, City = p.City, State = p.State,
|
||||
ZipCode = p.ZipCode, BankName = p.BankName, BankAccountNumber = p.BankAccountNumber,
|
||||
BankRoutingNumber = p.BankRoutingNumber, NextCheckNumber = p.NextCheckNumber,
|
||||
AiProvider = p.AiProvider,
|
||||
ClaudeModel = p.ClaudeModel,
|
||||
ClaudeApiKeyMasked = Mask(p.ClaudeApiKey),
|
||||
GeminiModel = p.GeminiModel,
|
||||
GeminiApiKeyMasked = Mask(p.GeminiApiKey),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -29,6 +34,12 @@ public class ChurchProfileService : IChurchProfileService
|
||||
p.Website = r.Website; p.Address = r.Address; p.City = r.City; p.State = r.State;
|
||||
p.ZipCode = r.ZipCode; p.BankName = r.BankName; p.BankAccountNumber = r.BankAccountNumber;
|
||||
p.BankRoutingNumber = r.BankRoutingNumber; p.NextCheckNumber = r.NextCheckNumber;
|
||||
p.AiProvider = string.IsNullOrWhiteSpace(r.AiProvider) ? "Claude" : r.AiProvider;
|
||||
p.ClaudeModel = r.ClaudeModel;
|
||||
p.GeminiModel = r.GeminiModel;
|
||||
// Leave-unchanged semantics: only overwrite a stored key when a new value is supplied.
|
||||
if (!string.IsNullOrWhiteSpace(r.ClaudeApiKey)) p.ClaudeApiKey = r.ClaudeApiKey;
|
||||
if (!string.IsNullOrWhiteSpace(r.GeminiApiKey)) p.GeminiApiKey = r.GeminiApiKey;
|
||||
await _db.SaveChangesAsync();
|
||||
}
|
||||
|
||||
@@ -43,4 +54,12 @@ public class ChurchProfileService : IChurchProfileService
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>Mask a stored secret for display: 6 bullets + last 4 chars; fully masked when ≤4 chars.</summary>
|
||||
private static string Mask(string? key)
|
||||
{
|
||||
if (string.IsNullOrEmpty(key)) return "";
|
||||
if (key.Length <= 4) return new string('•', key.Length);
|
||||
return new string('•', 6) + key[^4..];
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user