Skip to content

Commit 290ad95

Browse files
authored
Create Main Flows (#7)
* Create Main Flows * Complete Login Path with Minimum Required Features * Add Validation Flow * Logout Flow & Fix Cookie Options Conflict * Refresh Flow * Polish Flows
1 parent e21f572 commit 290ad95

File tree

195 files changed

+62647
-348
lines changed

Some content is hidden

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

195 files changed

+62647
-348
lines changed

CodeBeam.UltimateAuth.Server.AspNetCore/CodeBeam.UltimateAuth.Server.AspNetCore.csproj

Lines changed: 0 additions & 9 deletions
This file was deleted.

UltimateAuth.slnx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<Solution>
22
<Folder Name="/Samples/">
33
<Project Path="samples/blazor-server/UltimateAuth.BlazorServer/UltimateAuth.BlazorServer.csproj" />
4+
<Project Path="samples/blazor-standalone-wasm/UltimateAuth.Sample.BlazorStandaloneWasm/UltimateAuth.Sample.BlazorStandaloneWasm.csproj" Id="27bd3c4d-65a9-4c70-a6c9-4178b1897730" />
45
</Folder>
56
<Folder Name="/Solution Items/">
67
<File Path="Readme.md" />

samples/blazor-server/UltimateAuth.BlazorServer/Components/App.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<script src="_framework/blazor.web.js"></script>
2222
<script src="_content/MudBlazor/MudBlazor.min.js"></script>
2323
<script src="_content/CodeBeam.MudBlazor.Extensions/MudExtensions.min.js"></script>
24+
<script src="_content/CodeBeam.UltimateAuth.Client/uauth.js"></script>
2425
</body>
2526

2627
</html>

samples/blazor-server/UltimateAuth.BlazorServer/Components/Layout/MainLayout.razor

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
@inherits LayoutComponentBase
22

3+
<UAuthClientProvider />
4+
35
<MudThemeProvider />
46
<MudPopoverProvider />
57
<MudDialogProvider />
Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,47 @@
11
@page "/"
2-
@inject IUAuthFlowService<UserId> FlowService
2+
@page "/login"
3+
@using CodeBeam.UltimateAuth.Client
4+
@using CodeBeam.UltimateAuth.Core.Abstractions
5+
@using CodeBeam.UltimateAuth.Core.Runtime
6+
@using CodeBeam.UltimateAuth.Server.Abstractions
7+
@using CodeBeam.UltimateAuth.Server.Cookies
8+
@using CodeBeam.UltimateAuth.Server.Infrastructure
9+
@inject IUAuthFlowService<UserId> Flow
310
@inject ISnackbar Snackbar
4-
@inject IHttpClientFactory Http
11+
@inject ISessionQueryService<UserId> SessionQuery
12+
@inject ICredentialResolver CredentialResolver
13+
@inject IClock Clock
14+
@inject IUAuthCookieManager CookieManager
15+
@inject IHttpContextAccessor HttpContextAccessor
16+
@inject IUAuthClient UAuthClient
17+
@inject NavigationManager Nav
18+
@inject IUAuthProductInfoProvider ProductInfo
19+
520

621
<div class="uauth-page d-flex align-center justify-center">
722
<MudStack Class="uauth-stack">
8-
<form method="post" action="/auth/login">
9-
<MudText Typo="Typo.h4">Welcome to UltimateAuth!</MudText>
10-
<!-- Hidden fields -->
11-
<input type="hidden" name="Identifier" value="@_username" />
12-
<input type="hidden" name="Secret" value="@_password" />
23+
<UALoginForm @ref="_form" Identifier="@_username" Secret="@_password">
24+
<MudStack>
25+
<MudText Typo="Typo.h4">Welcome to UltimateAuth!</MudText>
26+
<MudTextField @bind-Value="@_username" Variant="Variant.Outlined" Label="Username" Immediate="true" />
27+
<MudPasswordField @bind-Value="@_password" Variant="Variant.Outlined" Label="Password" Immediate="true" />
28+
<MudButton Variant="Variant.Filled" Color="Color.Primary" ButtonType="ButtonType.Submit">Login</MudButton>
29+
</MudStack>
30+
</UALoginForm>
31+
32+
<MudStack Class="mud-width-full" Row="true">
33+
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="ValidateAsync">Validate</MudButton>
34+
<MudButton Variant="Variant.Filled" Color="Color.Secondary" OnClick="LogoutAsync">Logout</MudButton>
35+
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="RefreshAsync">Refresh</MudButton>
36+
</MudStack>
1337

14-
<!-- UI -->
15-
<MudTextField @bind-Value="@_username" Variant="Variant.Outlined" Label="Username" Immediate="true" />
16-
<MudPasswordField @bind-Value="@_password" Variant="Variant.Outlined" Label="Password" Immediate="true" />
38+
<MudStack Class="mud-width-full">
39+
<MudButton Variant="Variant.Filled" Color="Color.Info" OnClick="ProgrammaticLogin">Programmatic Login</MudButton>
40+
</MudStack>
1741

18-
<MudButton Variant="Variant.Filled" Color="Color.Primary" ButtonType="ButtonType.Submit">Login</MudButton>
19-
</form>
42+
<MudStack Spacing="0">
43+
<MudText><b>@ProductInfo.Get().ProductName</b> v @ProductInfo.Get().Version</MudText>
44+
<MudText>Client Profile: @ProductInfo.Get().ClientProfile.ToString()</MudText>
45+
</MudStack>
2046
</MudStack>
2147
</div>
Lines changed: 96 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
using CodeBeam.UltimateAuth.Core.Contracts;
2-
using Microsoft.AspNetCore.Authentication.Cookies;
3-
using Microsoft.AspNetCore.Http;
1+
using CodeBeam.UltimateAuth.Client;
2+
using CodeBeam.UltimateAuth.Core.Contracts;
3+
using CodeBeam.UltimateAuth.Core.Domain;
44
using MudBlazor;
55

66
namespace UltimateAuth.BlazorServer.Components.Pages
@@ -10,38 +10,109 @@ public partial class Home
1010
private string? _username;
1111
private string? _password;
1212

13-
private async Task LoginAsync()
13+
private UALoginForm _form = null!;
14+
15+
private async Task ProgrammaticLogin()
16+
{
17+
var request = new LoginRequest
18+
{
19+
Identifier = "Admin",
20+
Secret = "Password!",
21+
};
22+
await UAuthClient.LoginAsync(request);
23+
}
24+
25+
private async Task ValidateAsync()
1426
{
27+
var httpContext = HttpContextAccessor.HttpContext;
1528

16-
try
29+
if (httpContext is null)
1730
{
18-
//var result = await FlowService.LoginAsync(new LoginRequest
19-
//{
20-
// Identifier = _username!,
21-
// Secret = _password!
22-
//});
23-
var client = Http.CreateClient();
24-
var result = await client.PostAsJsonAsync(
25-
"https://localhost:7213/auth/login",
26-
new LoginRequest
27-
{
28-
Identifier = _username!,
29-
Secret = _password!
30-
});
31+
Snackbar.Add("HttpContext not available", Severity.Error);
32+
return;
33+
}
3134

35+
var credential = CredentialResolver.Resolve(httpContext);
3236

33-
if (!result.IsSuccessStatusCode)
37+
if (credential is null)
38+
{
39+
Snackbar.Add("No credential found", Severity.Error);
40+
return;
41+
}
42+
43+
if (!AuthSessionId.TryCreate(credential.Value, out var sessionId))
44+
{
45+
Snackbar.Add("Invalid session id", Severity.Error);
46+
return;
47+
}
48+
49+
var result = await SessionQuery.ValidateSessionAsync(
50+
new SessionValidationContext
3451
{
35-
Snackbar.Add("Login failed.", Severity.Info);
36-
return;
37-
}
52+
TenantId = credential.TenantId,
53+
SessionId = sessionId,
54+
Device = credential.Device,
55+
Now = Clock.UtcNow
56+
});
3857

39-
Snackbar.Add("Successfully logged in!", Severity.Success);
58+
if (result.IsValid)
59+
{
60+
Snackbar.Add("Session is valid ✅", Severity.Success);
4061
}
41-
catch (Exception ex)
62+
else
4263
{
43-
Snackbar.Add(ex.ToString(), Severity.Error);
64+
Snackbar.Add(
65+
$"Session invalid ❌ ({result.State})",
66+
Severity.Error);
4467
}
4568
}
69+
70+
private async Task LogoutAsync()
71+
{
72+
await UAuthClient.LogoutAsync();
73+
Snackbar.Add("Logged out", Severity.Success);
74+
}
75+
76+
private async Task RefreshAsync()
77+
{
78+
await UAuthClient.RefreshAsync();
79+
//Snackbar.Add("Logged out", Severity.Success);
80+
}
81+
82+
protected override void OnAfterRender(bool firstRender)
83+
{
84+
if (firstRender)
85+
{
86+
var uri = Nav.ToAbsoluteUri(Nav.Uri);
87+
var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query);
88+
89+
if (query.TryGetValue("error", out var error))
90+
{
91+
ShowLoginError(error.ToString());
92+
ClearQueryString();
93+
}
94+
}
95+
}
96+
97+
private void ShowLoginError(string code)
98+
{
99+
var message = code switch
100+
{
101+
"invalid" => "Invalid username or password.",
102+
"locked" => "Your account is locked.",
103+
"mfa" => "Multi-factor authentication required.",
104+
_ => "Login failed."
105+
};
106+
107+
Snackbar.Add(message, Severity.Error);
108+
}
109+
110+
private void ClearQueryString()
111+
{
112+
var uri = new Uri(Nav.Uri);
113+
var clean = uri.GetLeftPart(UriPartial.Path);
114+
Nav.NavigateTo(clean, replace: true);
115+
}
116+
46117
}
47118
}

