Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
026469d
Sample Improvement (Part 2/2)
mckaragoz Feb 27, 2026
588da38
Identifier Normalization & Improved Exists Logic
mckaragoz Feb 27, 2026
77a11bc
Complete Identifier and Add New Tests
mckaragoz Feb 27, 2026
9218fa4
Complete Needed Identifier Logics & Improved PagedResult
mckaragoz Feb 27, 2026
b545078
Added Concurrency Support & Identifier Implementation
mckaragoz Feb 28, 2026
a395d72
Add & Fix Test
mckaragoz Feb 28, 2026
079181f
Added Session Concurrency
mckaragoz Feb 28, 2026
554cb9b
Improved Session Domains & Basic Device Id Binding
mckaragoz Feb 28, 2026
ebfe076
Improved Device Context Properties
mckaragoz Mar 1, 2026
a9a4412
Added State Clear on Current Chain Revoke
mckaragoz Mar 1, 2026
d458639
Credential Enhancement
mckaragoz Mar 2, 2026
342df09
Support Credential Level Lockout
mckaragoz Mar 2, 2026
1aafa3b
Complete Credential Change & Tests
mckaragoz Mar 3, 2026
3a2b793
Complete Credential Reset & Added Tests
mckaragoz Mar 4, 2026
012b85f
Added Generic InMemory Store and User Lifecycle Store Implementation
mckaragoz Mar 5, 2026
959f136
Completed User Create
mckaragoz Mar 5, 2026
031a9bc
Enhanced Authorization (RBAC)
mckaragoz Mar 8, 2026
25bf2bf
Authorization Completion & Tests
mckaragoz Mar 8, 2026
54016f7
Fixed Identifier Concurrency Test
mckaragoz Mar 8, 2026
032a0a5
Profile Dialog & UAuthClientEvents
mckaragoz Mar 8, 2026
da72d5e
User Self Deletion
mckaragoz Mar 8, 2026
2e826f7
Added Self User Status Change
mckaragoz Mar 9, 2026
5f2de3a
Complete Logout & Revoke Semantics & Added Tests
mckaragoz Mar 9, 2026
123876a
Home Page Design and ReauthRequired Raiese Event Test Fix
mckaragoz Mar 10, 2026
06925ee
Admin Role Crud Dialog & State Handling Mode Enhancement :)
mckaragoz Mar 10, 2026
8da7c1b
Permission Set Logic
mckaragoz Mar 11, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
1 change: 1 addition & 0 deletions UltimateAuth.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<Folder Name="/Tests/">
<Project Path="tests/CodeBeam.UltimateAuth.Tests.Unit/CodeBeam.UltimateAuth.Tests.Unit.csproj" Id="6f4b22da-849a-4a79-b5c5-aee7cb1429a6" />
</Folder>
<Project Path="src/authentication/CodeBeam.UltimateAuth.Authentication.InMemory/CodeBeam.UltimateAuth.Authentication.InMemory.csproj" Id="bd87e254-0565-4fc5-950d-ee5bbb416079" />
<Project Path="src/authorization/CodeBeam.UltimateAuth.Authorization.Contracts/CodeBeam.UltimateAuth.Authorization.Contracts.csproj" Id="40a23002-f885-42a8-bdd9-fd962ab28742" />
<Project Path="src/authorization/CodeBeam.UltimateAuth.Authorization.InMemory/CodeBeam.UltimateAuth.Authorization.InMemory.csproj" Id="a1e6d007-bdc0-4574-b549-ec863757edd3" />
<Project Path="src/authorization/CodeBeam.UltimateAuth.Authorization.Reference/CodeBeam.UltimateAuth.Authorization.Reference.csproj" Id="84b784d0-bb48-406a-a0d1-c600da667597" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\authentication\CodeBeam.UltimateAuth.Authentication.InMemory\CodeBeam.UltimateAuth.Authentication.InMemory.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization.InMemory\CodeBeam.UltimateAuth.Authorization.InMemory.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization.Reference\CodeBeam.UltimateAuth.Authorization.Reference.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization\CodeBeam.UltimateAuth.Authorization.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using CodeBeam.UltimateAuth.Authentication.InMemory;
using CodeBeam.UltimateAuth.Authorization.InMemory;
using CodeBeam.UltimateAuth.Authorization.InMemory.Extensions;
using CodeBeam.UltimateAuth.Authorization.Reference.Extensions;
Expand All @@ -8,8 +9,6 @@
using CodeBeam.UltimateAuth.Credentials.Reference;
using CodeBeam.UltimateAuth.Sample.UAuthHub.Components;
using CodeBeam.UltimateAuth.Security.Argon2;
using CodeBeam.UltimateAuth.Server.Authentication;
using CodeBeam.UltimateAuth.Server.Defaults;
using CodeBeam.UltimateAuth.Server.Extensions;
using CodeBeam.UltimateAuth.Sessions.InMemory;
using CodeBeam.UltimateAuth.Tokens.InMemory;
Expand Down Expand Up @@ -57,6 +56,7 @@
.AddUltimateAuthAuthorizationReference()
.AddUltimateAuthInMemorySessions()
.AddUltimateAuthInMemoryTokens()
.AddUltimateAuthInMemoryAuthenticationSecurity()
.AddUltimateAuthArgon2();

