Skip to content

Commit 1950bc1

Browse files
committed
Enhance Credential Plugin Domain
1 parent 33f23a9 commit 1950bc1

62 files changed

Lines changed: 1031 additions & 547 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
@inject IHubCredentialResolver HubCredentialResolver
1818
@inject IAuthStore AuthStore
1919
@inject IBrowserStorage BrowserStorage
20-
@inject IUAuthFlowService<UserKey> Flow
20+
@inject IUAuthFlowService Flow
2121
@inject ISnackbar Snackbar
2222
@inject IFlowCredentialResolver CredentialResolver
2323
@inject IUAuthClient UAuthClient

‎samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor‎

Lines changed: 80 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,31 @@
2121
<PropertyColumn Property="x => x.IsVerified" Title="Verified" Editable="false" />
2222
<TemplateColumn Title="Actions" Editable="false">
2323
<CellTemplate>
24-
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Filled.Edit" OnClick="@context.Actions.StartEditingItemAsync" />
25-
<MudIconButton Size="@Size.Small" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => DeleteIdentifier(context.Item.Id))" />
24+
<MudStack Style="min-width: 120px" Row="true" Spacing="2" Wrap="Wrap.Wrap">
25+
<MudTooltip Text="Edit" Color="Color.Primary" Delay="300">
26+
<MudIconButton Color="Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Edit" OnClick="@context.Actions.StartEditingItemAsync" />
27+
</MudTooltip>
28+
@if (context.Item.IsPrimary)
29+
{
30+
<MudTooltip Text="Unset Primary" Color="Color.Primary" Delay="300">
31+
<MudIconButton Color="Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.KeyOff" OnClick="@(() => UnsetPrimaryAsync(context.Item.Id))" />
32+
</MudTooltip>
33+
}
34+
else
35+
{
36+
<MudTooltip Text="Set Primary" Color="Color.Primary" Delay="300">
37+
<MudIconButton Color="Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Key" OnClick="@(() => SetPrimaryAsync(context.Item.Id))" />
38+
</MudTooltip>
39+
}
40+
41+
<MudTooltip Text="Verify" Color="Color.Primary" Delay="300">
42+
<MudIconButton Color="Color.Primary" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Verified" OnClick="@(() => VerifyAsync(context.Item.Id))" />
43+
</MudTooltip>
44+
45+
<MudTooltip Text="Delete" Color="Color.Error" Delay="300">
46+
<MudIconButton Color="Color.Error" Variant="Variant.Filled" Icon="@Icons.Material.Filled.Delete" OnClick="@(() => DeleteIdentifier(context.Item.Id))" />
47+
</MudTooltip>
48+
</MudStack>
2649
</CellTemplate>
2750
</TemplateColumn>
2851
</Columns>
@@ -67,7 +90,7 @@
6790

6891
if (firstRender)
6992
{
70-
var result = await UAuthClient.Identifiers.GetUserIdentifiersAsync(AuthState.Identity!.UserKey);
93+
var result = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
7194
if (result != null && result.IsSuccess && result.Value != null)
7295
{
7396
_identifiers = result.Value.ToList();
@@ -114,7 +137,7 @@
114137
if (result.IsSuccess)
115138
{
116139
Snackbar.Add("Identifier added successfully", Severity.Success);
117-
var getResult = await UAuthClient.Identifiers.GetUserIdentifiersAsync(AuthState.Identity!.UserKey);
140+
var getResult = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
118141
_identifiers = getResult.Value?.ToList() ?? new List<UserIdentifierDto>();
119142
StateHasChanged();
120143
}
@@ -124,20 +147,71 @@
124147
}
125148
}
126149

