From 02da21f943dd15074b379bb69537a292236ee2df Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Thu, 7 Sep 2023 09:14:55 +0200 Subject: [PATCH 1/7] Add 'POST /alias' --- Directory.Build.props | 2 +- src/Sdk/Helpers/PasswordlessSerializerContext.cs | 1 + src/Sdk/IPasswordlessClient.cs | 8 ++++++++ src/Sdk/Models/AddAliasRequest.cs | 12 ++++++++++++ src/Sdk/PasswordlessClient.cs | 11 +++++++++-- 5 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 src/Sdk/Models/AddAliasRequest.cs diff --git a/Directory.Build.props b/Directory.Build.props index d755160..6b9ec43 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,7 +12,7 @@ 1 0 - 2 + 3 $(PasswordlessMajorVersion).$(PasswordlessMinorVersion) $(PasswordlessMajorMinorVersion).$(PasswordlessPatchVersion) diff --git a/src/Sdk/Helpers/PasswordlessSerializerContext.cs b/src/Sdk/Helpers/PasswordlessSerializerContext.cs index 451122c..f75a51f 100644 --- a/src/Sdk/Helpers/PasswordlessSerializerContext.cs +++ b/src/Sdk/Helpers/PasswordlessSerializerContext.cs @@ -7,6 +7,7 @@ namespace Passwordless.Net.Helpers; [JsonSourceGenerationOptions( PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] +[JsonSerializable(typeof(AddAliasRequest))] [JsonSerializable(typeof(RegisterTokenResponse))] [JsonSerializable(typeof(RegisterOptions))] [JsonSerializable(typeof(VerifyTokenRequest))] // TODO: Use this with JsonContent.Create diff --git a/src/Sdk/IPasswordlessClient.cs b/src/Sdk/IPasswordlessClient.cs index 1683f1e..ef1d6e8 100644 --- a/src/Sdk/IPasswordlessClient.cs +++ b/src/Sdk/IPasswordlessClient.cs @@ -7,6 +7,14 @@ namespace Passwordless.Net; /// public interface IPasswordlessClient { + /// + /// Adds one or more aliases to an existing user. + /// + /// + /// + /// + Task AddAliasAsync(AddAliasRequest request, CancellationToken cancellationToken = default); + /// /// Creates a which will be used by your frontend to negotiate /// the creation of a WebAuth credential. diff --git a/src/Sdk/Models/AddAliasRequest.cs b/src/Sdk/Models/AddAliasRequest.cs new file mode 100644 index 0000000..41bd0ee --- /dev/null +++ b/src/Sdk/Models/AddAliasRequest.cs @@ -0,0 +1,12 @@ +namespace Passwordless.Net.Models; + +public class AddAliasRequest +{ + public string UserId { get; set; } + public HashSet Aliases { get; set; } + + /// + /// If you want your aliases to be available in plain text, set the false. + /// + public bool Hashing { get; set; } = true; +} \ No newline at end of file diff --git a/src/Sdk/PasswordlessClient.cs b/src/Sdk/PasswordlessClient.cs index db9048f..df7ea32 100644 --- a/src/Sdk/PasswordlessClient.cs +++ b/src/Sdk/PasswordlessClient.cs @@ -1,8 +1,6 @@ using System.Diagnostics; -using System.Net.Http; using System.Net.Http.Json; using System.Text; -using Passwordless.Net.Helpers; using Passwordless.Net.Models; using JsonContext = Passwordless.Net.Helpers.PasswordlessSerializerContext; @@ -41,6 +39,15 @@ public PasswordlessClient(HttpClient client) _client = client; } + public async Task AddAliasAsync(AddAliasRequest request, CancellationToken cancellationToken) + { + var res = await _client.PostAsJsonAsync("alias", + request, + JsonContext.Default.AddAliasRequest, + cancellationToken); + res.EnsureSuccessStatusCode(); + } + /// public async Task CreateRegisterTokenAsync(RegisterOptions registerOptions, CancellationToken cancellationToken = default) { From 855b2d41ee93ce15202a7f167661d0394b9aa134 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Fri, 8 Sep 2023 10:01:44 +0200 Subject: [PATCH 2/7] Validation for AddAliasRequest --- src/Sdk/Models/AddAliasRequest.cs | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/Sdk/Models/AddAliasRequest.cs b/src/Sdk/Models/AddAliasRequest.cs index 41bd0ee..e37f2ec 100644 --- a/src/Sdk/Models/AddAliasRequest.cs +++ b/src/Sdk/Models/AddAliasRequest.cs @@ -2,8 +2,32 @@ namespace Passwordless.Net.Models; public class AddAliasRequest { - public string UserId { get; set; } - public HashSet Aliases { get; set; } + public AddAliasRequest(string userId, string alias, bool hashing = true) + : this(userId, hashing) + { + if (string.IsNullOrWhiteSpace(alias)) throw new ArgumentException($"'{nameof(alias)}' cannot be null, empty or whitespace."); + Aliases = new HashSet + { + alias ?? throw new ArgumentNullException(nameof(alias)) + }; + } + + public AddAliasRequest(string userId, HashSet aliases, bool hashing = true) + : this(userId, hashing) + { + if (aliases == null || !aliases.Any()) throw new ArgumentException($"'{nameof(aliases)}' cannot be null or empty."); + if (aliases.Any(string.IsNullOrWhiteSpace)) throw new ArgumentException("One of the aliases is null, empty or whitespace"); + Aliases = aliases; + } + + private AddAliasRequest(string userId, bool hashing = true) + { + UserId = userId ?? throw new ArgumentNullException(nameof(userId)); + Hashing = hashing; + } + + public string UserId { get; } + public HashSet Aliases { get; init; } /// /// If you want your aliases to be available in plain text, set the false. From fac6209887801c6a6091c39c3f3eeeec6b716e8b Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Fri, 8 Sep 2023 15:17:30 +0200 Subject: [PATCH 3/7] fix build --- src/Sdk/Models/AddAliasRequest.cs | 6 +++--- src/Sdk/PasswordlessClient.cs | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Sdk/Models/AddAliasRequest.cs b/src/Sdk/Models/AddAliasRequest.cs index e37f2ec..5230f6e 100644 --- a/src/Sdk/Models/AddAliasRequest.cs +++ b/src/Sdk/Models/AddAliasRequest.cs @@ -25,12 +25,12 @@ private AddAliasRequest(string userId, bool hashing = true) UserId = userId ?? throw new ArgumentNullException(nameof(userId)); Hashing = hashing; } - + public string UserId { get; } - public HashSet Aliases { get; init; } + public HashSet Aliases { get; } /// /// If you want your aliases to be available in plain text, set the false. /// - public bool Hashing { get; set; } = true; + public bool Hashing { get; } = true; } \ No newline at end of file diff --git a/src/Sdk/PasswordlessClient.cs b/src/Sdk/PasswordlessClient.cs index df7ea32..e9b354e 100644 --- a/src/Sdk/PasswordlessClient.cs +++ b/src/Sdk/PasswordlessClient.cs @@ -39,6 +39,7 @@ public PasswordlessClient(HttpClient client) _client = client; } + /// public async Task AddAliasAsync(AddAliasRequest request, CancellationToken cancellationToken) { var res = await _client.PostAsJsonAsync("alias", From 96ebc88aa26c08478a55637d37aaeec141602257 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Fri, 8 Sep 2023 22:02:49 +0200 Subject: [PATCH 4/7] Fix: an empty alias array is needed to clear aliases from the user --- Directory.Build.props | 2 +- src/Sdk/Models/AddAliasRequest.cs | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Directory.Build.props b/Directory.Build.props index 6b9ec43..2b28936 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -12,7 +12,7 @@ 1 0 - 3 + 4 $(PasswordlessMajorVersion).$(PasswordlessMinorVersion) $(PasswordlessMajorMinorVersion).$(PasswordlessPatchVersion) diff --git a/src/Sdk/Models/AddAliasRequest.cs b/src/Sdk/Models/AddAliasRequest.cs index 5230f6e..22b626b 100644 --- a/src/Sdk/Models/AddAliasRequest.cs +++ b/src/Sdk/Models/AddAliasRequest.cs @@ -5,19 +5,19 @@ public class AddAliasRequest public AddAliasRequest(string userId, string alias, bool hashing = true) : this(userId, hashing) { - if (string.IsNullOrWhiteSpace(alias)) throw new ArgumentException($"'{nameof(alias)}' cannot be null, empty or whitespace."); - Aliases = new HashSet + Aliases = new(); + if (!string.IsNullOrWhiteSpace(alias)) { - alias ?? throw new ArgumentNullException(nameof(alias)) - }; + Aliases = new() { alias }; + } } public AddAliasRequest(string userId, HashSet aliases, bool hashing = true) : this(userId, hashing) { - if (aliases == null || !aliases.Any()) throw new ArgumentException($"'{nameof(aliases)}' cannot be null or empty."); - if (aliases.Any(string.IsNullOrWhiteSpace)) throw new ArgumentException("One of the aliases is null, empty or whitespace"); - Aliases = aliases; + if (aliases == null) return; + + Aliases = new HashSet(aliases.Where(x => !string.IsNullOrWhiteSpace(x))); } private AddAliasRequest(string userId, bool hashing = true) @@ -32,5 +32,5 @@ private AddAliasRequest(string userId, bool hashing = true) /// /// If you want your aliases to be available in plain text, set the false. /// - public bool Hashing { get; } = true; + public bool Hashing { get; } } \ No newline at end of file From 76d82f5c0306cf5af4f2155d704a4fd90d30f59d Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Thu, 21 Sep 2023 14:21:33 +0200 Subject: [PATCH 5/7] fix build --- src/Passwordless/Models/AddAliasRequest.cs | 23 ++++++++++------------ 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/Passwordless/Models/AddAliasRequest.cs b/src/Passwordless/Models/AddAliasRequest.cs index 2f65204..0f215a7 100644 --- a/src/Passwordless/Models/AddAliasRequest.cs +++ b/src/Passwordless/Models/AddAliasRequest.cs @@ -2,31 +2,28 @@ namespace Passwordless.Models; public class AddAliasRequest { - public AddAliasRequest(string userId, string alias, bool hashing = true) - : this(userId, hashing) + public AddAliasRequest(string userId, bool hashing = true) + : this(userId, new HashSet(), hashing) { - Aliases = new(); - if (!string.IsNullOrWhiteSpace(alias)) - { - Aliases = new() { alias }; - } } - public AddAliasRequest(string userId, HashSet aliases, bool hashing = true) - : this(userId, hashing) + public AddAliasRequest(string userId, string alias, bool hashing = true) + : this(userId, new HashSet { alias }, hashing) { - if (aliases == null) return; - - Aliases = new HashSet(aliases.Where(x => !string.IsNullOrWhiteSpace(x))); } - private AddAliasRequest(string userId, bool hashing = true) + public AddAliasRequest(string userId, HashSet aliases, bool hashing = true) { UserId = userId ?? throw new ArgumentNullException(nameof(userId)); Hashing = hashing; + + Aliases = aliases == null + ? new HashSet() + : new HashSet(aliases.Where(x => !string.IsNullOrWhiteSpace(x))); } public string UserId { get; } + public HashSet Aliases { get; } /// From fbb523aa84382d10f10581190b0b3a8522008a42 Mon Sep 17 00:00:00 2001 From: Jonas Hendrickx Date: Mon, 25 Sep 2023 12:13:57 +0200 Subject: [PATCH 6/7] Rename AddAliasRequest to SetAliasRequest --- .../Helpers/PasswordlessSerializerContext.cs | 2 +- src/Passwordless/IPasswordlessClient.cs | 4 +- src/Passwordless/Models/AddAliasRequest.cs | 33 ----------- src/Passwordless/Models/SetAliasRequest.cs | 55 +++++++++++++++++++ src/Passwordless/PasswordlessClient.cs | 4 +- 5 files changed, 60 insertions(+), 38 deletions(-) delete mode 100644 src/Passwordless/Models/AddAliasRequest.cs create mode 100644 src/Passwordless/Models/SetAliasRequest.cs diff --git a/src/Passwordless/Helpers/PasswordlessSerializerContext.cs b/src/Passwordless/Helpers/PasswordlessSerializerContext.cs index 61d0526..95353c1 100644 --- a/src/Passwordless/Helpers/PasswordlessSerializerContext.cs +++ b/src/Passwordless/Helpers/PasswordlessSerializerContext.cs @@ -7,7 +7,7 @@ namespace Passwordless.Helpers; [JsonSourceGenerationOptions( PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase, DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull)] -[JsonSerializable(typeof(AddAliasRequest))] +[JsonSerializable(typeof(SetAliasRequest))] [JsonSerializable(typeof(RegisterTokenResponse))] [JsonSerializable(typeof(RegisterOptions))] [JsonSerializable(typeof(VerifyTokenRequest))] // TODO: Use this with JsonContent.Create diff --git a/src/Passwordless/IPasswordlessClient.cs b/src/Passwordless/IPasswordlessClient.cs index 1f63992..c7d2cb2 100644 --- a/src/Passwordless/IPasswordlessClient.cs +++ b/src/Passwordless/IPasswordlessClient.cs @@ -8,12 +8,12 @@ namespace Passwordless; public interface IPasswordlessClient { /// - /// Adds one or more aliases to an existing user. + /// Sets one or more aliases to an existing user and removes existing aliases that are not included in the request. /// /// /// /// - Task AddAliasAsync(AddAliasRequest request, CancellationToken cancellationToken = default); + Task SetAliasAsync(SetAliasRequest request, CancellationToken cancellationToken = default); /// /// Creates a which will be used by your frontend to negotiate diff --git a/src/Passwordless/Models/AddAliasRequest.cs b/src/Passwordless/Models/AddAliasRequest.cs deleted file mode 100644 index 0f215a7..0000000 --- a/src/Passwordless/Models/AddAliasRequest.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace Passwordless.Models; - -public class AddAliasRequest -{ - public AddAliasRequest(string userId, bool hashing = true) - : this(userId, new HashSet(), hashing) - { - } - - public AddAliasRequest(string userId, string alias, bool hashing = true) - : this(userId, new HashSet { alias }, hashing) - { - } - - public AddAliasRequest(string userId, HashSet aliases, bool hashing = true) - { - UserId = userId ?? throw new ArgumentNullException(nameof(userId)); - Hashing = hashing; - - Aliases = aliases == null - ? new HashSet() - : new HashSet(aliases.Where(x => !string.IsNullOrWhiteSpace(x))); - } - - public string UserId { get; } - - public HashSet Aliases { get; } - - /// - /// If you want your aliases to be available in plain text, set the false. - /// - public bool Hashing { get; } -} \ No newline at end of file diff --git a/src/Passwordless/Models/SetAliasRequest.cs b/src/Passwordless/Models/SetAliasRequest.cs new file mode 100644 index 0000000..b636897 --- /dev/null +++ b/src/Passwordless/Models/SetAliasRequest.cs @@ -0,0 +1,55 @@ +namespace Passwordless.Models; + +public class SetAliasRequest +{ + public SetAliasRequest(string userId) + : this(userId, new HashSet(), false) + { + } + + /// + /// Sets a single alias for a given user, and removes any other aliases that may exist. + /// + /// + /// + /// + public SetAliasRequest(string userId, string alias, bool hashing = true) + : this(userId, new HashSet { alias }, hashing) + { + } + + /// + /// Sets one or more aliases for a given user, and removes any other aliases that may exist. + /// + /// + /// + /// + /// + public SetAliasRequest(string userId, HashSet aliases, bool hashing = true) + { + UserId = userId ?? throw new ArgumentNullException(nameof(userId)); + Hashing = hashing; + + Aliases = aliases == null + ? new HashSet() + : new HashSet(aliases.Where(x => !string.IsNullOrWhiteSpace(x))); + } + + public string UserId { get; } + + public IReadOnlyCollection Aliases { get; } + + /// + /// If you want your aliases to be available in plain text, set the false. + /// + public bool Hashing { get; } + + /// + /// Removes all aliases from a user. + /// + /// + public static SetAliasRequest Empty(string userId) + { + return new SetAliasRequest(userId); + } +} \ No newline at end of file diff --git a/src/Passwordless/PasswordlessClient.cs b/src/Passwordless/PasswordlessClient.cs index d5c9b01..4d8e036 100644 --- a/src/Passwordless/PasswordlessClient.cs +++ b/src/Passwordless/PasswordlessClient.cs @@ -41,11 +41,11 @@ public PasswordlessClient(HttpClient client) } /// - public async Task AddAliasAsync(AddAliasRequest request, CancellationToken cancellationToken) + public async Task SetAliasAsync(SetAliasRequest request, CancellationToken cancellationToken) { var res = await _client.PostAsJsonAsync("alias", request, - PasswordlessSerializerContext.Default.AddAliasRequest, + PasswordlessSerializerContext.Default.SetAliasRequest, cancellationToken); res.EnsureSuccessStatusCode(); } From fe03869027d69316a6220725499cc6b0ad62d83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20=C3=85berg?= Date: Mon, 25 Sep 2023 14:41:18 +0200 Subject: [PATCH 7/7] Replace empty ctor because of static method --- src/Passwordless/Models/SetAliasRequest.cs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Passwordless/Models/SetAliasRequest.cs b/src/Passwordless/Models/SetAliasRequest.cs index b636897..7d68e0f 100644 --- a/src/Passwordless/Models/SetAliasRequest.cs +++ b/src/Passwordless/Models/SetAliasRequest.cs @@ -2,10 +2,6 @@ namespace Passwordless.Models; public class SetAliasRequest { - public SetAliasRequest(string userId) - : this(userId, new HashSet(), false) - { - } /// /// Sets a single alias for a given user, and removes any other aliases that may exist. @@ -50,6 +46,6 @@ public SetAliasRequest(string userId, HashSet aliases, bool hashing = tr /// public static SetAliasRequest Empty(string userId) { - return new SetAliasRequest(userId); + return new SetAliasRequest(userId, new HashSet(), true); } } \ No newline at end of file