builder.Services.AddUltimateAuthClient(o =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\..\src\authentication\CodeBeam.UltimateAuth.Authentication.InMemory\CodeBeam.UltimateAuth.Authentication.InMemory.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization.InMemory\CodeBeam.UltimateAuth.Authorization.InMemory.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization.Reference\CodeBeam.UltimateAuth.Authorization.Reference.csproj" />
<ProjectReference Include="..\..\..\src\authorization\CodeBeam.UltimateAuth.Authorization\CodeBeam.UltimateAuth.Authorization.csproj" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<MudPage Class="mud-width-full" FullScreen="FullScreen.FullWithoutAppbar" Column="1" Row="1">
<MudContainer Class="mud-height-full" MaxWidth="MaxWidth.Small">
@ChildContent
</MudContainer>
</MudPage>

@code {
[Parameter]
public RenderFragment? ChildContent { get; set; }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
@using CodeBeam.UltimateAuth.Core.Contracts
@using CodeBeam.UltimateAuth.Users.Contracts
@inject IUAuthClient UAuthClient
@inject ISnackbar Snackbar
@inject IDialogService DialogService

<MudDialog Class="mud-width-full" ContentClass="uauth-dialog">
<TitleContent>
<MudText>Identifier Management</MudText>
<MudText Typo="Typo.subtitle2" Color="Color.Primary">User: @AuthState?.Identity?.DisplayName</MudText>
</TitleContent>
<DialogContent>
<MudStack Class="mud-width-full">
<MudButton Variant="Variant.Outlined" Color="Color.Primary" StartIcon="@Icons.Material.Filled.NearbyOff" OnClick="SuspendAccountAsync">
Suspend Account
</MudButton>

<MudButton Variant="Variant.Outlined" Color="Color.Error" StartIcon="@Icons.Material.Filled.Delete" OnClick="DeleteAccountAsync">
Delete Account
</MudButton>
</MudStack>
</DialogContent>
</MudDialog>

@code {
[CascadingParameter]
private IMudDialogInstance MudDialog { get; set; } = default!;

[Parameter]
public UAuthState AuthState { get; set; } = default!;

private async Task SuspendAccountAsync()
{
var info = await DialogService.ShowMessageBoxAsync(
title: "Are You Sure",
markupMessage: (MarkupString)
"""
You are going to suspend your account.<br/><br/>
You can still active your account later.
""",
yesText: "Suspend", noText: "Cancel",
options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" });

if (info != true)
{
Snackbar.Add("Suspend process cancelled", Severity.Info);
return;
}

ChangeUserStatusSelfRequest request = new() { NewStatus = SelfUserStatus.SelfSuspended };
var result = await UAuthClient.Users.ChangeStatusSelfAsync(request);
if (result.IsSuccess)
{
Snackbar.Add("Your account suspended successfully.", Severity.Success);
MudDialog.Close();
}
else
{
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Delete failed.", Severity.Error);
}
}

private async Task DeleteAccountAsync()
{
var info = await DialogService.ShowMessageBoxAsync(
title: "Are You Sure",
markupMessage: (MarkupString)
"""
You are going to delete your account.<br/><br/>
This action can't be undone.<br/><br/>
(Actually it is, admin can handle soft deleted accounts.)
""",
yesText: "Delete", noText: "Cancel",
options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" });

if (info != true)
{
Snackbar.Add("Deletion cancelled", Severity.Info);
return;
}

var result = await UAuthClient.Users.DeleteMeAsync();
if (result.IsSuccess)
{
Snackbar.Add("Your account deleted successfully.", Severity.Success);
MudDialog.Close();
}
else
{
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Delete failed.", Severity.Error);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
@using CodeBeam.UltimateAuth.Core.Contracts
@using CodeBeam.UltimateAuth.Credentials.Contracts
@using CodeBeam.UltimateAuth.Users.Contracts
@inject IUAuthClient UAuthClient
@inject ISnackbar Snackbar
@inject IDialogService DialogService
@inject IUAuthStateManager StateManager
@inject NavigationManager Nav

<MudDialog Class="mud-width-full" ContentClass="uauth-dialog">
<TitleContent>
<MudText>Credential Management</MudText>
<MudText Typo="Typo.subtitle2" Color="Color.Primary">User: @AuthState?.Identity?.DisplayName</MudText>
</TitleContent>
<DialogContent>
<MudForm @ref="@_form" OnEnterPressed="@ChangePasswordAsync">
<MudGrid Spacing="2">
<MudItem xs="12" sm="6">
<MudPasswordField @bind-Value="_oldPassword" @bind-PasswordMode="@_passwordMode1" Label="Old Password" Variant="Variant.Outlined" Immediate="true" Required="true" />
</MudItem>

<MudItem xs="12" sm="6">
<MudPasswordField @bind-Value="_newPassword" @bind-PasswordMode="@_passwordMode2" Label="New Password" Variant="Variant.Outlined" Immediate="true" Required="true" />
</MudItem>

<MudItem xs="12" sm="6">
<MudPasswordField @bind-Value="_newPasswordCheck" @bind-PasswordMode="@_passwordMode3" Label="New Password (Again)" Variant="Variant.Outlined" Immediate="true" Required="true" Validation="@(new Func<string, string>(PasswordMatch))" />
</MudItem>

<MudItem xs="12">
<MudButton Color="Color.Primary" Variant="Variant.Filled" OnClick="ChangePasswordAsync">Change Password</MudButton>
</MudItem>
</MudGrid>
</MudForm>
</DialogContent>
<DialogActions>
<MudButton OnClick="Cancel">Cancel</MudButton>
<MudButton Color="Color.Primary" OnClick="Submit">OK</MudButton>
</DialogActions>
</MudDialog>

@code {
private MudForm _form = null!;
private string? _oldPassword;
private string? _newPassword;
private string? _newPasswordCheck;
private bool _passwordMode1 = false;
private bool _passwordMode2 = false;
private bool _passwordMode3 = true;

[CascadingParameter]
private IMudDialogInstance MudDialog { get; set; } = default!;

[Parameter]
public UAuthState AuthState { get; set; } = default!;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);

if (firstRender)
{

}
}

private async Task ChangePasswordAsync()
{
if (_form is null)
return;

await _form.Validate();
if (!_form.IsValid)
{
Snackbar.Add("Form is not valid.", Severity.Error);
return;
}

if (_newPassword != _newPasswordCheck)
{
Snackbar.Add("New password and check do not match", Severity.Error);
return;
}

ChangeCredentialRequest request = new ChangeCredentialRequest
{
CurrentSecret = _oldPassword!,
NewSecret = _newPassword!,
};

var result = await UAuthClient.Credentials.ChangeMyAsync(request);
if (result.IsSuccess)
{
Snackbar.Add("Password changed successfully", Severity.Success);
// Logout also if you want. Password change only revoke other open sessions, not the current one.
// await UAuthClient.Flows.LogoutAsync();
}
else
{
Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "An error occurred while changing password", Severity.Error);
}
}

private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty;

private void Submit() => MudDialog.Close(DialogResult.Ok(true));

private void Cancel() => MudDialog.Cancel();
}
Loading
Loading