diff --git a/src/UnifiSharp/UnifiClientOptions.cs b/src/UnifiSharp/UnifiClientOptions.cs index df66809..0fe3fe3 100644 --- a/src/UnifiSharp/UnifiClientOptions.cs +++ b/src/UnifiSharp/UnifiClientOptions.cs @@ -46,4 +46,12 @@ public sealed record UnifiClientOptions return new UnifiClientOptions { BaseUrl = new Uri(baseUrl), ApiKey = apiKey, VerifyTls = verifyTls }; } + + /// + /// Redacted representation. The synthesized record ToString() would + /// otherwise print , leaking it into any log or + /// interpolated string. The key is never emitted. + /// + public override string ToString() => + $"UnifiClientOptions {{ BaseUrl = {BaseUrl}, ApiKey = ***, VerifyTls = {VerifyTls} }}"; } diff --git a/tests/UnifiSharp.Tests/UnifiClientOptionsTests.cs b/tests/UnifiSharp.Tests/UnifiClientOptionsTests.cs index 11a9b4a..642064e 100644 --- a/tests/UnifiSharp.Tests/UnifiClientOptionsTests.cs +++ b/tests/UnifiSharp.Tests/UnifiClientOptionsTests.cs @@ -30,4 +30,19 @@ public void Create_builds_a_client() Assert.NotNull(client); } + + [Fact] + public void ToString_does_not_leak_the_api_key() + { + var options = new UnifiClientOptions + { + BaseUrl = new Uri("https://192.168.1.1/proxy/network/integration/v1"), + ApiKey = "super-secret-api-key", + }; + + var text = options.ToString(); + + Assert.DoesNotContain("super-secret-api-key", text); + Assert.Contains("***", text); + } }