150+
private async Task SetPrimaryAsync(Guid id)
151+
{
152+
SetPrimaryUserIdentifierRequest request = new() { IdentifierId = id };
153+
var result = await UAuthClient.Identifiers.SetPrimarySelfAsync(request);
154+
if (result.IsSuccess)
155+
{
156+
Snackbar.Add("Primary identifier set successfully", Severity.Success);
157+
var getResult = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
158+
_identifiers = getResult.Value?.ToList() ?? new List<UserIdentifierDto>();
159+
StateHasChanged();
160+
}
161+
else
162+
{
163+
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Failed to set primary identifier", Severity.Error);
164+
}
165+
}
166+
167+
private async Task VerifyAsync(Guid id)
168+
{
169+
VerifyUserIdentifierRequest request = new() { IdentifierId = id };
170+
var result = await UAuthClient.Identifiers.VerifySelfAsync(request);
171+
if (result.IsSuccess)
172+
{
173+
Snackbar.Add("Primary identifier verified successfully", Severity.Success);
174+
var getResult = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
175+
_identifiers = getResult.Value?.ToList() ?? new List<UserIdentifierDto>();
176+
StateHasChanged();
177+
}
178+
else
179+
{
180+
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Failed to verify primary identifier", Severity.Error);
181+
}
182+
}
183+
184+
private async Task UnsetPrimaryAsync(Guid id)
185+
{
186+
UnsetPrimaryUserIdentifierRequest request = new() { IdentifierId = id };
187+
var result = await UAuthClient.Identifiers.UnsetPrimarySelfAsync(request);
188+
if (result.IsSuccess)
189+
{
190+
Snackbar.Add("Primary identifier unset successfully", Severity.Success);
191+
var getResult = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
192+
_identifiers = getResult.Value?.ToList() ?? new List<UserIdentifierDto>();
193+
StateHasChanged();
194+
}
195+
else
196+
{
197+
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Failed to unset primary identifier", Severity.Error);
198+
}
199+
}
200+
127201
private async Task DeleteIdentifier(Guid id)
128202
{
129203
DeleteUserIdentifierRequest request = new() { IdentifierId = id };
130204
var result = await UAuthClient.Identifiers.DeleteSelfAsync(request);
131205
if (result.IsSuccess)
132206
{
133207
Snackbar.Add("Identifier deleted successfully", Severity.Success);
134-
var getResult = await UAuthClient.Identifiers.GetUserIdentifiersAsync(AuthState.Identity!.UserKey);
208+
var getResult = await UAuthClient.Identifiers.GetMyIdentifiersAsync();
135209
_identifiers = getResult.Value?.ToList() ?? new List<UserIdentifierDto>();
136210
StateHasChanged();
137211
}
138212
else
139213
{
140-
Snackbar.Add("Failed to delete identifier", Severity.Error);
214+
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Failed to delete identifier", Severity.Error);
141215
}
142216
}
143217

‎samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
//o.Token.RefreshTokenLifetime = TimeSpan.FromSeconds(32);
4646
o.Login.MaxFailedAttempts = 2;
4747
o.Login.LockoutDuration = TimeSpan.FromSeconds(10);
48+
o.UserIdentifiers.AllowMultipleUsernames = true;
4849
})
4950
.AddUltimateAuthUsersInMemory()
5051
.AddUltimateAuthUsersReference()