samples/blazor-server/UltimateAuth.BlazorServer/Components/_Imports.razor

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
@using CodeBeam.UltimateAuth.Core.Abstractions
1313
@using CodeBeam.UltimateAuth.Core.Domain
14+
@using CodeBeam.UltimateAuth.Client
1415

1516
@using MudBlazor
1617
@using MudExtensions

samples/blazor-server/UltimateAuth.BlazorServer/Program.cs

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
using CodeBeam.UltimateAuth.Client.Extensions;
2+
using CodeBeam.UltimateAuth.Core.Extensions;
3+
using CodeBeam.UltimateAuth.Core.Options;
14
using CodeBeam.UltimateAuth.Credentials.InMemory;
25
using CodeBeam.UltimateAuth.Security.Argon2;
36
using CodeBeam.UltimateAuth.Server.Extensions;
@@ -12,7 +15,11 @@
1215

1316
// Add services to the container.
1417
builder.Services.AddRazorComponents()
15-
.AddInteractiveServerComponents();
18+
.AddInteractiveServerComponents()
19+
.AddCircuitOptions(options =>
20+
{
21+
options.DetailedErrors = true;
22+
});
1623

1724
builder.Services.AddMudServices();
1825
builder.Services.AddMudExtensions();
@@ -22,25 +29,40 @@
2229

