diff --git a/src/OutlookAddin.Core/Security/DpapiCredentialStore.cs b/src/OutlookAddin.Core/Security/DpapiCredentialStore.cs index e837622..5d8df40 100644 --- a/src/OutlookAddin.Core/Security/DpapiCredentialStore.cs +++ b/src/OutlookAddin.Core/Security/DpapiCredentialStore.cs @@ -36,14 +36,13 @@ namespace MarcusLaw.OutlookAddin.Core.Security public string FilePath => _filePath; - public void Save(string username, string apiKey) + public void Save(string? username, string apiKey) { - if (string.IsNullOrWhiteSpace(username)) throw new ArgumentException("username required", nameof(username)); if (string.IsNullOrWhiteSpace(apiKey)) throw new ArgumentException("apiKey required", nameof(apiKey)); var payload = JsonSerializer.SerializeToUtf8Bytes(new StoredCredentials { - Username = username, + Username = username ?? string.Empty, ApiKey = apiKey }); diff --git a/src/OutlookAddin.Tests/Security/DpapiCredentialStoreTests.cs b/src/OutlookAddin.Tests/Security/DpapiCredentialStoreTests.cs index 308e8ef..9a40d48 100644 --- a/src/OutlookAddin.Tests/Security/DpapiCredentialStoreTests.cs +++ b/src/OutlookAddin.Tests/Security/DpapiCredentialStoreTests.cs @@ -95,11 +95,23 @@ namespace MarcusLaw.OutlookAddin.Tests.Security } [Fact] - public void Save_RejectsBlankInput() + public void Save_RejectsBlankApiKey() { var store = NewStore(); - Assert.Throws(() => store.Save("", "k")); + // Empty username is OK (some EspoCRM API-User installs need only the key); + // empty apiKey is not. Assert.Throws(() => store.Save("u", "")); } + + [Fact] + public void Save_AcceptsEmptyUsername() + { + var store = NewStore(); + store.Save(null, "key-only"); + var loaded = store.Load(); + loaded.Should().NotBeNull(); + loaded!.Username.Should().BeEmpty(); + loaded.ApiKey.Should().Be("key-only"); + } } } diff --git a/src/OutlookAddin.UI/ViewModels/SettingsViewModel.cs b/src/OutlookAddin.UI/ViewModels/SettingsViewModel.cs index ada7968..16e7bb9 100644 --- a/src/OutlookAddin.UI/ViewModels/SettingsViewModel.cs +++ b/src/OutlookAddin.UI/ViewModels/SettingsViewModel.cs @@ -240,7 +240,7 @@ namespace MarcusLaw.OutlookAddin.UI.ViewModels _settingsManager.Save(_settings); - _credentialStore.Save(string.IsNullOrWhiteSpace(Username) ? "(api-key)" : Username.Trim(), apiKey); + _credentialStore.Save(string.IsNullOrWhiteSpace(Username) ? null : Username.Trim(), apiKey); _logger.Information("Settings saved (user={User}, url={Url}, watched={WatchedCount})", Username, _settings.EspoCrmUrl, _settings.WatchedFolders.Count);