Skip to content

Commit c8dcbad

Browse files
committed
WASM Sample New Design Implementation
1 parent 81a74cf commit c8dcbad

Some content is hidden

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

44 files changed

+1699
-640
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
@namespace CodeBeam.UltimateAuth.Sample
2+
@inherits ComponentBase
3+
4+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 200 240" width="@Size" height="@Size" style="@BuildStyle()" class="@Class">
5+
6+
@if (Variant == UAuthLogoVariant.Brand)
7+
{
8+
<path fill="@ShieldColor"
9+
d="M32.39,14.07H167.61c11.27,0,18,6.76,18,18V133.52c0,22.54-58.59,69.87-85.64,92.41-27-22.54-85.64-69.87-85.64-92.41V32.1C14.36,20.83,21.12,14.07,32.39,14.07Z" />
10+
11+
<path fill="@KeyColor" fill-rule="evenodd" d="@KeyPath" />
12+
}
13+
else
14+
{
15+
<path d="M32.39,14.07H167.61c11.27,0,18,6.76,18,18V133.52c0,22.54-58.59,69.87-85.64,92.41-27-22.54-85.64-69.87-85.64-92.41V32.1C14.36,20.83,21.12,14.07,32.39,14.07Z" />
16+
17+
<path fill-rule="evenodd" d="@KeyPath" />
18+
}
19+
</svg>
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
using Microsoft.AspNetCore.Components;
2+
using Microsoft.AspNetCore.Components.Web;
3+
4+
namespace CodeBeam.UltimateAuth.Sample;
5+
6+
public partial class UAuthLogo : ComponentBase
7+
{
8+
[Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand;
9+
10+
[Parameter] public int Size { get; set; } = 32;
11+
12+
[Parameter] public string? ShieldColor { get; set; } = "#00072d";
13+
[Parameter] public string? KeyColor { get; set; } = "#f6f5ae";
14+
15+
[Parameter] public string? Class { get; set; }
16+
[Parameter] public string? Style { get; set; }
17+
18+
private string BuildStyle()
19+
{
20+
if (Variant == UAuthLogoVariant.Mono)
21+
return $"color: {KeyColor}; {Style}";
22+
23+
return Style ?? "";
24+
}
25+
26+
protected string KeyPath => @"
27+
M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37
28+
A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99
29+
v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153
30+
V99.79h-8V93.32L108.19,89h12.24
31+
A11.67,11.67,0,0,0,132.1,77.37V51.11
32+
A11.67,11.67,0,0,0,120.43,39.44Z
33+
34+
M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92
35+
v5.84a2.92,2.92 0 0 1 -2.92,2.92
36+
h-5.84a2.91,2.91 0 0 1 -2.91,-2.92
37+
v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z
38+
39+
M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92
40+
v5.83a2.92,2.92 0 0 1 -2.92,2.92
41+
h-5.84a2.91,2.91 0 0 1 -2.91,-2.92
42+
v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z
43+
44+
M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92
45+
v5.84a2.91,2.91 0 0 1 -2.91,2.91
46+
h-5.84a2.92,2.92 0 0 1 -2.92,-2.91
47+
v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z
48+
49+
M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92
50+
v5.83a2.91,2.91 0 0 1 -2.91,2.92
51+
h-5.84a2.92,2.92 0 0 1 -2.92,-2.92
52+
v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z
53+
";
54+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
namespace CodeBeam.UltimateAuth.Sample;
2+
3+
public enum UAuthLogoVariant
4+
{
5+
Brand,
6+
Mono
7+
}

samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,10 @@
99
</PropertyGroup>
1010

1111
<ItemGroup>
12-
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="9.0.1" />
13-
<PackageReference Include="MudBlazor" Version="9.0.0" />
12+
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="9.0.3" />
13+
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.5" />
14+
<PackageReference Include="MudBlazor" Version="9.1.0" />
15+
<PackageReference Include="Scalar.AspNetCore.Microsoft" Version="2.13.8" />
1416
</ItemGroup>
1517

1618
<ItemGroup>

samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/App.razor

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
77
<base href="/" />
88
<ResourcePreloader />
9-
<link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" />
9+
@* <link rel="stylesheet" href="@Assets["lib/bootstrap/dist/css/bootstrap.min.css"]" /> *@
1010
<link rel="stylesheet" href="@Assets["app.css"]" />
1111
<link rel="stylesheet" href="@Assets["UltimateAuth.Sample.UAuthHub.styles.css"]" />
1212
<ImportMap />
13-
<link rel="icon" type="image/png" href="favicon.png" />
13+
<link rel="icon" type="image/png" href="~/UltimateAuth-Logo.png" />
1414

1515
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" rel="stylesheet" />
1616
<link href="_content/MudBlazor/MudBlazor.min.css" rel="stylesheet" />

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

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,26 @@
3131
<MudStack Class="uauth-stack">
3232
@if (_state == null || !_state.IsActive)
3333
{
34-
<MudText>
35-
This page cannot be accessed directly.
36-
UAuthHub login flows can only be initiated by an authorized client application.
37-
</MudText>
34+
<MudPage Class="d-flex align-center justify-center" FullScreen="FullScreen.FullWithoutAppbar" Column="1" Row="1">
35+
<MudPaper Class="pa-8" Elevation="4" Style="max-width: 520px; width: 100%;">
36+
<MudStack Spacing="3" AlignItems="AlignItems.Center">
37+
<UAuthLogo Size="72" />
38+
39+
<MudText Typo="Typo.h5"><b>Access Denied</b></MudText>
40+
41+
<MudText Typo="Typo.body2" Align="Align.Center">
42+
This page cannot be accessed directly.
43+
UAuthHub login flows can only be initiated by an authorized client application.
44+
</MudText>
45+
46+
<MudDivider Class="my-2" />
47+
48+
<MudText Typo="Typo.caption" Color="Color.Secondary">
49+
UltimateAuth protects this resource based on your session and permissions.
50+
</MudText>
51+
</MudStack>
52+
</MudPaper>
53+
</MudPage>
3854
return;
3955
}
4056
<UAuthLoginForm Identifier="@_username" Secret="@_password" LoginType="UAuthLoginType.Pkce">

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

Lines changed: 98 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -6,131 +6,130 @@
66
using Microsoft.AspNetCore.WebUtilities;
77
using MudBlazor;
88

9-
namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages
9+
namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages;
10+
11+
public partial class Home
1012
{
11-
public partial class Home
12-
{
13-
[SupplyParameterFromQuery(Name = "hub")]
14-
public string? HubKey { get; set; }
13+
[SupplyParameterFromQuery(Name = "hub")]
14+
public string? HubKey { get; set; }
1515

16-
private string? _username;
17-
private string? _password;
16+
private string? _username;
17+
private string? _password;
1818

19-
private HubFlowState? _state;
19+
private HubFlowState? _state;
2020

21-
protected override async Task OnParametersSetAsync()
21+
protected override async Task OnParametersSetAsync()
22+
{
23+
if (string.IsNullOrWhiteSpace(HubKey))
2224
{
23-
if (string.IsNullOrWhiteSpace(HubKey))
24-
{
25-
_state = null;
26-
return;
27-
}
28-
29-
if (!HubSessionId.TryParse(HubKey, out var hubSessionId))
30-
_state = await HubFlowReader.GetStateAsync(hubSessionId);
25+
_state = null;
26+
return;
3127
}
3228

33-
protected override async Task OnAfterRenderAsync(bool firstRender)
34-
{
35-
if (!firstRender)
36-
return;
37-
38-
var currentError = await BrowserStorage.GetAsync(StorageScope.Session, "uauth:last_error");
39-
40-
if (!string.IsNullOrWhiteSpace(currentError))
41-
{
42-
Snackbar.Add(ResolveErrorMessage(currentError), Severity.Error);
43-
await BrowserStorage.RemoveAsync(StorageScope.Session, "uauth:last_error");
44-
}
45-
46-
var uri = Nav.ToAbsoluteUri(Nav.Uri);
47-
var query = QueryHelpers.ParseQuery(uri.Query);
48-
49-
if (query.TryGetValue("__uauth_error", out var error))
50-
{
51-
await BrowserStorage.SetAsync(StorageScope.Session, "uauth:last_error", error.ToString());
52-
}
53-
54-
if (string.IsNullOrWhiteSpace(HubKey))
55-
{
56-
return;
57-
}
58-
59-
if (_state is null || !_state.Exists)
60-
return;
61-
62-
if (_state?.IsActive != true)
63-
{
64-
await StartNewPkceAsync();
65-
return;
66-
}
67-
}
29+
if (!HubSessionId.TryParse(HubKey, out var hubSessionId))
30+
_state = await HubFlowReader.GetStateAsync(hubSessionId);
31+
}
6832

69-
// For testing & debugging
70-
private async Task ProgrammaticPkceLogin()
71-
{
72-
var hub = _state;
33+
protected override async Task OnAfterRenderAsync(bool firstRender)
34+
{
35+
if (!firstRender)
36+
return;
7337

74-
if (hub is null)
75-
return;
38+
var currentError = await BrowserStorage.GetAsync(StorageScope.Session, "uauth:last_error");
7639

77-
if (!HubSessionId.TryParse(HubKey, out var hubSessionId))
78-
return;
40+
if (!string.IsNullOrWhiteSpace(currentError))
41+
{
42+
Snackbar.Add(ResolveErrorMessage(currentError), Severity.Error);
43+
await BrowserStorage.RemoveAsync(StorageScope.Session, "uauth:last_error");
44+
}
7945

80-
var credentials = await HubCredentialResolver.ResolveAsync(hubSessionId);
46+
var uri = Nav.ToAbsoluteUri(Nav.Uri);
47+
var query = QueryHelpers.ParseQuery(uri.Query);
8148

82-
var request = new PkceLoginRequest
83-
{
84-
Identifier = "admin",
85-
Secret = "admin",
86-
AuthorizationCode = credentials?.AuthorizationCode ?? string.Empty,
87-
CodeVerifier = credentials?.CodeVerifier ?? string.Empty,
88-
ReturnUrl = _state?.ReturnUrl ?? string.Empty
89-
};
90-
await UAuthClient.Flows.CompletePkceLoginAsync(request);
49+
if (query.TryGetValue("__uauth_error", out var error))
50+
{
51+
await BrowserStorage.SetAsync(StorageScope.Session, "uauth:last_error", error.ToString());
52+
}
53+
54+
if (string.IsNullOrWhiteSpace(HubKey))
55+
{
56+
return;
9157
}
9258

93-
private async Task StartNewPkceAsync()
59+
if (_state is null || !_state.Exists)
60+
return;
61+
62+
if (_state?.IsActive != true)
9463
{
95-
var returnUrl = await ResolveReturnUrlAsync();
96-
await UAuthClient.Flows.BeginPkceAsync(returnUrl);
64+
await StartNewPkceAsync();
65+
return;
9766
}
67+
}
9868

99-
private async Task<string> ResolveReturnUrlAsync()
69+
// For testing & debugging
70+
private async Task ProgrammaticPkceLogin()
71+
{
72+
var hub = _state;
73+
74+
if (hub is null)
75+
return;
76+
77+
if (!HubSessionId.TryParse(HubKey, out var hubSessionId))
78+
return;
79+
80+
var credentials = await HubCredentialResolver.ResolveAsync(hubSessionId);
81+
82+
var request = new PkceLoginRequest
10083
{
101-
var fromContext = _state?.ReturnUrl;
102-
if (!string.IsNullOrWhiteSpace(fromContext))
103-
return fromContext;
84+
Identifier = "admin",
85+
Secret = "admin",
86+
AuthorizationCode = credentials?.AuthorizationCode ?? string.Empty,
87+
CodeVerifier = credentials?.CodeVerifier ?? string.Empty,
88+
ReturnUrl = _state?.ReturnUrl ?? string.Empty
89+
};
90+
await UAuthClient.Flows.CompletePkceLoginAsync(request);
91+
}
10492

105-
var uri = Nav.ToAbsoluteUri(Nav.Uri);
106-
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);
93+
private async Task StartNewPkceAsync()
94+
{
95+
var returnUrl = await ResolveReturnUrlAsync();
96+
await UAuthClient.Flows.BeginPkceAsync(returnUrl);
97+
}
10798

108-
if (query.TryGetValue("return_url", out var ru) && !string.IsNullOrWhiteSpace(ru))
109-
return ru!;
99+
private async Task<string> ResolveReturnUrlAsync()
100+
{
101+
var fromContext = _state?.ReturnUrl;
102+
if (!string.IsNullOrWhiteSpace(fromContext))
103+
return fromContext;
110104

111-
if (query.TryGetValue("hub", out var hubKey) && !string.IsNullOrWhiteSpace(hubKey))
112-
{
113-
var artifact = await AuthStore.GetAsync(new AuthArtifactKey(hubKey!));
114-
if (artifact is HubFlowArtifact flow && !string.IsNullOrWhiteSpace(flow.ReturnUrl))
115-
return flow.ReturnUrl!;
116-
}
105+
var uri = Nav.ToAbsoluteUri(Nav.Uri);
106+
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);
117107

118-
// Config default (recommend adding to options)
119-
//if (!string.IsNullOrWhiteSpace(_options.Login.DefaultReturnUrl))
120-
// return _options.Login.DefaultReturnUrl!;
108+
if (query.TryGetValue("return_url", out var ru) && !string.IsNullOrWhiteSpace(ru))
109+
return ru!;
121110

122-
return Nav.Uri;
123-
}
124-
125-
private string ResolveErrorMessage(string? errorKey)
111+
if (query.TryGetValue("hub", out var hubKey) && !string.IsNullOrWhiteSpace(hubKey))
126112
{
127-
if (errorKey == "invalid")
128-
{
129-
return "Login failed.";
130-
}
113+
var artifact = await AuthStore.GetAsync(new AuthArtifactKey(hubKey!));
114+
if (artifact is HubFlowArtifact flow && !string.IsNullOrWhiteSpace(flow.ReturnUrl))
115+
return flow.ReturnUrl!;
116+
}
117+
118+
// Config default (recommend adding to options)
119+
//if (!string.IsNullOrWhiteSpace(_options.Login.DefaultReturnUrl))
120+
// return _options.Login.DefaultReturnUrl!;
131121

132-
return "Failed attempt.";
122+
return Nav.Uri;
123+
}
124+
125+
private string ResolveErrorMessage(string? errorKey)
126+
{
127+
if (errorKey == "invalid")
128+
{
129+
return "Login failed.";
133130
}
134131

132+
return "Failed attempt.";
135133
}
134+
136135
}

samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Controllers/HubLoginController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99

1010
namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Controllers;
1111

12-
[Route("uauthhub")]
12+
[Route("auth/uauthhub")]
1313
[IgnoreAntiforgeryToken]
1414
public sealed class HubLoginController : Controller
1515
{

0 commit comments

Comments
 (0)