2330
builder.Services.AddHttpContextAccessor();
2431

32+
builder.Services.AddUltimateAuth();
2533

26-
builder.Services.AddUltimateAuthServer()
34+
builder.Services.AddUltimateAuthServer(o => {
35+
o.Diagnostics.EnableRefreshHeaders = true;
36+
})
2737
.AddInMemoryCredentials()
2838
.AddUltimateAuthInMemorySessions()
2939
.AddUltimateAuthInMemoryTokens()
3040
.AddUltimateAuthArgon2();
3141

32-
builder.Services.AddHttpClient("AuthApi", client =>
33-
{
34-
client.BaseAddress = new Uri("https://localhost:7213");
35-
})
36-
.ConfigurePrimaryHttpMessageHandler(() =>
42+
builder.Services.AddUltimateAuthClient();
43+
44+
builder.Services.AddScoped(sp =>
3745
{
38-
return new HttpClientHandler
46+
var navigation = sp.GetRequiredService<NavigationManager>();
47+
48+
return new HttpClient
3949
{
40-
UseCookies = true
50+
BaseAddress = new Uri(navigation.BaseUri)
4151
};
4252
});
4353

54+
//builder.Services.AddHttpClient("AuthApi", client =>
55+
//{
56+
// client.BaseAddress = new Uri("https://localhost:7213");
57+
//})
58+
//.ConfigurePrimaryHttpMessageHandler(() =>
59+
//{
60+
// return new HttpClientHandler
61+
// {
62+
// UseCookies = true
63+
// };
64+
//});
65+
4466

4567
var app = builder.Build();
4668

samples/blazor-server/UltimateAuth.BlazorServer/UltimateAuth.BlazorServer.csproj

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
<Project Sdk="Microsoft.NET.Sdk.Web">
22

3-
<PropertyGroup>
4-
<TargetFramework>net8.0</TargetFramework>
5-
<Nullable>enable</Nullable>
6-
<ImplicitUsings>enable</ImplicitUsings>
7-
</PropertyGroup>
3+
<PropertyGroup>
4+
<TargetFramework>net8.0</TargetFramework>
5+
<Nullable>enable</Nullable>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Version>0.0.1-preview</Version>
8+
</PropertyGroup>
89

9-
<ItemGroup>
10-
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.3.0" />
11-
<PackageReference Include="MudBlazor" Version="8.15.0" />
12-
</ItemGroup>
10+
<ItemGroup>
11+
<PackageReference Include="MudBlazor" Version="8.15.0" />
12+
<PackageReference Include="CodeBeam.MudBlazor.Extensions" Version="8.3.0" />
13+
</ItemGroup>
1314

1415
<ItemGroup>
16+
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Client\CodeBeam.UltimateAuth.Client.csproj" />
1517
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Core\CodeBeam.UltimateAuth.Core.csproj" />
1618
<ProjectReference Include="..\..\..\src\CodeBeam.UltimateAuth.Server\CodeBeam.UltimateAuth.Server.csproj" />
1719
<ProjectReference Include="..\..\..\src\security\CodeBeam.UltimateAuth.Security.Argon2\CodeBeam.UltimateAuth.Security.Argon2.csproj" />
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<Router AppAssembly="@typeof(App).Assembly">
2+
<Found Context="routeData">
3+
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
4+
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
5+
</Found>
6+
<NotFound>
7+
<PageTitle>Not found</PageTitle>
8+
<LayoutView Layout="@typeof(MainLayout)">
9+
<p role="alert">Sorry, there's nothing at this address.</p>
10+
</LayoutView>
11+
</NotFound>
12+
</Router>

0 commit comments

Comments
 (0)