‎src/CodeBeam.UltimateAuth.Core/Errors/Base/UAuthRuntimeException.cs‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
public abstract class UAuthRuntimeException : UAuthException
44
{
5+
public virtual int StatusCode => 400;
6+
7+
public virtual string Title => "A request error occurred.";
8+
9+
public virtual string TypePrefix => "https://docs.ultimateauth.com/errors";
10+
511
protected UAuthRuntimeException(string code, string message) : base(code, message)
612
{
713
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
namespace CodeBeam.UltimateAuth.Core.Errors;
2+
3+
public abstract class UAuthIdentifierException : UAuthRuntimeException
4+
{
5+
public override string Title => "User identifier operation failed.";
6+
public override string TypePrefix => "https://docs.ultimateauth.com/errors/identifiers";
7+
8+
protected UAuthIdentifierException(string code, string message) : base(code, message)
9+
{
10+
}
11+
}
12+
13+
public sealed class UAuthIdentifierConflictException : UAuthIdentifierException
14+
{
15+
public override int StatusCode => 409;
16+
public UAuthIdentifierConflictException(string code, string? message = null)
17+
: base(code, message ?? code) { }
18+
}
19+
20+
public sealed class UAuthIdentifierValidationException : UAuthIdentifierException
21+
{
22+
public override int StatusCode => 400;
23+
public UAuthIdentifierValidationException(string code, string? message = null)
24+
: base(code, message ?? code) { }
25+
}
26+
27+
public sealed class UAuthIdentifierNotFoundException : UAuthIdentifierException
28+
{
29+
public override int StatusCode => 404;
30+
public UAuthIdentifierNotFoundException(string code = "identifier_not_found", string? message = null)
31+
: base(code, message ?? code) { }
32+
}
Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
using CodeBeam.UltimateAuth.Core.Domain;
2-
using Microsoft.AspNetCore.Http;
1+
//using CodeBeam.UltimateAuth.Core.Domain;
2+
//using Microsoft.AspNetCore.Http;
33

4-
namespace CodeBeam.UltimateAuth.Server.Endpoints;
4+
//namespace CodeBeam.UltimateAuth.Server.Endpoints;
55

6-
internal sealed class LoginEndpointHandlerBridge : ILoginEndpointHandler
7-
{
8-
private readonly LoginEndpointHandler<UserKey> _inner;
6+
//internal sealed class LoginEndpointHandlerBridge : ILoginEndpointHandler
7+
//{
8+
// private readonly LoginEndpointHandler<UserKey> _inner;
99

10-
public LoginEndpointHandlerBridge(LoginEndpointHandler<UserKey> inner)
11-
{
12-
_inner = inner;
13-
}
10+
// public LoginEndpointHandlerBridge(LoginEndpointHandler<UserKey> inner)
11+
// {
12+
// _inner = inner;
13+
// }
1414

15-
public Task<IResult> LoginAsync(HttpContext ctx) => _inner.LoginAsync(ctx);
16-
}
15+
// public Task<IResult> LoginAsync(HttpContext ctx) => _inner.LoginAsync(ctx);
16+
//}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
using CodeBeam.UltimateAuth.Core.Domain;
2-
using Microsoft.AspNetCore.Http;
1+
//using CodeBeam.UltimateAuth.Core.Domain;
2+
//using Microsoft.AspNetCore.Http;
33

4-
namespace CodeBeam.UltimateAuth.Server.Endpoints;
4+
//namespace CodeBeam.UltimateAuth.Server.Endpoints;
55

6-
internal sealed class LogoutEndpointHandlerBridge : ILogoutEndpointHandler
7-
{
8-
private readonly LogoutEndpointHandler<UserKey> _inner;
6+
//internal sealed class LogoutEndpointHandlerBridge : ILogoutEndpointHandler
7+
//{
8+
// private readonly LogoutEndpointHandler<UserKey> _inner;
99

10-
public LogoutEndpointHandlerBridge(LogoutEndpointHandler<UserKey> inner)
11-
{
12-
_inner = inner;
13-
}
10+
// public LogoutEndpointHandlerBridge(LogoutEndpointHandler<UserKey> inner)
11+
// {
12+
// _inner = inner;
13+
// }
1414

15-
public Task<IResult> LogoutAsync(HttpContext ctx)
16-
=> _inner.LogoutAsync(ctx);
17-
}
15+
// public Task<IResult> LogoutAsync(HttpContext ctx)
16+
// => _inner.LogoutAsync(ctx);
17+
//}
Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
1-
using CodeBeam.UltimateAuth.Core.Domain;
2-
using Microsoft.AspNetCore.Http;
1+
//using CodeBeam.UltimateAuth.Core.Domain;
2+
//using Microsoft.AspNetCore.Http;
33

4-
namespace CodeBeam.UltimateAuth.Server.Endpoints;
4+
//namespace CodeBeam.UltimateAuth.Server.Endpoints;
55

6-
internal sealed class PkceEndpointHandlerBridge : IPkceEndpointHandler
7-
{
8-
private readonly PkceEndpointHandler<UserKey> _inner;
6+
//internal sealed class PkceEndpointHandlerBridge : IPkceEndpointHandler
7+
//{
8+
// private readonly PkceEndpointHandler<UserKey> _inner;
99

10-
public PkceEndpointHandlerBridge(PkceEndpointHandler<UserKey> inner)
11-
{
12-
_inner = inner;
13-
}
10+
// public PkceEndpointHandlerBridge(PkceEndpointHandler<UserKey> inner)
11+
// {
12+
// _inner = inner;
13+
// }
1414

15-
public Task<IResult> AuthorizeAsync(HttpContext ctx) => _inner.AuthorizeAsync(ctx);
15+
// public Task<IResult> AuthorizeAsync(HttpContext ctx) => _inner.AuthorizeAsync(ctx);
1616

17-
public Task<IResult> CompleteAsync(HttpContext ctx) => _inner.CompleteAsync(ctx);
18-
}
17+
// public Task<IResult> CompleteAsync(HttpContext ctx) => _inner.CompleteAsync(ctx);
18+
//}

‎src/CodeBeam.UltimateAuth.Server/Endpoints/LoginEndpointHandler.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,17 @@
99

1010
namespace CodeBeam.UltimateAuth.Server.Endpoints;
1111

12-
public sealed class LoginEndpointHandler<TUserId> : ILoginEndpointHandler
12+
public sealed class LoginEndpointHandler : ILoginEndpointHandler
1313
{
1414
private readonly IAuthFlowContextAccessor _authFlow;
15-
private readonly IUAuthFlowService<TUserId> _flowService;
15+
private readonly IUAuthFlowService _flowService;
1616
private readonly IClock _clock;
1717
private readonly ICredentialResponseWriter _credentialResponseWriter;
1818
private readonly IAuthRedirectResolver _redirectResolver;
1919

2020
public LoginEndpointHandler(
2121
IAuthFlowContextAccessor authFlow,
22-
IUAuthFlowService<TUserId> flowService,
22+
IUAuthFlowService flowService,
2323
IClock clock,
2424
ICredentialResponseWriter credentialResponseWriter,
2525
IAuthRedirectResolver redirectResolver)

‎src/CodeBeam.UltimateAuth.Server/Endpoints/LogoutEndpointHandler.cs‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@
99

1010
namespace CodeBeam.UltimateAuth.Server.Endpoints;
1111

12-
public sealed class LogoutEndpointHandler<TUserId> : ILogoutEndpointHandler
12+
public sealed class LogoutEndpointHandler : ILogoutEndpointHandler
1313
{
1414
private readonly IAuthFlowContextAccessor _authContext;
15-
private readonly IUAuthFlowService<TUserId> _flow;
15+
private readonly IUAuthFlowService _flow;
1616
private readonly IClock _clock;
1717
private readonly IUAuthCookieManager _cookieManager;
1818
private readonly IAuthRedirectResolver _redirectResolver;
1919

20-
public LogoutEndpointHandler(IAuthFlowContextAccessor authContext, IUAuthFlowService<TUserId> flow, IClock clock, IUAuthCookieManager cookieManager, IAuthRedirectResolver redirectResolver)
20+
public LogoutEndpointHandler(IAuthFlowContextAccessor authContext, IUAuthFlowService flow, IClock clock, IUAuthCookieManager cookieManager, IAuthRedirectResolver redirectResolver)
2121
{
2222
_authContext = authContext;
2323
_flow = flow;

0 commit comments

Comments
 (0)