From 3bbbb88e61796217aa2246d584b7e553baf58ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Wed, 14 Oct 2026 20:54:34 +0300 Subject: [PATCH 1/8] Add Shared Sample Project and Remove Sample Code Duplication --- UltimateAuth.slnx | 1 + ...eBeam.UltimateAuth.Docs.Wasm.Client.csproj | 8 +- .../CodeBeam.UltimateAuth.Docs.Wasm.csproj | 2 +- ...CodeBeam.UltimateAuth.Sample.Shared.csproj | 25 ++ .../Common/UAuthDialog.cs | 29 ++ .../Dialogs/AccountStatusDialog.razor | 0 .../Dialogs/AccountStatusDialog.razor.cs | 2 +- .../Dialogs/CreateUserDialog.razor | 4 +- .../Dialogs/CreateUserDialog.razor.cs | 2 +- .../Dialogs/CredentialDialog.razor | 0 .../Dialogs/CredentialDialog.razor.cs | 2 +- .../Dialogs/IdentifierDialog.razor | 0 .../Dialogs/IdentifierDialog.razor.cs | 2 +- .../Dialogs/PermissionDialog.razor | 0 .../Dialogs/PermissionDialog.razor.cs | 2 +- .../Dialogs/ProfileDialog.razor | 0 .../Dialogs/ProfileDialog.razor.cs | 2 +- .../Dialogs/ResetDialog.razor | 0 .../Dialogs/ResetDialog.razor.cs | 2 +- .../Dialogs/RoleDialog.razor | 0 .../Dialogs/RoleDialog.razor.cs | 2 +- .../Dialogs/SessionDialog.razor | 1 - .../Dialogs/SessionDialog.razor.cs | 2 +- .../Dialogs/UserDetailDialog.razor | 4 +- .../Dialogs/UserDetailDialog.razor.cs | 4 +- .../Dialogs/UserRoleDialog.razor | 0 .../Dialogs/UserRoleDialog.razor.cs | 2 +- .../Dialogs/UsersDialog.razor | 1 - .../Dialogs/UsersDialog.razor.cs | 4 +- .../_Imports.razor | 11 + .../wwwroot/background.png | Bin 0 -> 378 bytes .../wwwroot/exampleJsInterop.js | 6 + ...UltimateAuth.Sample.UAuthHub.EFCore.csproj | 3 +- ...deBeam.UltimateAuth.Sample.UAuthHub.csproj | 3 +- ...mateAuth.Sample.BlazorServer.EFCore.csproj | 3 +- .../Dialogs/AccountStatusDialog.razor.cs | 77 ----- .../Components/Dialogs/CreateUserDialog.razor | 27 -- .../Dialogs/CreateUserDialog.razor.cs | 55 ---- .../Dialogs/CredentialDialog.razor.cs | 92 ------ .../Dialogs/IdentifierDialog.razor.cs | 309 ----------------- .../Dialogs/PermissionDialog.razor.cs | 120 ------- .../Components/Dialogs/ProfileDialog.razor | 94 ------ .../Components/Dialogs/ProfileDialog.razor.cs | 114 ------- .../Components/Dialogs/ResetDialog.razor | 37 --- .../Components/Dialogs/ResetDialog.razor.cs | 40 --- .../Components/Dialogs/RoleDialog.razor.cs | 164 --------- .../Components/Dialogs/SessionDialog.razor | 217 ------------ .../Components/Dialogs/SessionDialog.razor.cs | 284 ---------------- .../Components/Dialogs/UserDetailDialog.razor | 75 ----- .../Dialogs/UserDetailDialog.razor.cs | 100 ------ .../Dialogs/UserRoleDialog.razor.cs | 124 ------- .../Components/Dialogs/UsersDialog.razor | 85 ----- .../Components/Dialogs/UsersDialog.razor.cs | 176 ---------- .../Components/Pages/Home.razor.cs | 2 +- .../Components/Pages/Login.razor.cs | 2 +- ...am.UltimateAuth.Sample.BlazorServer.csproj | 3 +- .../Dialogs/AccountStatusDialog.razor | 23 -- .../Dialogs/AccountStatusDialog.razor.cs | 77 ----- .../Components/Dialogs/CreateUserDialog.razor | 27 -- .../Dialogs/CreateUserDialog.razor.cs | 55 ---- .../Components/Dialogs/CredentialDialog.razor | 51 --- .../Dialogs/CredentialDialog.razor.cs | 92 ------ .../Components/Dialogs/IdentifierDialog.razor | 106 ------ .../Components/Dialogs/PermissionDialog.razor | 46 --- .../Dialogs/PermissionDialog.razor.cs | 120 ------- .../Components/Dialogs/ResetDialog.razor.cs | 40 --- .../Components/Dialogs/RoleDialog.razor | 81 ----- .../Components/Dialogs/UserDetailDialog.razor | 75 ----- .../Components/Dialogs/UserRoleDialog.razor | 49 --- .../Dialogs/UserRoleDialog.razor.cs | 124 ------- .../Components/Pages/Home.razor.cs | 2 +- .../Components/Pages/Login.razor.cs | 2 +- ...ateAuth.Sample.BlazorStandaloneWasm.csproj | 3 +- .../Dialogs/AccountStatusDialog.razor | 23 -- .../Dialogs/AccountStatusDialog.razor.cs | 77 ----- .../Dialogs/CreateUserDialog.razor.cs | 55 ---- .../Components/Dialogs/CredentialDialog.razor | 51 --- .../Dialogs/CredentialDialog.razor.cs | 92 ------ .../Components/Dialogs/IdentifierDialog.razor | 115 ------- .../Dialogs/IdentifierDialog.razor.cs | 311 ------------------ .../Components/Dialogs/PermissionDialog.razor | 46 --- .../Dialogs/PermissionDialog.razor.cs | 120 ------- .../Components/Dialogs/ProfileDialog.razor | 103 ------ .../Components/Dialogs/ProfileDialog.razor.cs | 116 ------- .../Components/Dialogs/ResetDialog.razor | 37 --- .../Components/Dialogs/ResetDialog.razor.cs | 40 --- .../Components/Dialogs/RoleDialog.razor | 90 ----- .../Components/Dialogs/RoleDialog.razor.cs | 176 ---------- .../Components/Dialogs/SessionDialog.razor | 226 ------------- .../Components/Dialogs/SessionDialog.razor.cs | 286 ---------------- .../Components/Dialogs/UserDetailDialog.razor | 75 ----- .../Dialogs/UserDetailDialog.razor.cs | 100 ------ .../Components/Dialogs/UserRoleDialog.razor | 49 --- .../Dialogs/UserRoleDialog.razor.cs | 124 ------- .../Components/Dialogs/UsersDialog.razor | 94 ------ .../Components/Dialogs/UsersDialog.razor.cs | 188 ----------- .../Pages/Home.razor.cs | 1 + .../Pages/Login.razor.cs | 1 + ...odeBeam.UAuth.Sample.IntWasm.Client.csproj | 7 +- .../Dialogs/AccountStatusDialog.razor | 23 -- .../Components/Dialogs/CreateUserDialog.razor | 27 -- .../Components/Dialogs/CredentialDialog.razor | 51 --- .../Components/Dialogs/IdentifierDialog.razor | 115 ------- .../Dialogs/IdentifierDialog.razor.cs | 311 ------------------ .../Components/Dialogs/PermissionDialog.razor | 46 --- .../Components/Dialogs/ProfileDialog.razor | 103 ------ .../Components/Dialogs/ProfileDialog.razor.cs | 116 ------- .../Components/Dialogs/ResetDialog.razor | 37 --- .../Components/Dialogs/RoleDialog.razor | 90 ----- .../Components/Dialogs/RoleDialog.razor.cs | 176 ---------- .../Components/Dialogs/SessionDialog.razor | 226 ------------- .../Components/Dialogs/SessionDialog.razor.cs | 286 ---------------- .../Dialogs/UserDetailDialog.razor.cs | 100 ------ .../Components/Dialogs/UserRoleDialog.razor | 49 --- .../Components/Dialogs/UsersDialog.razor | 94 ------ .../Components/Dialogs/UsersDialog.razor.cs | 188 ----------- .../Pages/Home.razor.cs | 3 +- .../Pages/Login.razor.cs | 5 +- .../CodeBeam.UAuth.Sample.IntWasm.csproj | 2 +- ...imateAuth.Sample.ResourceApi.EfCore.csproj | 1 + 120 files changed, 113 insertions(+), 7838 deletions(-) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Common/UAuthDialog.cs rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/AccountStatusDialog.razor (100%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/AccountStatusDialog.razor.cs (97%) rename samples/{blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/CreateUserDialog.razor (90%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/CreateUserDialog.razor.cs (95%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/CredentialDialog.razor (100%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/CredentialDialog.razor.cs (97%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/IdentifierDialog.razor (100%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/IdentifierDialog.razor.cs (99%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/PermissionDialog.razor (100%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/PermissionDialog.razor.cs (98%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ProfileDialog.razor (100%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ProfileDialog.razor.cs (97%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ResetDialog.razor (100%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ResetDialog.razor.cs (94%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/RoleDialog.razor (100%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/RoleDialog.razor.cs (98%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/SessionDialog.razor (99%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/SessionDialog.razor.cs (99%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UserDetailDialog.razor (96%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UserDetailDialog.razor.cs (95%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UserRoleDialog.razor (100%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UserRoleDialog.razor.cs (98%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UsersDialog.razor (98%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/UsersDialog.razor.cs (97%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/_Imports.razor create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/background.png create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor.cs diff --git a/UltimateAuth.slnx b/UltimateAuth.slnx index 5f659632..751ea927 100644 --- a/UltimateAuth.slnx +++ b/UltimateAuth.slnx @@ -13,6 +13,7 @@ + diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/CodeBeam.UltimateAuth.Docs.Wasm.Client.csproj b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/CodeBeam.UltimateAuth.Docs.Wasm.Client.csproj index 3e3e1fb5..69a55d41 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/CodeBeam.UltimateAuth.Docs.Wasm.Client.csproj +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/CodeBeam.UltimateAuth.Docs.Wasm.Client.csproj @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.csproj b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.csproj index 300b60ef..be947b19 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.csproj +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.csproj @@ -10,7 +10,7 @@ - + diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj new file mode 100644 index 00000000..22d39e8b --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj @@ -0,0 +1,25 @@ + + + + net10.0 + enable + enable + false + + + + + + + + + + + + + + + + + + diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Common/UAuthDialog.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Common/UAuthDialog.cs new file mode 100644 index 00000000..8e16bbe6 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Common/UAuthDialog.cs @@ -0,0 +1,29 @@ +using CodeBeam.UltimateAuth.Client; +using CodeBeam.UltimateAuth.Core.Domain; +using MudBlazor; + +namespace CodeBeam.UltimateAuth.Sample.Shared.Common; + +public static class UAuthDialog +{ + public static DialogParameters GetDialogParameters(UAuthState state, UserKey? userKey = null) + { + DialogParameters parameters = new DialogParameters(); + parameters.Add("AuthState", state); + if (userKey != null ) + { + parameters.Add("UserKey", userKey); + } + return parameters; + } + + public static DialogOptions GetDialogOptions(MaxWidth maxWidth = MaxWidth.Medium) + { + return new DialogOptions + { + MaxWidth = maxWidth, + FullWidth = true, + CloseButton = true + }; + } +} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs similarity index 97% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs index d5652e62..a2dcc718 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class AccountStatusDialog { diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor similarity index 90% rename from samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor index 9a514935..20127849 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor @@ -1,6 +1,4 @@ -@using CodeBeam.UltimateAuth.Credentials.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient +@inject IUAuthClient UAuthClient @inject ISnackbar Snackbar diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs similarity index 95% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs index d96ee282..9b5b3b8e 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class CreateUserDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs similarity index 97% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs index fa3f8117..68ac8a0e 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class CredentialDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs similarity index 99% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs index 77d8e254..ebba43ec 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class IdentifierDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs similarity index 98% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs index b6b03bb8..615b4b68 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class PermissionDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ProfileDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ProfileDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ProfileDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs similarity index 97% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ProfileDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs index 43b08720..7dfa0f58 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ProfileDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class ProfileDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs similarity index 94% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs index 349f56ff..962b7297 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class ResetDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs similarity index 98% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs index 453acb8c..cfb78161 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class RoleDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor similarity index 99% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor index 8ecf2a15..efba51c4 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor @@ -1,5 +1,4 @@ @using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts @inject IUAuthClient UAuthClient @inject ISnackbar Snackbar @inject IDialogService DialogService diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs similarity index 99% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs index 17af4337..ee4b392f 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/SessionDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class SessionDialog { diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor similarity index 96% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor index 39053d5e..97631deb 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor @@ -1,6 +1,4 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UAuth.Sample.IntWasm.Client.Common -@using CodeBeam.UltimateAuth.Users.Contracts +@using CodeBeam.UltimateAuth.Users.Contracts @inject IUAuthClient UAuthClient @inject IDialogService DialogService @inject ISnackbar Snackbar diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs similarity index 95% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs index 7228a3d2..9eb1e498 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs @@ -1,12 +1,12 @@ using CodeBeam.UltimateAuth.Client; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Common; +using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class UserDetailDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs similarity index 98% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs index b167d6db..0f078f48 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class UserRoleDialog { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor similarity index 98% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor index bf19af4e..66c8e887 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor @@ -1,5 +1,4 @@ @using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorServer.Common @using CodeBeam.UltimateAuth.Users.Contracts @inject IUAuthClient UAuthClient @inject IDialogService DialogService diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs similarity index 97% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs index 5d184fe7..4550ad3a 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UsersDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs @@ -1,12 +1,12 @@ using CodeBeam.UltimateAuth.Client; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Common; +using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class UsersDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/_Imports.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/_Imports.razor new file mode 100644 index 00000000..7309978c --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/_Imports.razor @@ -0,0 +1,11 @@ +@using Microsoft.AspNetCore.Components.Web + +@using CodeBeam.UltimateAuth.Core.Abstractions +@using CodeBeam.UltimateAuth.Core.Domain +@using CodeBeam.UltimateAuth.Client +@using CodeBeam.UltimateAuth.Client.Runtime +@using CodeBeam.UltimateAuth.Client.Diagnostics +@using CodeBeam.UltimateAuth.Client.Blazor + +@using MudBlazor +@using MudExtensions diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/background.png b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/background.png new file mode 100644 index 0000000000000000000000000000000000000000..e15a3bde6e2bdb380df6a0b46d7ed00bdeb0aaa8 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK1SGdsl%54rjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucLCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33 zJwr2>%=KS^ie7oTIEF;HpS|GCbyPusHSqiXaCu3qf)82(9Gq&mZq2{Kq}M*X&MWtJ zSi1Jo7ZzfImg%g=t(qo=wsSR2lZoP(Rj#3wacN=q0?Br(rXzgZEGK2$ID{|A=5S{xJEuzSH>!M+7wSY6hB<=-E^*n0W7 S8wY^CX7F_Nb6Mw<&;$S{dxtsz literal 0 HcmV?d00001 diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js new file mode 100644 index 00000000..ea8d76ad --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js @@ -0,0 +1,6 @@ +// This is a JavaScript module that is loaded on demand. It can export any number of +// functions, and may import other JavaScript modules if required. + +export function showPrompt(message) { + return prompt(message, 'Type anything here'); +} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj index 3bf1515b..a0aba4c9 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj @@ -9,7 +9,6 @@ - all @@ -20,7 +19,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - @@ -29,6 +27,7 @@ + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj index 5e9e2eee..361680e0 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj @@ -9,9 +9,7 @@ - - @@ -21,6 +19,7 @@ + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.csproj b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.csproj index 98b4e775..9f0beb00 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.csproj +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.csproj @@ -19,8 +19,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - @@ -28,6 +26,7 @@ + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor.cs deleted file mode 100644 index 195f1fbd..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/AccountStatusDialog.razor.cs +++ /dev/null @@ -1,77 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class AccountStatusDialog -{ - [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.

- 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 = SelfAssignableUserStatus.SelfSuspended }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("Your account suspended successfully.", Severity.Success); - MudDialog.Close(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "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.

- This action can't be undone.

- (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?.ErrorText ?? "Delete failed.", Severity.Error); - } - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor deleted file mode 100644 index 9a514935..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor +++ /dev/null @@ -1,27 +0,0 @@ -@using CodeBeam.UltimateAuth.Credentials.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Create User - - - - - - - - - - - - - - - - Cancel - Create - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor.cs deleted file mode 100644 index a06a2acd..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CreateUserDialog.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class CreateUserDialog -{ - private MudForm _form = null!; - private string? _username; - private string? _email; - private string? _password; - private string? _passwordCheck; - private string? _displayName; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - private async Task CreateUserAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - if (_password != _passwordCheck) - { - Snackbar.Add("Passwords don't match.", Severity.Error); - return; - } - - var request = new CreateUserRequest - { - UserName = _username, - Email = _email, - DisplayName = _displayName, - Password = _password - }; - - var result = await UAuthClient.Users.CreateAsAdminAsync(request); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "User creation failed.", Severity.Error); - return; - } - - Snackbar.Add("User created successfully", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - - private string PasswordMatch(string? arg) => _password != arg ? "Passwords don't match." : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor.cs deleted file mode 100644 index 13b4f69f..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/CredentialDialog.razor.cs +++ /dev/null @@ -1,92 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class CredentialDialog -{ - 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!; - - [Parameter] - public UserKey? UserKey { get; set; } - - private async Task ChangePasswordAsync() - { - if (_form is null) - return; - - await _form.ValidateAsync(); - 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; - - if (UserKey is null) - { - request = new ChangeCredentialRequest - { - CurrentSecret = _oldPassword!, - NewSecret = _newPassword! - }; - } - else - { - request = new ChangeCredentialRequest - { - NewSecret = _newPassword! - }; - } - - UAuthResult result; - if (UserKey is null) - { - result = await UAuthClient.Credentials.ChangeMyAsync(request); - } - else - { - result = await UAuthClient.Credentials.ChangeUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Password changed successfully", Severity.Success); - _oldPassword = null; - _newPassword = null; - _newPasswordCheck = null; - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "An error occurred while changing password", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor.cs deleted file mode 100644 index 67a76cff..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/IdentifierDialog.razor.cs +++ /dev/null @@ -1,309 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class IdentifierDialog -{ - private MudDataGrid? _grid; - private UserIdentifierType _newIdentifierType; - private string? _newIdentifierValue; - private bool _newIdentifierPrimary; - private bool _loading = false; - private bool _reloadQueued; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - var result = await UAuthClient.Identifiers.GetMyAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - StateHasChanged(); - } - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Identifiers.GetMyAsync(req); - } - else - { - res = await UAuthClient.Identifiers.GetUserAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task CommittedItemChanges(UserIdentifierInfo item) - { - UpdateUserIdentifierRequest updateRequest = new() - { - Id = item.Id, - NewValue = item.Value - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UpdateMyAsync(updateRequest); - } - else - { - result = await UAuthClient.Identifiers.UpdateUserAsync(UserKey.Value, updateRequest); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier updated successfully.", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to update identifier.", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task AddNewIdentifier() - { - if (string.IsNullOrEmpty(_newIdentifierValue)) - { - Snackbar.Add("Value cannot be empty", Severity.Warning); - return; - } - - AddUserIdentifierRequest request = new() - { - Type = _newIdentifierType, - Value = _newIdentifierValue, - IsPrimary = _newIdentifierPrimary - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.AddMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.AddUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier added successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to add identifier.", Severity.Error); - } - } - - private async Task VerifyAsync(Guid id) - { - var demoInfo = await DialogService.ShowMessageBoxAsync( - title: "Demo Verification", - markupMessage: (MarkupString) - """ - This is a demo action.

- In a real app, you should verify identifiers via Email, SMS, or an Authenticator flow. - This will only mark the identifier as verified in UltimateAuth. - """, - yesText: "Verify", noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (demoInfo != true) - { - Snackbar.Add("Verification cancelled", Severity.Info); - return; - } - - VerifyUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.VerifyMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.VerifyUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier verified successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to verify primary identifier.", Severity.Error); - } - } - - private async Task SetPrimaryAsync(Guid id) - { - SetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.SetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.SetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier set successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to set primary identifier.", Severity.Error); - } - } - - private async Task UnsetPrimaryAsync(Guid id) - { - UnsetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UnsetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.UnsetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier unset successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to unset primary identifier.", Severity.Error); - } - } - - private async Task DeleteIdentifier(Guid id) - { - DeleteUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.DeleteMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.DeleteUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier deleted successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to delete identifier.", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor.cs deleted file mode 100644 index 0e755f76..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/PermissionDialog.razor.cs +++ /dev/null @@ -1,120 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class PermissionDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public RoleInfo Role { get; set; } = default!; - - private List _groups = new(); - - protected override void OnInitialized() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - _groups = catalog - .GroupBy(p => p.Split('.')[0]) - .Select(g => new PermissionGroup - { - Name = g.Key, - Items = g.Select(p => new PermissionItem - { - Value = p, - Selected = selected.Contains(p) - }).ToList() - }) - .OrderBy(x => x.Name) - .ToList(); - } - - private void ToggleGroup(PermissionGroup group, bool value) - { - foreach (var item in group.Items) - item.Selected = value; - } - - private void TogglePermission(PermissionItem item, bool value) - { - item.Selected = value; - } - - private bool? GetGroupState(PermissionGroup group) - { - var selected = group.Items.Count(x => x.Selected); - - if (selected == 0) - return false; - - if (selected == group.Items.Count) - return true; - - return null; - } - - private async Task Save() - { - var permissions = _groups.SelectMany(g => g.Items).Where(x => x.Selected).Select(x => Permission.From(x.Value)).ToList(); - - var req = new SetRolePermissionsRequest - { - RoleId = Role.Id, - Permissions = permissions - }; - - var result = await UAuthClient.Authorization.SetRolePermissionsAsync(req); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "Failed to update permissions", Severity.Error); - return; - } - - var result2 = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery() { Search = Role.Name }); - if (result2.Value?.Items is not null) - { - Role = result2.Value.Items.First(); - } - - Snackbar.Add("Permissions updated", Severity.Success); - RefreshUI(); - } - - private void RefreshUI() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - foreach (var group in _groups) - { - foreach (var item in group.Items) - { - item.Selected = selected.Contains(item.Value); - } - } - - StateHasChanged(); - } - - private void Cancel() => MudDialog.Cancel(); - - private class PermissionGroup - { - public string Name { get; set; } = ""; - public List Items { get; set; } = new(); - } - - private class PermissionItem - { - public string Value { get; set; } = ""; - public bool Selected { get; set; } - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor deleted file mode 100644 index d09fcfa0..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor +++ /dev/null @@ -1,94 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - - - - - - Name - - - - - - - - - - - - - - - - - - - Personal - - - - - - - - - - - - - - - - - - - Localization - - - - - - - - - - - @foreach (var tz in TimeZoneInfo.GetSystemTimeZones()) - { - @tz.Id - @tz.DisplayName - } - - - - - - - - - - - - Cancel - Save - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor.cs deleted file mode 100644 index 0ce2be6f..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ProfileDialog.razor.cs +++ /dev/null @@ -1,114 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class ProfileDialog -{ - private MudForm? _form; - private string? _firstName; - private string? _lastName; - private string? _displayName; - private DateTime? _birthDate; - private string? _gender; - private string? _bio; - private string? _language; - private string? _timeZone; - private string? _culture; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.GetMeAsync(); - } - else - { - result = await UAuthClient.Users.GetUserAsync(UserKey.Value); - } - - if (result.IsSuccess && result.Value is not null) - { - var p = result.Value; - - _firstName = p.FirstName; - _lastName = p.LastName; - _displayName = p.DisplayName; - - _gender = p.Gender; - _birthDate = p.BirthDate?.ToDateTime(TimeOnly.MinValue); - _bio = p.Bio; - - _language = p.Language; - _timeZone = p.TimeZone; - _culture = p.Culture; - } - } - - private async Task SaveAsync() - { - if (AuthState is null || AuthState.Identity is null) - { - Snackbar.Add("No AuthState found.", Severity.Error); - return; - } - - if (_form is not null) - { - await _form.ValidateAsync(); - if (!_form.IsValid) - return; - } - - var request = new UpdateProfileRequest - { - FirstName = _firstName, - LastName = _lastName, - DisplayName = _displayName, - BirthDate = _birthDate.HasValue ? DateOnly.FromDateTime(_birthDate.Value) : null, - Gender = _gender, - Bio = _bio, - Language = _language, - TimeZone = _timeZone, - Culture = _culture - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.UpdateMyProfileAsync(request); - } - else - { - result = await UAuthClient.Users.UpdateUserProfileAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Profile updated", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to update profile", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor deleted file mode 100644 index 8d4c90d3..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor +++ /dev/null @@ -1,37 +0,0 @@ -@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 - - - - Reset Credential - - - - - - This is a demonstration of how to implement a credential reset flow. - In a production application, you should use reset token or code in email, SMS etc. verification steps. - - - Reset request always returns ok even with not found users due to security reasons. - - - Request Reset - @if (_resetRequested) - { - Your reset code is on the server console. - Use Reset Code - } - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor.cs deleted file mode 100644 index 25c068f0..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/ResetDialog.razor.cs +++ /dev/null @@ -1,40 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class ResetDialog -{ - private bool _resetRequested = false; - private string? _identifier; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private async Task RequestResetAsync() - { - var request = new BeginResetCredentialRequest - { - CredentialType = CredentialType.Password, - ResetCodeType = ResetCodeType.Code, - Identifier = _identifier ?? string.Empty - }; - - var result = await UAuthClient.Credentials.BeginResetAsync(request); - if (!result.IsSuccess || result.Value is null) - { - Snackbar.Add(result.ErrorText ?? "Failed to request credential reset.", Severity.Error); - return; - } - - _resetRequested = true; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor.cs deleted file mode 100644 index 931687d8..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/RoleDialog.razor.cs +++ /dev/null @@ -1,164 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class RoleDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _newRoleName; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new RoleQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Authorization.QueryRolesAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task CommittedItemChanges(RoleInfo role) - { - var req = new RenameRoleRequest - { - Id = role.Id, - Name = role.Name - }; - - var result = await UAuthClient.Authorization.RenameRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add("Role renamed", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Rename failed", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task CreateRole() - { - if (string.IsNullOrWhiteSpace(_newRoleName)) - { - Snackbar.Add("Role name required.", Severity.Warning); - return; - } - - var req = new CreateRoleRequest - { - Name = _newRoleName - }; - - var res = await UAuthClient.Authorization.CreateRoleAsync(req); - - if (res.IsSuccess) - { - Snackbar.Add("Role created.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(res.ErrorText ?? "Creation failed.", Severity.Error); - } - } - - private async Task DeleteRole(RoleId roleId) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Delete role", - "Are you sure?", - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - return; - - var req = new DeleteRoleRequest() { Id = roleId }; - var result = await UAuthClient.Authorization.DeleteRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add($"Role deleted, assignments removed from {result.Value?.RemovedAssignments.ToString() ?? "unknown"} users.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Deletion failed.", Severity.Error); - } - } - - private async Task EditPermissions(RoleInfo role) - { - var dialog = await DialogService.ShowAsync( - "Edit Permissions", - new DialogParameters - { - { nameof(PermissionDialog.Role), role } - }, - new DialogOptions - { - CloseButton = true, - MaxWidth = MaxWidth.Large, - FullWidth = true - }); - - var result = await dialog.Result; - await ReloadAsync(); - } - - private async Task ReloadAsync() - { - _loading = true; - await Task.Delay(300); - if (_grid is null) - return; - - await _grid.ReloadServerData(); - _loading = false; - } - - private int GetPermissionCount(RoleInfo role) - { - var expanded = PermissionExpander.Expand(role.Permissions, UAuthPermissionCatalog.GetAdminPermissions()); - return expanded.Count; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor deleted file mode 100644 index 8ecf2a15..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor +++ /dev/null @@ -1,217 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@inject IUAuthStateManager StateManager -@inject NavigationManager Nav - - - - Session Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_chainDetail is not null) - { - - - - Device Details - - - - @if (!_chainDetail.IsRevoked) - { - - Revoke Device - - } - - - - - - - Device Type - @_chainDetail.DeviceType - - - - Platform - @_chainDetail.Platform - - - - Operating System - @_chainDetail.OperatingSystem - - - - Browser - @_chainDetail.Browser - - - - Created - @_chainDetail.CreatedAt.ToLocalTime() - - - - Last Seen - @_chainDetail.LastSeenAt.ToLocalTime() - - - - State - - @_chainDetail.State - - - - - Active Session - @_chainDetail.ActiveSessionId - - - - Rotation Count - @_chainDetail.RotationCount - - - - Touch Count - @_chainDetail.TouchCount - - - - - - Session History - - - - Session Id - Created - Expires - Status - - - - @context.SessionId - @context.CreatedAt.ToLocalTime() - @context.ExpiresAt.ToLocalTime() - - @if (context.IsRevoked) - { - Revoked - } - else - { - Active - } - - - - - } - else - { - - Logout All Devices - @if (UserKey == null) - { - Logout Other Devices - } - Revoke All Devices - @if (UserKey == null) - { - Revoke Other Devices - } - - - - Sessions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.ChainId - - - - Created At - @context.Item.CreatedAt - - - - Touch Count - @context.Item.TouchCount - - - - Rotation Count - @context.Item.RotationCount - - - - - - - - - } - - - Cancel - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor.cs deleted file mode 100644 index fb86d0cf..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/SessionDialog.razor.cs +++ /dev/null @@ -1,284 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class SessionDialog -{ - private MudDataGrid? _grid; - private bool _loading = false; - private bool _reloadQueued; - private SessionChainDetail? _chainDetail; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - var result = await UAuthClient.Sessions.GetMyChainsAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - StateHasChanged(); - } - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Sessions.GetMyChainsAsync(req); - } - else - { - res = await UAuthClient.Sessions.GetUserChainsAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task LogoutAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutAllMyDevicesAsync(); - } - else - { - result = await UAuthClient.Flows.LogoutAllUserDevicesAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task LogoutOthersAsync() - { - var result = await UAuthClient.Flows.LogoutMyOtherDevicesAsync(); - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of other devices.", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout", Severity.Error); - } - } - - private async Task LogoutDeviceAsync(SessionChainId chainId) - { - LogoutDeviceRequest request = new() { ChainId = chainId }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutMyDeviceAsync(request); - } - else - { - result = await UAuthClient.Flows.LogoutUserDeviceAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of device.", Severity.Success); - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeAllMyChainsAsync(); - } - else - { - result = await UAuthClient.Sessions.RevokeAllUserChainsAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeOthersAsync() - { - var result = await UAuthClient.Sessions.RevokeMyOtherChainsAsync(); - if (result.IsSuccess) - { - Snackbar.Add("Revoked all other devices.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeChainAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeMyChainAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.RevokeUserChainAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - Snackbar.Add("Device revoked successfully.", Severity.Success); - - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task ShowChainDetailsAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.GetMyChainDetailAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.GetUserChainDetailAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - _chainDetail = result.Value; - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to fetch chain details.", Severity.Error); - _chainDetail = null; - } - } - - private void ClearDetail() - { - _chainDetail = null; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor deleted file mode 100644 index 73fafa48..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor +++ /dev/null @@ -1,75 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - @_user?.UserKey.Value - - - - - - - - Display Name - @_user?.DisplayName - - - - Username - @_user?.UserName - - - - Email - @_user?.PrimaryEmail - - - - Phone - @_user?.PrimaryPhone - - - - Created - @_user?.CreatedAt?.ToLocalTime() - - - - Status - @_user?.Status - - - @foreach (var s in Enum.GetValues()) - { - @s - } - - Change - - - - - - - - Management - - Sessions - Profile - Identifiers - Credentials - Roles - - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor.cs deleted file mode 100644 index 8a1a76a3..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserDetailDialog.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class UserDetailDialog -{ - private UserView? _user; - private AdminAssignableUserStatus _status; - - [CascadingParameter] - IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - var result = await UAuthClient.Users.GetUserAsync(UserKey); - - if (result.IsSuccess) - { - _user = result.Value; - _status = _user?.Status.ToAdminAssignableUserStatus() ?? AdminAssignableUserStatus.Unknown; - } - } - - private async Task OpenSessions() - { - await DialogService.ShowAsync("Session Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenProfile() - { - await DialogService.ShowAsync("Profile Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifiers() - { - await DialogService.ShowAsync("Identifier Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentials() - { - await DialogService.ShowAsync("Credentials", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenRoles() - { - await DialogService.ShowAsync("Roles", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task ChangeStatusAsync() - { - if (_user is null) - return; - - ChangeUserStatusAdminRequest request = new() - { - NewStatus = _status - }; - - var result = await UAuthClient.Users.ChangeUserStatusAsync(_user.UserKey, request); - - if (result.IsSuccess) - { - Snackbar.Add("User status updated", Severity.Success); - _user = _user with { Status = _status.ToUserStatus() }; - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private Color GetStatusColor(UserStatus? status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor.cs deleted file mode 100644 index b1693a25..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UserRoleDialog.razor.cs +++ /dev/null @@ -1,124 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class UserRoleDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } = default!; - - private List _roles = new(); - private List _allRoles = new(); - - private string? _selectedRole; - - protected override async Task OnInitializedAsync() - { - await LoadRoles(); - } - - private async Task LoadRoles() - { - var userRoles = await UAuthClient.Authorization.GetUserRolesAsync(UserKey); - - if (userRoles.IsSuccess && userRoles.Value != null) - _roles = userRoles.Value.Roles.Items.Select(x => x.Name).ToList(); - - var roles = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery - { - PageNumber = 1, - PageSize = 200 - }); - - if (roles.IsSuccess && roles.Value != null) - _allRoles = roles.Value.Items.ToList(); - } - - private async Task AddRole() - { - if (string.IsNullOrWhiteSpace(_selectedRole)) - return; - - var request = new AssignRoleRequest - { - UserKey = UserKey, - RoleName = _selectedRole - }; - - var result = await UAuthClient.Authorization.AssignRoleToUserAsync(request); - - if (result.IsSuccess) - { - _roles.Add(_selectedRole); - Snackbar.Add("Role assigned", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - - _selectedRole = null; - } - - private async Task RemoveRole(string role) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Remove Role", - $"Remove {role} from user?", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - - if (role == "Admin") - { - var confirm2 = await DialogService.ShowMessageBoxAsync( - "Are You Sure", - "You are going to remove admin role. This action may cause the application unuseable.", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm2 != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - } - - var request = new RemoveRoleRequest - { - UserKey = UserKey, - RoleName = role - }; - - var result = await UAuthClient.Authorization.RemoveRoleFromUserAsync(request); - - if (result.IsSuccess) - { - _roles.Remove(role); - Snackbar.Add("Role removed.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private void Close() => MudDialog.Close(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor deleted file mode 100644 index 5fba5e4c..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor +++ /dev/null @@ -1,85 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - Browse, create and manage users - - - - - - - - - - - - - - - - - Users - - New User - - - - - - - - - - - @context.Item.Status - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.UserKey.Value - - - - Created At - @context.Item.CreatedAt - - - - - - - - - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor.cs deleted file mode 100644 index 3f963991..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Dialogs/UsersDialog.razor.cs +++ /dev/null @@ -1,176 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; - -public partial class UsersDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _search; - private bool _reloadQueued; - private UserStatus? _statusFilter; - - [CascadingParameter] - IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private async Task> LoadUsers(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new UserQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - Search = _search, - Status = _statusFilter, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Users.QueryAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed to load users.", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task OnStatusChanged(UserStatus? status) - { - _statusFilter = status; - await ReloadAsync(); - } - - private async Task OpenUser(UserKey userKey) - { - var dialog = await DialogService.ShowAsync("User", UAuthDialog.GetDialogParameters(AuthState, userKey), UAuthDialog.GetDialogOptions()); - await dialog.Result; - await ReloadAsync(); - } - - private async Task OpenCreateUser() - { - var dialog = await DialogService.ShowAsync( - "Create User", - new DialogOptions - { - MaxWidth = MaxWidth.Small, - FullWidth = true, - CloseButton = true - }); - - var result = await dialog.Result; - - if (result?.Canceled == false) - await ReloadAsync(); - } - - private async Task DeleteUserAsync(UserSummary user) - { - var confirm = await DialogService.ShowMessageBoxAsync( - title: "Delete user", - markupMessage: (MarkupString)$""" - Are you sure you want to delete {user.DisplayName ?? user.UserName ?? user.PrimaryEmail ?? user.UserKey}? -

- This operation is intended for admin usage. - """, - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions - { - MaxWidth = MaxWidth.Medium, - FullWidth = true, - BackgroundClass = "uauth-blur-slight" - }); - - if (confirm != true) - return; - - var req = new DeleteUserRequest - { - Mode = DeleteMode.Soft - }; - - var result = await UAuthClient.Users.DeleteUserAsync(user.UserKey, req); - - if (result.IsSuccess) - { - Snackbar.Add("User deleted successfully.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to delete user.", Severity.Error); - } - } - - private static Color GetStatusColor(UserStatus status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.SelfSuspended => Color.Warning, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs index 5764a674..829e2bb9 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs @@ -4,7 +4,7 @@ using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs index 2c130d17..4c764bf5 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs @@ -2,7 +2,7 @@ using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using MudBlazor; namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/CodeBeam.UltimateAuth.Sample.BlazorServer.csproj b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/CodeBeam.UltimateAuth.Sample.BlazorServer.csproj index 5345f4b9..cfe21912 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/CodeBeam.UltimateAuth.Sample.BlazorServer.csproj +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/CodeBeam.UltimateAuth.Sample.BlazorServer.csproj @@ -9,8 +9,6 @@ - - @@ -18,6 +16,7 @@ +
diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor deleted file mode 100644 index 0c91e45c..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor +++ /dev/null @@ -1,23 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - User: @AuthState?.Identity?.DisplayName - - - - - Suspend Account - - - - Delete Account - - - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor.cs deleted file mode 100644 index 4fda31ea..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/AccountStatusDialog.razor.cs +++ /dev/null @@ -1,77 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class AccountStatusDialog -{ - [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.

- 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 = SelfAssignableUserStatus.SelfSuspended }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("Your account suspended successfully.", Severity.Success); - MudDialog.Close(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "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.

- This action can't be undone.

- (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?.ErrorText ?? "Delete failed.", Severity.Error); - } - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor deleted file mode 100644 index 9a514935..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor +++ /dev/null @@ -1,27 +0,0 @@ -@using CodeBeam.UltimateAuth.Credentials.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Create User - - - - - - - - - - - - - - - - Cancel - Create - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor.cs deleted file mode 100644 index af13ee27..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CreateUserDialog.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class CreateUserDialog -{ - private MudForm _form = null!; - private string? _username; - private string? _email; - private string? _password; - private string? _passwordCheck; - private string? _displayName; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - private async Task CreateUserAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - if (_password != _passwordCheck) - { - Snackbar.Add("Passwords don't match.", Severity.Error); - return; - } - - var request = new CreateUserRequest - { - UserName = _username, - Email = _email, - DisplayName = _displayName, - Password = _password - }; - - var result = await UAuthClient.Users.CreateAsAdminAsync(request); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "User creation failed.", Severity.Error); - return; - } - - Snackbar.Add("User created successfully", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - - private string PasswordMatch(string? arg) => _password != arg ? "Passwords don't match." : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor deleted file mode 100644 index 660b7c3a..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor +++ /dev/null @@ -1,51 +0,0 @@ -@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 - - - - Credential Management - User: @AuthState?.Identity?.DisplayName - - - - - @if (UserKey == null) - { - - - - } - else - { - - - Administrators can directly assign passwords to users. - However, using the credential reset flow is generally recommended for better security and auditability. - - - } - - - - - - - - - - - @(UserKey is null ? "Change Password" : "Set Password") - - - - - - Cancel - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor.cs deleted file mode 100644 index 04ba3a44..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/CredentialDialog.razor.cs +++ /dev/null @@ -1,92 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class CredentialDialog -{ - 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!; - - [Parameter] - public UserKey? UserKey { get; set; } - - private async Task ChangePasswordAsync() - { - if (_form is null) - return; - - await _form.ValidateAsync(); - 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; - - if (UserKey is null) - { - request = new ChangeCredentialRequest - { - CurrentSecret = _oldPassword!, - NewSecret = _newPassword! - }; - } - else - { - request = new ChangeCredentialRequest - { - NewSecret = _newPassword! - }; - } - - UAuthResult result; - if (UserKey is null) - { - result = await UAuthClient.Credentials.ChangeMyAsync(request); - } - else - { - result = await UAuthClient.Credentials.ChangeUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Password changed successfully", Severity.Success); - _oldPassword = null; - _newPassword = null; - _newPasswordCheck = null; - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "An error occurred while changing password", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor deleted file mode 100644 index 0d631533..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/IdentifierDialog.razor +++ /dev/null @@ -1,106 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - - - - Identifiers - - - - - - - - - - - - - - - - - - - - - - - - - @if (context.Item.IsPrimary) - { - - - - } - else - { - - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add - - - - - - - - Cancel - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor deleted file mode 100644 index 8e0df863..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor +++ /dev/null @@ -1,46 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using System.Reflection - -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Role Permissions - @Role.Name - - - - @* For Debug *@ - @* Current Permissions: @string.Join(", ", Role.Permissions) *@ - - @foreach (var group in _groups) - { - - - - - @group.Name (@group.Items.Count(x => x.Selected)/@group.Items.Count) - - - - - @foreach (var perm in group.Items) - { - - - - } - - - - } - - - - - Cancel - Save - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor.cs deleted file mode 100644 index 3f085402..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/PermissionDialog.razor.cs +++ /dev/null @@ -1,120 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class PermissionDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public RoleInfo Role { get; set; } = default!; - - private List _groups = new(); - - protected override void OnInitialized() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - _groups = catalog - .GroupBy(p => p.Split('.')[0]) - .Select(g => new PermissionGroup - { - Name = g.Key, - Items = g.Select(p => new PermissionItem - { - Value = p, - Selected = selected.Contains(p) - }).ToList() - }) - .OrderBy(x => x.Name) - .ToList(); - } - - private void ToggleGroup(PermissionGroup group, bool value) - { - foreach (var item in group.Items) - item.Selected = value; - } - - private void TogglePermission(PermissionItem item, bool value) - { - item.Selected = value; - } - - private bool? GetGroupState(PermissionGroup group) - { - var selected = group.Items.Count(x => x.Selected); - - if (selected == 0) - return false; - - if (selected == group.Items.Count) - return true; - - return null; - } - - private async Task Save() - { - var permissions = _groups.SelectMany(g => g.Items).Where(x => x.Selected).Select(x => Permission.From(x.Value)).ToList(); - - var req = new SetRolePermissionsRequest - { - RoleId = Role.Id, - Permissions = permissions - }; - - var result = await UAuthClient.Authorization.SetRolePermissionsAsync(req); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "Failed to update permissions", Severity.Error); - return; - } - - var result2 = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery() { Search = Role.Name }); - if (result2.Value?.Items is not null) - { - Role = result2.Value.Items.First(); - } - - Snackbar.Add("Permissions updated", Severity.Success); - RefreshUI(); - } - - private void RefreshUI() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - foreach (var group in _groups) - { - foreach (var item in group.Items) - { - item.Selected = selected.Contains(item.Value); - } - } - - StateHasChanged(); - } - - private void Cancel() => MudDialog.Cancel(); - - private class PermissionGroup - { - public string Name { get; set; } = ""; - public List Items { get; set; } = new(); - } - - private class PermissionItem - { - public string Value { get; set; } = ""; - public bool Selected { get; set; } - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor.cs deleted file mode 100644 index 0cbbd926..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/ResetDialog.razor.cs +++ /dev/null @@ -1,40 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class ResetDialog -{ - private bool _resetRequested = false; - private string? _identifier; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private async Task RequestResetAsync() - { - var request = new BeginResetCredentialRequest - { - CredentialType = CredentialType.Password, - ResetCodeType = ResetCodeType.Code, - Identifier = _identifier ?? string.Empty - }; - - var result = await UAuthClient.Credentials.BeginResetAsync(request); - if (!result.IsSuccess || result.Value is null) - { - Snackbar.Add(result.ErrorText ?? "Failed to request credential reset.", Severity.Error); - return; - } - - _resetRequested = true; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor deleted file mode 100644 index b78db16f..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/RoleDialog.razor +++ /dev/null @@ -1,81 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - - Role Management - Manage system roles - - - - - - - - Roles - - - - - - - - - - - @GetPermissionCount(context.Item) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor deleted file mode 100644 index 52b9c527..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserDetailDialog.razor +++ /dev/null @@ -1,75 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorServer.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - @_user?.UserKey.Value - - - - - - - - Display Name - @_user?.DisplayName - - - - Username - @_user?.UserName - - - - Email - @_user?.PrimaryEmail - - - - Phone - @_user?.PrimaryPhone - - - - Created - @_user?.CreatedAt?.ToLocalTime() - - - - Status - @_user?.Status - - - @foreach (var s in Enum.GetValues()) - { - @s - } - - Change - - - - - - - - Management - - Sessions - Profile - Identifiers - Credentials - Roles - - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor deleted file mode 100644 index 6e754848..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor +++ /dev/null @@ -1,49 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - - User Roles - UserKey: @UserKey.Value - - - - - Assigned Roles - - @if (_roles.Count == 0) - { - No roles assigned - } - - - @foreach (var role in _roles) - { - @role - } - - - - - Add Role - - - - @foreach (var role in _allRoles) - { - @role.Name - } - - - Add - - - - - - Close - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor.cs deleted file mode 100644 index 21683f5b..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Dialogs/UserRoleDialog.razor.cs +++ /dev/null @@ -1,124 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; - -public partial class UserRoleDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } = default!; - - private List _roles = new(); - private List _allRoles = new(); - - private string? _selectedRole; - - protected override async Task OnInitializedAsync() - { - await LoadRoles(); - } - - private async Task LoadRoles() - { - var userRoles = await UAuthClient.Authorization.GetUserRolesAsync(UserKey); - - if (userRoles.IsSuccess && userRoles.Value != null) - _roles = userRoles.Value.Roles.Items.Select(x => x.Name).ToList(); - - var roles = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery - { - PageNumber = 1, - PageSize = 200 - }); - - if (roles.IsSuccess && roles.Value != null) - _allRoles = roles.Value.Items.ToList(); - } - - private async Task AddRole() - { - if (string.IsNullOrWhiteSpace(_selectedRole)) - return; - - var request = new AssignRoleRequest - { - UserKey = UserKey, - RoleName = _selectedRole - }; - - var result = await UAuthClient.Authorization.AssignRoleToUserAsync(request); - - if (result.IsSuccess) - { - _roles.Add(_selectedRole); - Snackbar.Add("Role assigned", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - - _selectedRole = null; - } - - private async Task RemoveRole(string role) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Remove Role", - $"Remove {role} from user?", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - - if (role == "Admin") - { - var confirm2 = await DialogService.ShowMessageBoxAsync( - "Are You Sure", - "You are going to remove admin role. This action may cause the application unuseable.", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm2 != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - } - - var request = new RemoveRoleRequest - { - UserKey = UserKey, - RoleName = role - }; - - var result = await UAuthClient.Authorization.RemoveRoleFromUserAsync(request); - - if (result.IsSuccess) - { - _roles.Remove(role); - Snackbar.Add("Role removed.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private void Close() => MudDialog.Close(); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs index 415e586a..ae2f478a 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs @@ -4,7 +4,7 @@ using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; using CodeBeam.UltimateAuth.Sample.BlazorServer.Common; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs index 73d6ebd3..a90b7e04 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs @@ -2,7 +2,7 @@ using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using MudBlazor; namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj index db5ea39b..572d2e70 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj @@ -8,16 +8,15 @@ - - +
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor deleted file mode 100644 index 0c91e45c..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor +++ /dev/null @@ -1,23 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - User: @AuthState?.Identity?.DisplayName - - - - - Suspend Account - - - - Delete Account - - - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor.cs deleted file mode 100644 index 0bd13951..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/AccountStatusDialog.razor.cs +++ /dev/null @@ -1,77 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class AccountStatusDialog -{ - [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.

- 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 = SelfAssignableUserStatus.SelfSuspended }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("Your account suspended successfully.", Severity.Success); - MudDialog.Close(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "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.

- This action can't be undone.

- (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?.ErrorText ?? "Delete failed.", Severity.Error); - } - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor.cs deleted file mode 100644 index b10d7d9d..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CreateUserDialog.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class CreateUserDialog -{ - private MudForm _form = null!; - private string? _username; - private string? _email; - private string? _password; - private string? _passwordCheck; - private string? _displayName; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - private async Task CreateUserAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - if (_password != _passwordCheck) - { - Snackbar.Add("Passwords don't match.", Severity.Error); - return; - } - - var request = new CreateUserRequest - { - UserName = _username, - Email = _email, - DisplayName = _displayName, - Password = _password - }; - - var result = await UAuthClient.Users.CreateAsAdminAsync(request); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "User creation failed.", Severity.Error); - return; - } - - Snackbar.Add("User created successfully", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - - private string PasswordMatch(string? arg) => _password != arg ? "Passwords don't match." : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor deleted file mode 100644 index 660b7c3a..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor +++ /dev/null @@ -1,51 +0,0 @@ -@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 - - - - Credential Management - User: @AuthState?.Identity?.DisplayName - - - - - @if (UserKey == null) - { - - - - } - else - { - - - Administrators can directly assign passwords to users. - However, using the credential reset flow is generally recommended for better security and auditability. - - - } - - - - - - - - - - - @(UserKey is null ? "Change Password" : "Set Password") - - - - - - Cancel - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor.cs deleted file mode 100644 index e3b5c2ed..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/CredentialDialog.razor.cs +++ /dev/null @@ -1,92 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class CredentialDialog -{ - 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!; - - [Parameter] - public UserKey? UserKey { get; set; } - - private async Task ChangePasswordAsync() - { - if (_form is null) - return; - - await _form.ValidateAsync(); - 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; - - if (UserKey is null) - { - request = new ChangeCredentialRequest - { - CurrentSecret = _oldPassword!, - NewSecret = _newPassword! - }; - } - else - { - request = new ChangeCredentialRequest - { - NewSecret = _newPassword! - }; - } - - UAuthResult result; - if (UserKey is null) - { - result = await UAuthClient.Credentials.ChangeMyAsync(request); - } - else - { - result = await UAuthClient.Credentials.ChangeUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Password changed successfully", Severity.Success); - _oldPassword = null; - _newPassword = null; - _newPasswordCheck = null; - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "An error occurred while changing password", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor deleted file mode 100644 index 24c9e8c9..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor +++ /dev/null @@ -1,115 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - - - - Identifiers - - - - - - - - - - - - - - - - - - - - - - - - - @if (context.Item.IsPrimary) - { - - - - } - else - { - - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add - - - - - } - else - { -
- -
- } -
- - - Cancel - -
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor.cs deleted file mode 100644 index d0e89b89..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/IdentifierDialog.razor.cs +++ /dev/null @@ -1,311 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class IdentifierDialog -{ - private MudDataGrid? _grid; - private UserIdentifierType _newIdentifierType; - private string? _newIdentifierValue; - private bool _newIdentifierPrimary; - private bool _loading = false; - private bool _reloadQueued; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - _loaded = true; - var result = await UAuthClient.Identifiers.GetMyAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - } - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Identifiers.GetMyAsync(req); - } - else - { - res = await UAuthClient.Identifiers.GetUserAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task CommittedItemChanges(UserIdentifierInfo item) - { - UpdateUserIdentifierRequest updateRequest = new() - { - Id = item.Id, - NewValue = item.Value - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UpdateMyAsync(updateRequest); - } - else - { - result = await UAuthClient.Identifiers.UpdateUserAsync(UserKey.Value, updateRequest); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier updated successfully", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to update identifier", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task AddNewIdentifier() - { - if (string.IsNullOrEmpty(_newIdentifierValue)) - { - Snackbar.Add("Value cannot be empty", Severity.Warning); - return; - } - - AddUserIdentifierRequest request = new() - { - Type = _newIdentifierType, - Value = _newIdentifierValue, - IsPrimary = _newIdentifierPrimary - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.AddMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.AddUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier added successfully", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to add identifier", Severity.Error); - } - } - - private async Task VerifyAsync(Guid id) - { - var demoInfo = await DialogService.ShowMessageBoxAsync( - title: "Demo verification", - markupMessage: (MarkupString) - """ - This is a demo action.

- In a real app, you should verify identifiers via Email, SMS, or an Authenticator flow. - This will only mark the identifier as verified in UltimateAuth. - """, - yesText: "Verify", noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (demoInfo != true) - { - Snackbar.Add("Verification cancelled", Severity.Info); - return; - } - - VerifyUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.VerifyMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.VerifyUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier verified successfully", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to verify primary identifier", Severity.Error); - } - } - - private async Task SetPrimaryAsync(Guid id) - { - SetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.SetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.SetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier set successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to set primary identifier", Severity.Error); - } - } - - private async Task UnsetPrimaryAsync(Guid id) - { - UnsetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UnsetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.UnsetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier unset successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to unset primary identifier", Severity.Error); - } - } - - private async Task DeleteIdentifier(Guid id) - { - DeleteUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.DeleteMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.DeleteUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier deleted successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to delete identifier", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor deleted file mode 100644 index 8e0df863..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor +++ /dev/null @@ -1,46 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using System.Reflection - -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Role Permissions - @Role.Name - - - - @* For Debug *@ - @* Current Permissions: @string.Join(", ", Role.Permissions) *@ - - @foreach (var group in _groups) - { - - - - - @group.Name (@group.Items.Count(x => x.Selected)/@group.Items.Count) - - - - - @foreach (var perm in group.Items) - { - - - - } - - - - } - - - - - Cancel - Save - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor.cs deleted file mode 100644 index e676d6ed..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/PermissionDialog.razor.cs +++ /dev/null @@ -1,120 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class PermissionDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public RoleInfo Role { get; set; } = default!; - - private List _groups = new(); - - protected override void OnInitialized() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - _groups = catalog - .GroupBy(p => p.Split('.')[0]) - .Select(g => new PermissionGroup - { - Name = g.Key, - Items = g.Select(p => new PermissionItem - { - Value = p, - Selected = selected.Contains(p) - }).ToList() - }) - .OrderBy(x => x.Name) - .ToList(); - } - - private void ToggleGroup(PermissionGroup group, bool value) - { - foreach (var item in group.Items) - item.Selected = value; - } - - private void TogglePermission(PermissionItem item, bool value) - { - item.Selected = value; - } - - private bool? GetGroupState(PermissionGroup group) - { - var selected = group.Items.Count(x => x.Selected); - - if (selected == 0) - return false; - - if (selected == group.Items.Count) - return true; - - return null; - } - - private async Task Save() - { - var permissions = _groups.SelectMany(g => g.Items).Where(x => x.Selected).Select(x => Permission.From(x.Value)).ToList(); - - var req = new SetRolePermissionsRequest - { - RoleId = Role.Id, - Permissions = permissions - }; - - var result = await UAuthClient.Authorization.SetRolePermissionsAsync(req); - - if (!result.IsSuccess) - { - Snackbar.Add(result.ErrorText ?? "Failed to update permissions", Severity.Error); - return; - } - - var result2 = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery() { Search = Role.Name }); - if (result2.Value?.Items is not null) - { - Role = result2.Value.Items.First(); - } - - Snackbar.Add("Permissions updated", Severity.Success); - RefreshUI(); - } - - private void RefreshUI() - { - var catalog = UAuthPermissionCatalog.GetAdminPermissions(); - var expanded = PermissionExpander.Expand(Role.Permissions, catalog); - var selected = expanded.Select(x => x.Value).ToHashSet(); - - foreach (var group in _groups) - { - foreach (var item in group.Items) - { - item.Selected = selected.Contains(item.Value); - } - } - - StateHasChanged(); - } - - private void Cancel() => MudDialog.Cancel(); - - private class PermissionGroup - { - public string Name { get; set; } = ""; - public List Items { get; set; } = new(); - } - - private class PermissionItem - { - public string Value { get; set; } = ""; - public bool Selected { get; set; } - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor deleted file mode 100644 index a36af169..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor +++ /dev/null @@ -1,103 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - - - - - - Name - - - - - - - - - - - - - - - - - - - Personal - - - - - - - - - - - - - - - - - - - Localization - - - - - - - - - - - @foreach (var tz in TimeZoneInfo.GetSystemTimeZones()) - { - @tz.Id - @tz.DisplayName - } - - - - - - - - - - } - else - { -
- -
- } -
- - Cancel - Save - -
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor.cs deleted file mode 100644 index 8fd1ba9d..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ProfileDialog.razor.cs +++ /dev/null @@ -1,116 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class ProfileDialog -{ - private MudForm? _form; - private string? _firstName; - private string? _lastName; - private string? _displayName; - private DateTime? _birthDate; - private string? _gender; - private string? _bio; - private string? _language; - private string? _timeZone; - private string? _culture; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.GetMeAsync(); - } - else - { - result = await UAuthClient.Users.GetUserAsync(UserKey.Value); - } - - if (result.IsSuccess && result.Value is not null) - { - var p = result.Value; - - _firstName = p.FirstName; - _lastName = p.LastName; - _displayName = p.DisplayName; - - _gender = p.Gender; - _birthDate = p.BirthDate?.ToDateTime(TimeOnly.MinValue); - _bio = p.Bio; - - _language = p.Language; - _timeZone = p.TimeZone; - _culture = p.Culture; - } - _loaded = true; - } - - private async Task SaveAsync() - { - if (AuthState is null || AuthState.Identity is null) - { - Snackbar.Add("No AuthState found.", Severity.Error); - return; - } - - if (_form is not null) - { - await _form.ValidateAsync(); - if (!_form.IsValid) - return; - } - - var request = new UpdateProfileRequest - { - FirstName = _firstName, - LastName = _lastName, - DisplayName = _displayName, - BirthDate = _birthDate.HasValue ? DateOnly.FromDateTime(_birthDate.Value) : null, - Gender = _gender, - Bio = _bio, - Language = _language, - TimeZone = _timeZone, - Culture = _culture - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.UpdateMyProfileAsync(request); - } - else - { - result = await UAuthClient.Users.UpdateUserProfileAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Profile updated", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to update profile", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor deleted file mode 100644 index 8d4c90d3..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor +++ /dev/null @@ -1,37 +0,0 @@ -@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 - - - - Reset Credential - - - - - - This is a demonstration of how to implement a credential reset flow. - In a production application, you should use reset token or code in email, SMS etc. verification steps. - - - Reset request always returns ok even with not found users due to security reasons. - - - Request Reset - @if (_resetRequested) - { - Your reset code is on the server console. - Use Reset Code - } - - - - - Close - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor.cs deleted file mode 100644 index eafbd881..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResetDialog.razor.cs +++ /dev/null @@ -1,40 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Credentials.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class ResetDialog -{ - private bool _resetRequested = false; - private string? _identifier; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private async Task RequestResetAsync() - { - var request = new BeginResetCredentialRequest - { - CredentialType = CredentialType.Password, - ResetCodeType = ResetCodeType.Code, - Identifier = _identifier ?? string.Empty - }; - - var result = await UAuthClient.Credentials.BeginResetAsync(request); - if (!result.IsSuccess || result.Value is null) - { - Snackbar.Add(result.ErrorText ?? "Failed to request credential reset.", Severity.Error); - return; - } - - _resetRequested = true; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor deleted file mode 100644 index bfcf9428..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor +++ /dev/null @@ -1,90 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - - Role Management - Manage system roles - - - - @if (_loaded) - { - - - - - Roles - - - - - - - - - - - @GetPermissionCount(context.Item) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - } - else - { -
- -
- } -
- - - Close - -
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor.cs deleted file mode 100644 index 22c6ea7d..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/RoleDialog.razor.cs +++ /dev/null @@ -1,176 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class RoleDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _newRoleName; - private bool _loaded; - - [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) - { - _loaded = true; - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new RoleQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Authorization.QueryRolesAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task CommittedItemChanges(RoleInfo role) - { - var req = new RenameRoleRequest - { - Id = role.Id, - Name = role.Name - }; - - var result = await UAuthClient.Authorization.RenameRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add("Role renamed", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Rename failed", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task CreateRole() - { - if (string.IsNullOrWhiteSpace(_newRoleName)) - { - Snackbar.Add("Role name required.", Severity.Warning); - return; - } - - var req = new CreateRoleRequest - { - Name = _newRoleName - }; - - var res = await UAuthClient.Authorization.CreateRoleAsync(req); - - if (res.IsSuccess) - { - Snackbar.Add("Role created.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(res.ErrorText ?? "Creation failed.", Severity.Error); - } - } - - private async Task DeleteRole(RoleId roleId) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Delete role", - "Are you sure?", - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - return; - - var req = new DeleteRoleRequest() { Id = roleId }; - var result = await UAuthClient.Authorization.DeleteRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add($"Role deleted, assignments removed from {result.Value?.RemovedAssignments.ToString() ?? "unknown"} users.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Deletion failed.", Severity.Error); - } - } - - private async Task EditPermissions(RoleInfo role) - { - var dialog = await DialogService.ShowAsync( - "Edit Permissions", - new DialogParameters - { - { nameof(PermissionDialog.Role), role } - }, - new DialogOptions - { - CloseButton = true, - MaxWidth = MaxWidth.Large, - FullWidth = true - }); - - var result = await dialog.Result; - await ReloadAsync(); - } - - private async Task ReloadAsync() - { - _loading = true; - await Task.Delay(300); - if (_grid is null) - return; - - await _grid.ReloadServerData(); - _loading = false; - } - - private int GetPermissionCount(RoleInfo role) - { - var expanded = PermissionExpander.Expand(role.Permissions, UAuthPermissionCatalog.GetAdminPermissions()); - return expanded.Count; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor deleted file mode 100644 index e5ee0c4d..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor +++ /dev/null @@ -1,226 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@inject IUAuthStateManager StateManager -@inject NavigationManager Nav - - - - Session Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - @if (_chainDetail is not null) - { - - - - Device Details - - - - @if (!_chainDetail.IsRevoked) - { - - Revoke Device - - } - - - - - - - Device Type - @_chainDetail.DeviceType - - - - Platform - @_chainDetail.Platform - - - - Operating System - @_chainDetail.OperatingSystem - - - - Browser - @_chainDetail.Browser - - - - Created - @_chainDetail.CreatedAt.ToLocalTime() - - - - Last Seen - @_chainDetail.LastSeenAt.ToLocalTime() - - - - State - - @_chainDetail.State - - - - - Active Session - @_chainDetail.ActiveSessionId - - - - Rotation Count - @_chainDetail.RotationCount - - - - Touch Count - @_chainDetail.TouchCount - - - - - - Session History - - - - Session Id - Created - Expires - Status - - - - @context.SessionId - @context.CreatedAt.ToLocalTime() - @context.ExpiresAt.ToLocalTime() - - @if (context.IsRevoked) - { - Revoked - } - else - { - Active - } - - - - - } - else - { - - Logout All Devices - @if (UserKey == null) - { - Logout Other Devices - } - Revoke All Devices - @if (UserKey == null) - { - Revoke Other Devices - } - - - - Sessions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.ChainId - - - - Created At - @context.Item.CreatedAt - - - - Touch Count - @context.Item.TouchCount - - - - Rotation Count - @context.Item.RotationCount - - - - - - - - - } - } - else - { -
- -
- } -
- - Cancel - -
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor.cs deleted file mode 100644 index 1aaceacb..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/SessionDialog.razor.cs +++ /dev/null @@ -1,286 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class SessionDialog -{ - private MudDataGrid? _grid; - private bool _loading = false; - private bool _reloadQueued; - private SessionChainDetail? _chainDetail; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - _loaded = true; - var result = await UAuthClient.Sessions.GetMyChainsAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - } - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Sessions.GetMyChainsAsync(req); - } - else - { - res = await UAuthClient.Sessions.GetUserChainsAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task LogoutAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutAllMyDevicesAsync(); - } - else - { - result = await UAuthClient.Flows.LogoutAllUserDevicesAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task LogoutOthersAsync() - { - var result = await UAuthClient.Flows.LogoutMyOtherDevicesAsync(); - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of other devices.", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout", Severity.Error); - } - } - - private async Task LogoutDeviceAsync(SessionChainId chainId) - { - LogoutDeviceRequest request = new() { ChainId = chainId }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutMyDeviceAsync(request); - } - else - { - result = await UAuthClient.Flows.LogoutUserDeviceAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of device.", Severity.Success); - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeAllMyChainsAsync(); - } - else - { - result = await UAuthClient.Sessions.RevokeAllUserChainsAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeOthersAsync() - { - var result = await UAuthClient.Sessions.RevokeMyOtherChainsAsync(); - if (result.IsSuccess) - { - Snackbar.Add("Revoked all other devices.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeChainAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeMyChainAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.RevokeUserChainAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - Snackbar.Add("Device revoked successfully.", Severity.Success); - - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task ShowChainDetailsAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.GetMyChainDetailAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.GetUserChainDetailAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - _chainDetail = result.Value; - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to fetch chain details.", Severity.Error); - _chainDetail = null; - } - } - - private void ClearDetail() - { - _chainDetail = null; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor deleted file mode 100644 index b8f511f8..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor +++ /dev/null @@ -1,75 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - @_user?.UserKey.Value - - - - - - - - Display Name - @_user?.DisplayName - - - - Username - @_user?.UserName - - - - Email - @_user?.PrimaryEmail - - - - Phone - @_user?.PrimaryPhone - - - - Created - @_user?.CreatedAt?.ToLocalTime() - - - - Status - @_user?.Status - - - @foreach (var s in Enum.GetValues()) - { - @s - } - - Change - - - - - - - - Management - - Sessions - Profile - Identifiers - Credentials - Roles - - - - - - Close - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor.cs deleted file mode 100644 index 5d3e3455..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserDetailDialog.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class UserDetailDialog -{ - private UserView? _user; - private AdminAssignableUserStatus _status; - - [CascadingParameter] - IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - var result = await UAuthClient.Users.GetUserAsync(UserKey); - - if (result.IsSuccess) - { - _user = result.Value; - _status = _user?.Status.ToAdminAssignableUserStatus() ?? AdminAssignableUserStatus.Unknown; - } - } - - private async Task OpenSessions() - { - await DialogService.ShowAsync("Session Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenProfile() - { - await DialogService.ShowAsync("Profile Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifiers() - { - await DialogService.ShowAsync("Identifier Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentials() - { - await DialogService.ShowAsync("Credentials", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenRoles() - { - await DialogService.ShowAsync("Roles", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task ChangeStatusAsync() - { - if (_user is null) - return; - - ChangeUserStatusAdminRequest request = new() - { - NewStatus = _status, - }; - - var result = await UAuthClient.Users.ChangeUserStatusAsync(_user.UserKey, request); - - if (result.IsSuccess) - { - Snackbar.Add("User status updated", Severity.Success); - _user = _user with { Status = _status.ToUserStatus() }; - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private Color GetStatusColor(UserStatus? status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor deleted file mode 100644 index 6e754848..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor +++ /dev/null @@ -1,49 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - - User Roles - UserKey: @UserKey.Value - - - - - Assigned Roles - - @if (_roles.Count == 0) - { - No roles assigned - } - - - @foreach (var role in _roles) - { - @role - } - - - - - Add Role - - - - @foreach (var role in _allRoles) - { - @role.Name - } - - - Add - - - - - - Close - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor.cs deleted file mode 100644 index e89d60ff..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UserRoleDialog.razor.cs +++ /dev/null @@ -1,124 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class UserRoleDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } = default!; - - private List _roles = new(); - private List _allRoles = new(); - - private string? _selectedRole; - - protected override async Task OnInitializedAsync() - { - await LoadRoles(); - } - - private async Task LoadRoles() - { - var userRoles = await UAuthClient.Authorization.GetUserRolesAsync(UserKey); - - if (userRoles.IsSuccess && userRoles.Value != null) - _roles = userRoles.Value.Roles.Items.Select(x => x.Name).ToList(); - - var roles = await UAuthClient.Authorization.QueryRolesAsync(new RoleQuery - { - PageNumber = 1, - PageSize = 200 - }); - - if (roles.IsSuccess && roles.Value != null) - _allRoles = roles.Value.Items.ToList(); - } - - private async Task AddRole() - { - if (string.IsNullOrWhiteSpace(_selectedRole)) - return; - - var request = new AssignRoleRequest - { - UserKey = UserKey, - RoleName = _selectedRole - }; - - var result = await UAuthClient.Authorization.AssignRoleToUserAsync(request); - - if (result.IsSuccess) - { - _roles.Add(_selectedRole); - Snackbar.Add("Role assigned", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - - _selectedRole = null; - } - - private async Task RemoveRole(string role) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Remove Role", - $"Remove {role} from user?", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - - if (role == "Admin") - { - var confirm2 = await DialogService.ShowMessageBoxAsync( - "Are You Sure", - "You are going to remove admin role. This action may cause the application unuseable.", - yesText: "Remove", - noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm2 != true) - { - Snackbar.Add("Role remove process cancelled.", Severity.Info); - return; - } - } - - var request = new RemoveRoleRequest - { - UserKey = UserKey, - RoleName = role - }; - - var result = await UAuthClient.Authorization.RemoveRoleFromUserAsync(request); - - if (result.IsSuccess) - { - _roles.Remove(role); - Snackbar.Add("Role removed.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private void Close() => MudDialog.Close(); -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor deleted file mode 100644 index f9df9a84..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor +++ /dev/null @@ -1,94 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - Browse, create and manage users - - - - @if (_loaded) - { - - - - - - - - - - - - - - Users - - New User - - - - - - - - - - - @context.Item.Status - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.UserKey.Value - - - - Created At - @context.Item.CreatedAt - - - - - - - - - - } - else - { -
- -
- } -
- - - Close - -
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor.cs deleted file mode 100644 index a215a013..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/UsersDialog.razor.cs +++ /dev/null @@ -1,188 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class UsersDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _search; - private bool _reloadQueued; - private UserStatus? _statusFilter; - private bool _loaded; - - [CascadingParameter] - 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) - { - _loaded = true; - StateHasChanged(); - } - } - - private async Task> LoadUsers(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new UserQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - Search = _search, - Status = _statusFilter, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Users.QueryAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed to load users.", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task OnStatusChanged(UserStatus? status) - { - _statusFilter = status; - await ReloadAsync(); - } - - private async Task OpenUser(UserKey userKey) - { - var dialog = await DialogService.ShowAsync("User", UAuthDialog.GetDialogParameters(AuthState, userKey), UAuthDialog.GetDialogOptions()); - await dialog.Result; - await ReloadAsync(); - } - - private async Task OpenCreateUser() - { - var dialog = await DialogService.ShowAsync( - "Create User", - new DialogOptions - { - MaxWidth = MaxWidth.Small, - FullWidth = true, - CloseButton = true - }); - - var result = await dialog.Result; - - if (result?.Canceled == false) - await ReloadAsync(); - } - - private async Task DeleteUserAsync(UserSummary user) - { - var confirm = await DialogService.ShowMessageBoxAsync( - title: "Delete user", - markupMessage: (MarkupString)$""" - Are you sure you want to delete {user.DisplayName ?? user.UserName ?? user.PrimaryEmail ?? user.UserKey}? -

- This operation is intended for admin usage. - """, - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions - { - MaxWidth = MaxWidth.Medium, - FullWidth = true, - BackgroundClass = "uauth-blur-slight" - }); - - if (confirm != true) - return; - - var req = new DeleteUserRequest - { - Mode = DeleteMode.Soft - }; - - var result = await UAuthClient.Users.DeleteUserAsync(UserKey.Parse(user.UserKey, null), req); - - if (result.IsSuccess) - { - Snackbar.Add("User deleted successfully.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to delete user.", Severity.Error); - } - } - - private static Color GetStatusColor(UserStatus status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.SelfSuspended => Color.Warning, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs index 4464b6ff..108a3346 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs @@ -5,6 +5,7 @@ using CodeBeam.UltimateAuth.Core.Errors; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs index 3250a476..c1e90450 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs @@ -4,6 +4,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using MudBlazor; namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/CodeBeam.UAuth.Sample.IntWasm.Client.csproj b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/CodeBeam.UAuth.Sample.IntWasm.Client.csproj index e4408ae2..1dafa9a8 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/CodeBeam.UAuth.Sample.IntWasm.Client.csproj +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/CodeBeam.UAuth.Sample.IntWasm.Client.csproj @@ -11,14 +11,13 @@ - - - - + + +
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor deleted file mode 100644 index 0c91e45c..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/AccountStatusDialog.razor +++ /dev/null @@ -1,23 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - User: @AuthState?.Identity?.DisplayName - - - - - Suspend Account - - - - Delete Account - - - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor deleted file mode 100644 index 9a514935..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CreateUserDialog.razor +++ /dev/null @@ -1,27 +0,0 @@ -@using CodeBeam.UltimateAuth.Credentials.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Create User - - - - - - - - - - - - - - - - Cancel - Create - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor deleted file mode 100644 index 660b7c3a..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/CredentialDialog.razor +++ /dev/null @@ -1,51 +0,0 @@ -@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 - - - - Credential Management - User: @AuthState?.Identity?.DisplayName - - - - - @if (UserKey == null) - { - - - - } - else - { - - - Administrators can directly assign passwords to users. - However, using the credential reset flow is generally recommended for better security and auditability. - - - } - - - - - - - - - - - @(UserKey is null ? "Change Password" : "Set Password") - - - - - - Cancel - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor deleted file mode 100644 index 24c9e8c9..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor +++ /dev/null @@ -1,115 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - - - - Identifiers - - - - - - - - - - - - - - - - - - - - - - - - - @if (context.Item.IsPrimary) - { - - - - } - else - { - - - - } - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add - - - - - } - else - { -
- -
- } -
- - - Cancel - -
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor.cs deleted file mode 100644 index 135cdc64..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/IdentifierDialog.razor.cs +++ /dev/null @@ -1,311 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class IdentifierDialog -{ - private MudDataGrid? _grid; - private UserIdentifierType _newIdentifierType; - private string? _newIdentifierValue; - private bool _newIdentifierPrimary; - private bool _loading = false; - private bool _reloadQueued; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - _loaded = true; - var result = await UAuthClient.Identifiers.GetMyAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - } - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Identifiers.GetMyAsync(req); - } - else - { - res = await UAuthClient.Identifiers.GetUserAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task CommittedItemChanges(UserIdentifierInfo item) - { - UpdateUserIdentifierRequest updateRequest = new() - { - Id = item.Id, - NewValue = item.Value - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UpdateMyAsync(updateRequest); - } - else - { - result = await UAuthClient.Identifiers.UpdateUserAsync(UserKey.Value, updateRequest); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier updated successfully", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to update identifier", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task AddNewIdentifier() - { - if (string.IsNullOrEmpty(_newIdentifierValue)) - { - Snackbar.Add("Value cannot be empty", Severity.Warning); - return; - } - - AddUserIdentifierRequest request = new() - { - Type = _newIdentifierType, - Value = _newIdentifierValue, - IsPrimary = _newIdentifierPrimary - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.AddMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.AddUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier added successfully", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to add identifier", Severity.Error); - } - } - - private async Task VerifyAsync(Guid id) - { - var demoInfo = await DialogService.ShowMessageBoxAsync( - title: "Demo verification", - markupMessage: (MarkupString) - """ - This is a demo action.

- In a real app, you should verify identifiers via Email, SMS, or an Authenticator flow. - This will only mark the identifier as verified in UltimateAuth. - """, - yesText: "Verify", noText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (demoInfo != true) - { - Snackbar.Add("Verification cancelled", Severity.Info); - return; - } - - VerifyUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.VerifyMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.VerifyUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier verified successfully", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to verify primary identifier", Severity.Error); - } - } - - private async Task SetPrimaryAsync(Guid id) - { - SetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.SetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.SetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier set successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to set primary identifier", Severity.Error); - } - } - - private async Task UnsetPrimaryAsync(Guid id) - { - UnsetPrimaryUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.UnsetMyPrimaryAsync(request); - } - else - { - result = await UAuthClient.Identifiers.UnsetUserPrimaryAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Primary identifier unset successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to unset primary identifier", Severity.Error); - } - } - - private async Task DeleteIdentifier(Guid id) - { - DeleteUserIdentifierRequest request = new() { Id = id }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Identifiers.DeleteMyAsync(request); - } - else - { - result = await UAuthClient.Identifiers.DeleteUserAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Identifier deleted successfully.", Severity.Success); - await ReloadAsync(); - StateHasChanged(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to delete identifier", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor deleted file mode 100644 index 8e0df863..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/PermissionDialog.razor +++ /dev/null @@ -1,46 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using System.Reflection - -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - Role Permissions - @Role.Name - - - - @* For Debug *@ - @* Current Permissions: @string.Join(", ", Role.Permissions) *@ - - @foreach (var group in _groups) - { - - - - - @group.Name (@group.Items.Count(x => x.Selected)/@group.Items.Count) - - - - - @foreach (var perm in group.Items) - { - - - - } - - - - } - - - - - Cancel - Save - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor deleted file mode 100644 index a36af169..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor +++ /dev/null @@ -1,103 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - Identifier Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - - - - - - Name - - - - - - - - - - - - - - - - - - - Personal - - - - - - - - - - - - - - - - - - - Localization - - - - - - - - - - - @foreach (var tz in TimeZoneInfo.GetSystemTimeZones()) - { - @tz.Id - @tz.DisplayName - } - - - - - - - - - - } - else - { -
- -
- } -
- - Cancel - Save - -
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor.cs deleted file mode 100644 index 611e7141..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ProfileDialog.razor.cs +++ /dev/null @@ -1,116 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class ProfileDialog -{ - private MudForm? _form; - private string? _firstName; - private string? _lastName; - private string? _displayName; - private DateTime? _birthDate; - private string? _gender; - private string? _bio; - private string? _language; - private string? _timeZone; - private string? _culture; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.GetMeAsync(); - } - else - { - result = await UAuthClient.Users.GetUserAsync(UserKey.Value); - } - - if (result.IsSuccess && result.Value is not null) - { - var p = result.Value; - - _firstName = p.FirstName; - _lastName = p.LastName; - _displayName = p.DisplayName; - - _gender = p.Gender; - _birthDate = p.BirthDate?.ToDateTime(TimeOnly.MinValue); - _bio = p.Bio; - - _language = p.Language; - _timeZone = p.TimeZone; - _culture = p.Culture; - } - _loaded = true; - } - - private async Task SaveAsync() - { - if (AuthState is null || AuthState.Identity is null) - { - Snackbar.Add("No AuthState found.", Severity.Error); - return; - } - - if (_form is not null) - { - await _form.ValidateAsync(); - if (!_form.IsValid) - return; - } - - var request = new UpdateProfileRequest - { - FirstName = _firstName, - LastName = _lastName, - DisplayName = _displayName, - BirthDate = _birthDate.HasValue ? DateOnly.FromDateTime(_birthDate.Value) : null, - Gender = _gender, - Bio = _bio, - Language = _language, - TimeZone = _timeZone, - Culture = _culture - }; - - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Users.UpdateMyProfileAsync(request); - } - else - { - result = await UAuthClient.Users.UpdateUserProfileAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Profile updated", Severity.Success); - MudDialog.Close(DialogResult.Ok(true)); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to update profile", Severity.Error); - } - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor deleted file mode 100644 index 8d4c90d3..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResetDialog.razor +++ /dev/null @@ -1,37 +0,0 @@ -@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 - - - - Reset Credential - - - - - - This is a demonstration of how to implement a credential reset flow. - In a production application, you should use reset token or code in email, SMS etc. verification steps. - - - Reset request always returns ok even with not found users due to security reasons. - - - Request Reset - @if (_resetRequested) - { - Your reset code is on the server console. - Use Reset Code - } - - - - - Close - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor deleted file mode 100644 index bfcf9428..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor +++ /dev/null @@ -1,90 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@using CodeBeam.UltimateAuth.Core.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService - - - - - Role Management - Manage system roles - - - - @if (_loaded) - { - - - - - Roles - - - - - - - - - - - @GetPermissionCount(context.Item) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - - - - - } - else - { -
- -
- } -
- - - Close - -
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor.cs deleted file mode 100644 index f079d51a..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/RoleDialog.razor.cs +++ /dev/null @@ -1,176 +0,0 @@ -using CodeBeam.UltimateAuth.Authorization.Contracts; -using CodeBeam.UltimateAuth.Client; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class RoleDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _newRoleName; - private bool _loaded; - - [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) - { - _loaded = true; - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new RoleQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Authorization.QueryRolesAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task CommittedItemChanges(RoleInfo role) - { - var req = new RenameRoleRequest - { - Id = role.Id, - Name = role.Name - }; - - var result = await UAuthClient.Authorization.RenameRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add("Role renamed", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Rename failed", Severity.Error); - } - - await ReloadAsync(); - return DataGridEditFormAction.Close; - } - - private async Task CreateRole() - { - if (string.IsNullOrWhiteSpace(_newRoleName)) - { - Snackbar.Add("Role name required.", Severity.Warning); - return; - } - - var req = new CreateRoleRequest - { - Name = _newRoleName - }; - - var res = await UAuthClient.Authorization.CreateRoleAsync(req); - - if (res.IsSuccess) - { - Snackbar.Add("Role created.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(res.ErrorText ?? "Creation failed.", Severity.Error); - } - } - - private async Task DeleteRole(RoleId roleId) - { - var confirm = await DialogService.ShowMessageBoxAsync( - "Delete role", - "Are you sure?", - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions() { MaxWidth = MaxWidth.Medium, FullWidth = true, BackgroundClass = "uauth-blur-slight" }); - - if (confirm != true) - return; - - var req = new DeleteRoleRequest() { Id = roleId }; - var result = await UAuthClient.Authorization.DeleteRoleAsync(req); - - if (result.IsSuccess) - { - Snackbar.Add($"Role deleted, assignments removed from {result.Value?.RemovedAssignments.ToString() ?? "unknown"} users.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Deletion failed.", Severity.Error); - } - } - - private async Task EditPermissions(RoleInfo role) - { - var dialog = await DialogService.ShowAsync( - "Edit Permissions", - new DialogParameters - { - { nameof(PermissionDialog.Role), role } - }, - new DialogOptions - { - CloseButton = true, - MaxWidth = MaxWidth.Large, - FullWidth = true - }); - - var result = await dialog.Result; - await ReloadAsync(); - } - - private async Task ReloadAsync() - { - _loading = true; - await Task.Delay(300); - if (_grid is null) - return; - - await _grid.ReloadServerData(); - _loading = false; - } - - private int GetPermissionCount(RoleInfo role) - { - var expanded = PermissionExpander.Expand(role.Permissions, UAuthPermissionCatalog.GetAdminPermissions()); - return expanded.Count; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor deleted file mode 100644 index e5ee0c4d..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor +++ /dev/null @@ -1,226 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@inject IUAuthStateManager StateManager -@inject NavigationManager Nav - - - - Session Management - - @if (UserKey is null) - { - User: @AuthState?.Identity?.DisplayName - } - else - { - UserKey: @UserKey.Value - } - - - - @if (_loaded) - { - @if (_chainDetail is not null) - { - - - - Device Details - - - - @if (!_chainDetail.IsRevoked) - { - - Revoke Device - - } - - - - - - - Device Type - @_chainDetail.DeviceType - - - - Platform - @_chainDetail.Platform - - - - Operating System - @_chainDetail.OperatingSystem - - - - Browser - @_chainDetail.Browser - - - - Created - @_chainDetail.CreatedAt.ToLocalTime() - - - - Last Seen - @_chainDetail.LastSeenAt.ToLocalTime() - - - - State - - @_chainDetail.State - - - - - Active Session - @_chainDetail.ActiveSessionId - - - - Rotation Count - @_chainDetail.RotationCount - - - - Touch Count - @_chainDetail.TouchCount - - - - - - Session History - - - - Session Id - Created - Expires - Status - - - - @context.SessionId - @context.CreatedAt.ToLocalTime() - @context.ExpiresAt.ToLocalTime() - - @if (context.IsRevoked) - { - Revoked - } - else - { - Active - } - - - - - } - else - { - - Logout All Devices - @if (UserKey == null) - { - Logout Other Devices - } - Revoke All Devices - @if (UserKey == null) - { - Revoke Other Devices - } - - - - Sessions - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.ChainId - - - - Created At - @context.Item.CreatedAt - - - - Touch Count - @context.Item.TouchCount - - - - Rotation Count - @context.Item.RotationCount - - - - - - - - - } - } - else - { -
- -
- } -
- - Cancel - -
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor.cs deleted file mode 100644 index b7b084d3..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/SessionDialog.razor.cs +++ /dev/null @@ -1,286 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class SessionDialog -{ - private MudDataGrid? _grid; - private bool _loading = false; - private bool _reloadQueued; - private SessionChainDetail? _chainDetail; - private bool _loaded; - - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey? UserKey { get; set; } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - await base.OnAfterRenderAsync(firstRender); - - if (firstRender) - { - _loaded = true; - var result = await UAuthClient.Sessions.GetMyChainsAsync(); - if (result != null && result.IsSuccess && result.Value != null) - { - await ReloadAsync(); - } - StateHasChanged(); - } - } - - private async Task> LoadServerData(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new PageRequest - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - UAuthResult> res; - - if (UserKey is null) - { - res = await UAuthClient.Sessions.GetMyChainsAsync(req); - } - else - { - res = await UAuthClient.Sessions.GetUserChainsAsync(UserKey.Value, req); - } - - if (!res.IsSuccess || res.Value is null) - { - Snackbar.Add(res.Problem?.Title ?? "Failed", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - await Task.Delay(300); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task LogoutAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutAllMyDevicesAsync(); - } - else - { - result = await UAuthClient.Flows.LogoutAllUserDevicesAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task LogoutOthersAsync() - { - var result = await UAuthClient.Flows.LogoutMyOtherDevicesAsync(); - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of other devices.", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout", Severity.Error); - } - } - - private async Task LogoutDeviceAsync(SessionChainId chainId) - { - LogoutDeviceRequest request = new() { ChainId = chainId }; - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Flows.LogoutMyDeviceAsync(request); - } - else - { - result = await UAuthClient.Flows.LogoutUserDeviceAsync(UserKey.Value, request); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of device.", Severity.Success); - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeAllAsync() - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeAllMyChainsAsync(); - } - else - { - result = await UAuthClient.Sessions.RevokeAllUserChainsAsync(UserKey.Value); - } - - if (result.IsSuccess) - { - Snackbar.Add("Logged out of all devices.", Severity.Success); - - if (UserKey is null) - Nav.NavigateTo("/login"); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeOthersAsync() - { - var result = await UAuthClient.Sessions.RevokeMyOtherChainsAsync(); - if (result.IsSuccess) - { - Snackbar.Add("Revoked all other devices.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task RevokeChainAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.RevokeMyChainAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.RevokeUserChainAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - Snackbar.Add("Device revoked successfully.", Severity.Success); - - if (result?.Value?.CurrentChain == true) - { - Nav.NavigateTo("/login"); - return; - } - await ReloadAsync(); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to logout.", Severity.Error); - } - } - - private async Task ShowChainDetailsAsync(SessionChainId chainId) - { - UAuthResult result; - - if (UserKey is null) - { - result = await UAuthClient.Sessions.GetMyChainDetailAsync(chainId); - } - else - { - result = await UAuthClient.Sessions.GetUserChainDetailAsync(UserKey.Value, chainId); - } - - if (result.IsSuccess) - { - _chainDetail = result.Value; - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to fetch chain details.", Severity.Error); - _chainDetail = null; - } - } - - private void ClearDetail() - { - _chainDetail = null; - } - - private void Cancel() => MudDialog.Cancel(); -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor.cs deleted file mode 100644 index 842af288..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserDetailDialog.razor.cs +++ /dev/null @@ -1,100 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UAuth.Sample.IntWasm.Client.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class UserDetailDialog -{ - private UserView? _user; - private AdminAssignableUserStatus _status; - - [CascadingParameter] - IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - [Parameter] - public UserKey UserKey { get; set; } - - protected override async Task OnInitializedAsync() - { - await base.OnInitializedAsync(); - var result = await UAuthClient.Users.GetUserAsync(UserKey); - - if (result.IsSuccess) - { - _user = result.Value; - _status = _user?.Status.ToAdminAssignableUserStatus() ?? AdminAssignableUserStatus.Unknown; - } - } - - private async Task OpenSessions() - { - await DialogService.ShowAsync("Session Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenProfile() - { - await DialogService.ShowAsync("Profile Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifiers() - { - await DialogService.ShowAsync("Identifier Management", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentials() - { - await DialogService.ShowAsync("Credentials", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenRoles() - { - await DialogService.ShowAsync("Roles", UAuthDialog.GetDialogParameters(AuthState, _user?.UserKey), UAuthDialog.GetDialogOptions()); - } - - private async Task ChangeStatusAsync() - { - if (_user is null) - return; - - ChangeUserStatusAdminRequest request = new() - { - NewStatus = _status, - }; - - var result = await UAuthClient.Users.ChangeUserStatusAsync(_user.UserKey, request); - - if (result.IsSuccess) - { - Snackbar.Add("User status updated", Severity.Success); - _user = _user with { Status = _status.ToUserStatus() }; - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed", Severity.Error); - } - } - - private Color GetStatusColor(UserStatus? status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor deleted file mode 100644 index 6e754848..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UserRoleDialog.razor +++ /dev/null @@ -1,49 +0,0 @@ -@using CodeBeam.UltimateAuth.Authorization.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - - User Roles - UserKey: @UserKey.Value - - - - - Assigned Roles - - @if (_roles.Count == 0) - { - No roles assigned - } - - - @foreach (var role in _roles) - { - @role - } - - - - - Add Role - - - - @foreach (var role in _allRoles) - { - @role.Name - } - - - Add - - - - - - Close - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor deleted file mode 100644 index 0eea8438..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor +++ /dev/null @@ -1,94 +0,0 @@ -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UAuth.Sample.IntWasm.Client.Common -@using CodeBeam.UltimateAuth.Users.Contracts -@inject IUAuthClient UAuthClient -@inject IDialogService DialogService -@inject ISnackbar Snackbar - - - - User Management - Browse, create and manage users - - - - @if (_loaded) - { - - - - - - - - - - - - - - Users - - New User - - - - - - - - - - - @context.Item.Status - - - - - - - - - - - - - - - - - - - - - Id - @context.Item.UserKey.Value - - - - Created At - @context.Item.CreatedAt - - - - - - - - - - } - else - { -
- -
- } -
- - - Close - -
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor.cs deleted file mode 100644 index cc24a17b..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/UsersDialog.razor.cs +++ /dev/null @@ -1,188 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UAuth.Sample.IntWasm.Client.Common; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; - -public partial class UsersDialog -{ - private MudDataGrid? _grid; - private bool _loading; - private string? _search; - private bool _reloadQueued; - private UserStatus? _statusFilter; - private bool _loaded; - - [CascadingParameter] - 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) - { - _loaded = true; - StateHasChanged(); - } - } - - private async Task> LoadUsers(GridState state, CancellationToken ct) - { - var sort = state.SortDefinitions?.FirstOrDefault(); - - var req = new UserQuery - { - PageNumber = state.Page + 1, - PageSize = state.PageSize, - Search = _search, - Status = _statusFilter, - SortBy = sort?.SortBy, - Descending = sort?.Descending ?? false - }; - - var res = await UAuthClient.Users.QueryAsync(req); - - if (!res.IsSuccess || res.Value == null) - { - Snackbar.Add(res.ErrorText ?? "Failed to load users.", Severity.Error); - - return new GridData - { - Items = Array.Empty(), - TotalItems = 0 - }; - } - - return new GridData - { - Items = res.Value.Items, - TotalItems = res.Value.TotalCount - }; - } - - private async Task ReloadAsync() - { - if (_loading) - { - _reloadQueued = true; - return; - } - - if (_grid is null) - return; - - _loading = true; - await InvokeAsync(StateHasChanged); - - try - { - await _grid.ReloadServerData(); - } - finally - { - _loading = false; - - if (_reloadQueued) - { - _reloadQueued = false; - await ReloadAsync(); - } - - await InvokeAsync(StateHasChanged); - } - } - - private async Task OnStatusChanged(UserStatus? status) - { - _statusFilter = status; - await ReloadAsync(); - } - - private async Task OpenUser(UserKey userKey) - { - var dialog = await DialogService.ShowAsync("User", UAuthDialog.GetDialogParameters(AuthState, userKey), UAuthDialog.GetDialogOptions()); - await dialog.Result; - await ReloadAsync(); - } - - private async Task OpenCreateUser() - { - var dialog = await DialogService.ShowAsync( - "Create User", - new DialogOptions - { - MaxWidth = MaxWidth.Small, - FullWidth = true, - CloseButton = true - }); - - var result = await dialog.Result; - - if (result?.Canceled == false) - await ReloadAsync(); - } - - private async Task DeleteUserAsync(UserSummary user) - { - var confirm = await DialogService.ShowMessageBoxAsync( - title: "Delete user", - markupMessage: (MarkupString)$""" - Are you sure you want to delete {user.DisplayName ?? user.UserName ?? user.PrimaryEmail ?? user.UserKey}? -

- This operation is intended for admin usage. - """, - yesText: "Delete", - cancelText: "Cancel", - options: new DialogOptions - { - MaxWidth = MaxWidth.Medium, - FullWidth = true, - BackgroundClass = "uauth-blur-slight" - }); - - if (confirm != true) - return; - - var req = new DeleteUserRequest - { - Mode = DeleteMode.Soft - }; - - var result = await UAuthClient.Users.DeleteUserAsync(UserKey.Parse(user.UserKey, null), req); - - if (result.IsSuccess) - { - Snackbar.Add("User deleted successfully.", Severity.Success); - await ReloadAsync(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to delete user.", Severity.Error); - } - } - - private static Color GetStatusColor(UserStatus status) - { - return status switch - { - UserStatus.Active => Color.Success, - UserStatus.SelfSuspended => Color.Warning, - UserStatus.Suspended => Color.Warning, - UserStatus.Disabled => Color.Error, - _ => Color.Default - }; - } - - private void Close() - { - MudDialog.Close(); - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs index f14b1df3..abbeec3a 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs @@ -4,11 +4,12 @@ using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; using CodeBeam.UAuth.Sample.IntWasm.Client.Common; -using CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; using System.Security.Claims; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +using CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs index 616df5f2..29a2aead 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs @@ -1,10 +1,9 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Blazor; +using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; using MudBlazor; +using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.csproj b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.csproj index e03668c9..2154aec8 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.csproj +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.csproj @@ -11,7 +11,7 @@ - + diff --git a/samples/resource-api/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore.csproj b/samples/resource-api/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore.csproj index 20471edc..cde66c01 100644 --- a/samples/resource-api/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore.csproj +++ b/samples/resource-api/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore/CodeBeam.UltimateAuth.Sample.ResourceApi.EfCore.csproj @@ -4,6 +4,7 @@ net10.0 enable enable + false From 0860c21abfa060fc1199b6e3ffc4262ab3a403c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Wed, 14 Oct 2026 21:12:43 +0300 Subject: [PATCH 2/8] Brand and Common Folders --- .../Brand/UAuthLogo.razor | 2 +- .../Brand/UAuthLogo.razor.cs | 3 +- .../Brand/UAuthLogoVariant.cs | 2 +- ...CodeBeam.UltimateAuth.Sample.Shared.csproj | 6 +- .../Dialogs/ResourceApiDialog.razor | 2 +- .../Dialogs/ResourceApiDialog.razor.cs | 7 +- .../ResourceApi/ProductApiService.cs | 2 +- .../ResourceApi/SampleProduct.cs | 2 +- .../Brand/UAuthLogo.razor.cs | 54 ----------- .../Brand/UAuthLogoVariant.cs | 7 -- .../Brand/UAuthLogo.razor | 19 ---- .../Brand/UAuthLogo.razor | 19 ---- .../Brand/UAuthLogo.razor.cs | 54 ----------- .../Brand/UAuthLogoVariant.cs | 7 -- .../Common/UAuthDialog.cs | 29 ------ .../Components/Pages/Home.razor.cs | 2 +- .../Brand/UAuthLogo.razor | 19 ---- .../Brand/UAuthLogo.razor.cs | 54 ----------- .../Brand/UAuthLogoVariant.cs | 7 -- ...ateAuth.Sample.BlazorStandaloneWasm.csproj | 8 +- .../Common/UAuthDialog.cs | 29 ------ .../Dialogs/ResourceApiDialog.razor | 54 ----------- .../Dialogs/ResourceApiDialog.razor.cs | 95 ------------------- .../Pages/Home.razor.cs | 3 +- .../Pages/Login.razor.cs | 4 +- .../Program.cs | 2 +- .../ResourceApi/ProductApiService.cs | 78 --------------- .../ResourceApi/SampleProduct.cs | 7 -- .../Brand/UAuthLogo.razor | 19 ---- .../Brand/UAuthLogo.razor.cs | 54 ----------- .../Brand/UAuthLogoVariant.cs | 7 -- .../Common/UAuthDialog.cs | 29 ------ .../Layout/MainLayout.razor | 3 +- .../Pages/Home.razor.cs | 3 +- .../Pages/Login.razor | 1 + .../Pages/NotAuthorized.razor | 3 +- .../Pages/Register.razor | 1 + .../Program.cs | 2 +- .../CodeBeam.UAuth.Sample.IntWasm/Program.cs | 2 +- 39 files changed, 29 insertions(+), 672 deletions(-) rename samples/{UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore => CodeBeam.UltimateAuth.Sample.Shared}/Brand/UAuthLogo.razor (93%) rename samples/{UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub => CodeBeam.UltimateAuth.Sample.Shared}/Brand/UAuthLogo.razor.cs (94%) rename samples/{UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub => CodeBeam.UltimateAuth.Sample.Shared}/Brand/UAuthLogoVariant.cs (51%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ResourceApiDialog.razor (97%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components => CodeBeam.UltimateAuth.Sample.Shared}/Dialogs/ResourceApiDialog.razor.cs (90%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client => CodeBeam.UltimateAuth.Sample.Shared}/ResourceApi/ProductApiService.cs (97%) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client => CodeBeam.UltimateAuth.Sample.Shared}/ResourceApi/SampleProduct.cs (61%) delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor.cs delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogoVariant.cs delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogoVariant.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Common/UAuthDialog.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogoVariant.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Common/UAuthDialog.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/ProductApiService.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/SampleProduct.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogoVariant.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Common/UAuthDialog.cs diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor similarity index 93% rename from samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor index 2806b7d3..b18f2338 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor @@ -1,4 +1,4 @@ -@namespace CodeBeam.UltimateAuth.Sample +@namespace CodeBeam.UltimateAuth.Sample.Shared @inherits ComponentBase diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor.cs similarity index 94% rename from samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor.cs index 030d9b66..9425b43c 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogo.razor.cs @@ -1,7 +1,6 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; -namespace CodeBeam.UltimateAuth.Sample; +namespace CodeBeam.UltimateAuth.Sample.Shared; public partial class UAuthLogo : ComponentBase { diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogoVariant.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogoVariant.cs similarity index 51% rename from samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogoVariant.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogoVariant.cs index fe3be220..fc543d89 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogoVariant.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Brand/UAuthLogoVariant.cs @@ -1,4 +1,4 @@ -namespace CodeBeam.UltimateAuth.Sample; +namespace CodeBeam.UltimateAuth.Sample.Shared; public enum UAuthLogoVariant { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj index 22d39e8b..361c6a59 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj @@ -13,9 +13,11 @@ - + - + + + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor similarity index 97% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor index c235fb4b..899fc6de 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor @@ -1,4 +1,4 @@ -@using CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi +@using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi @inject ProductApiService Api @inject ISnackbar Snackbar diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs similarity index 90% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs index 7b6f3ebb..52efdf3b 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Dialogs/ResourceApiDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs @@ -1,12 +1,9 @@ using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi; -using CodeBeam.UltimateAuth.Users.Contracts; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; public partial class ResourceApiDialog { diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/ProductApiService.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs similarity index 97% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/ProductApiService.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs index 6220f56b..95176ea1 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/ProductApiService.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components.WebAssembly.Http; using System.Net.Http.Json; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi; +namespace CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; public class ProductApiService { diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/SampleProduct.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProduct.cs similarity index 61% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/SampleProduct.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProduct.cs index b169ecf3..c84ee0c7 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/ResourceApi/SampleProduct.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProduct.cs @@ -1,4 +1,4 @@ -namespace CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi; +namespace CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; public class SampleProduct { diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor.cs deleted file mode 100644 index 030d9b66..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogo.razor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace CodeBeam.UltimateAuth.Sample; - -public partial class UAuthLogo : ComponentBase -{ - [Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand; - - [Parameter] public int Size { get; set; } = 32; - - [Parameter] public string? ShieldColor { get; set; } = "#00072d"; - [Parameter] public string? KeyColor { get; set; } = "#f6f5ae"; - - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } - - private string BuildStyle() - { - if (Variant == UAuthLogoVariant.Mono) - return $"color: {KeyColor}; {Style}"; - - return Style ?? ""; - } - - protected string KeyPath => @" -M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37 -A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99 -v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153 -V99.79h-8V93.32L108.19,89h12.24 -A11.67,11.67,0,0,0,132.1,77.37V51.11 -A11.67,11.67,0,0,0,120.43,39.44Z - -M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.84a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z - -M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.83a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z - -M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.84a2.91,2.91 0 0 1 -2.91,2.91 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.91 -v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z - -M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.83a2.91,2.91 0 0 1 -2.91,2.92 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.92 -v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z -"; -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogoVariant.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogoVariant.cs deleted file mode 100644 index fe3be220..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Brand/UAuthLogoVariant.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample; - -public enum UAuthLogoVariant -{ - Brand, - Mono -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor deleted file mode 100644 index 2806b7d3..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Brand/UAuthLogo.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace CodeBeam.UltimateAuth.Sample -@inherits ComponentBase - - - - @if (Variant == UAuthLogoVariant.Brand) - { - - - - } - else - { - - - - } - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor deleted file mode 100644 index 2806b7d3..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace CodeBeam.UltimateAuth.Sample -@inherits ComponentBase - - - - @if (Variant == UAuthLogoVariant.Brand) - { - - - - } - else - { - - - - } - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor.cs deleted file mode 100644 index 030d9b66..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogo.razor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace CodeBeam.UltimateAuth.Sample; - -public partial class UAuthLogo : ComponentBase -{ - [Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand; - - [Parameter] public int Size { get; set; } = 32; - - [Parameter] public string? ShieldColor { get; set; } = "#00072d"; - [Parameter] public string? KeyColor { get; set; } = "#f6f5ae"; - - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } - - private string BuildStyle() - { - if (Variant == UAuthLogoVariant.Mono) - return $"color: {KeyColor}; {Style}"; - - return Style ?? ""; - } - - protected string KeyPath => @" -M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37 -A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99 -v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153 -V99.79h-8V93.32L108.19,89h12.24 -A11.67,11.67,0,0,0,132.1,77.37V51.11 -A11.67,11.67,0,0,0,120.43,39.44Z - -M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.84a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z - -M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.83a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z - -M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.84a2.91,2.91 0 0 1 -2.91,2.91 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.91 -v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z - -M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.83a2.91,2.91 0 0 1 -2.91,2.92 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.92 -v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z -"; -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogoVariant.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogoVariant.cs deleted file mode 100644 index fe3be220..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Brand/UAuthLogoVariant.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample; - -public enum UAuthLogoVariant -{ - Brand, - Mono -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Common/UAuthDialog.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Common/UAuthDialog.cs deleted file mode 100644 index 2183c80d..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Common/UAuthDialog.cs +++ /dev/null @@ -1,29 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common; - -public static class UAuthDialog -{ - public static DialogParameters GetDialogParameters(UAuthState state, UserKey? userKey = null) - { - DialogParameters parameters = new DialogParameters(); - parameters.Add("AuthState", state); - if (userKey != null ) - { - parameters.Add("UserKey", userKey); - } - return parameters; - } - - public static DialogOptions GetDialogOptions(MaxWidth maxWidth = MaxWidth.Medium) - { - return new DialogOptions - { - MaxWidth = maxWidth, - FullWidth = true, - CloseButton = true - }; - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs index 829e2bb9..24e2046a 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Common; +using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor deleted file mode 100644 index 2806b7d3..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace CodeBeam.UltimateAuth.Sample -@inherits ComponentBase - - - - @if (Variant == UAuthLogoVariant.Brand) - { - - - - } - else - { - - - - } - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor.cs deleted file mode 100644 index 030d9b66..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogo.razor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace CodeBeam.UltimateAuth.Sample; - -public partial class UAuthLogo : ComponentBase -{ - [Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand; - - [Parameter] public int Size { get; set; } = 32; - - [Parameter] public string? ShieldColor { get; set; } = "#00072d"; - [Parameter] public string? KeyColor { get; set; } = "#f6f5ae"; - - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } - - private string BuildStyle() - { - if (Variant == UAuthLogoVariant.Mono) - return $"color: {KeyColor}; {Style}"; - - return Style ?? ""; - } - - protected string KeyPath => @" -M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37 -A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99 -v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153 -V99.79h-8V93.32L108.19,89h12.24 -A11.67,11.67,0,0,0,132.1,77.37V51.11 -A11.67,11.67,0,0,0,120.43,39.44Z - -M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.84a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z - -M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.83a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z - -M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.84a2.91,2.91 0 0 1 -2.91,2.91 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.91 -v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z - -M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.83a2.91,2.91 0 0 1 -2.91,2.92 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.92 -v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z -"; -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogoVariant.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogoVariant.cs deleted file mode 100644 index fe3be220..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Brand/UAuthLogoVariant.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample; - -public enum UAuthLogoVariant -{ - Brand, - Mono -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj index 572d2e70..1ef3e632 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.csproj @@ -8,10 +8,10 @@ - - - - + + + + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Common/UAuthDialog.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Common/UAuthDialog.cs deleted file mode 100644 index 5e52a199..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Common/UAuthDialog.cs +++ /dev/null @@ -1,29 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common; - -public static class UAuthDialog -{ - public static DialogParameters GetDialogParameters(UAuthState state, UserKey? userKey = null) - { - DialogParameters parameters = new DialogParameters(); - parameters.Add("AuthState", state); - if (userKey != null ) - { - parameters.Add("UserKey", userKey); - } - return parameters; - } - - public static DialogOptions GetDialogOptions(MaxWidth maxWidth = MaxWidth.Medium) - { - return new DialogOptions - { - MaxWidth = maxWidth, - FullWidth = true, - CloseButton = true - }; - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor deleted file mode 100644 index fe0ebb2a..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor +++ /dev/null @@ -1,54 +0,0 @@ -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.ResourceApi -@inject ProductApiService Api -@inject ISnackbar Snackbar - - - - - Resource Api - Sample demonstration of a resource. - - - - Reload - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add - - - - - - - \ No newline at end of file diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor.cs deleted file mode 100644 index 33ddb1cc..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Dialogs/ResourceApiDialog.razor.cs +++ /dev/null @@ -1,95 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.ResourceApi; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; - -public partial class ResourceApiDialog -{ - [CascadingParameter] - private IMudDialogInstance MudDialog { get; set; } = default!; - - [Parameter] - public UAuthState AuthState { get; set; } = default!; - - private List _products = new List(); - private string? _newName = null; - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - _products = (await Api.GetAllAsync()).Value ?? new(); - StateHasChanged(); - } - } - - private async Task CommittedItemChanges(SampleProduct item) - { - var result = await Api.UpdateAsync(item.Id, item); - - if (result.IsSuccess) - { - Snackbar.Add("Product updated successfully", Severity.Success); - } - else - { - Snackbar.Add(result?.ErrorText ?? "Failed to update product.", Severity.Error); - } - - return DataGridEditFormAction.Close; - } - - private async Task GetProducts() - { - var result = await Api.GetAllAsync(); - - if (result.IsSuccess) - { - _products = result.Value ?? new(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Process failed.", Severity.Error); - } - } - - private async Task CreateProduct() - { - var product = new SampleProduct - { - Name = _newName - }; - - var result = await Api.CreateAsync(product); - - if (result.IsSuccess) - { - Snackbar.Add("New product created."); - _products = (await Api.GetAllAsync()).Value ?? new(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Process failed.", Severity.Error); - } - } - - private async Task DeleteProduct(int id) - { - var result = await Api.DeleteAsync(id); - - if (result.IsSuccess) - { - Snackbar.Add("Product deleted succesfully.", Severity.Success); - _products = (await Api.GetAllAsync()).Value ?? new(); - } - else - { - Snackbar.Add(result.ErrorText ?? "Process failed.", Severity.Error); - } - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs index 108a3346..9e8133ac 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs @@ -3,8 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Common; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs index c1e90450..a45edb56 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs @@ -1,9 +1,7 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Blazor; +using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Dialogs; using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using MudBlazor; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs index 90c603f5..6ebe7002 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs @@ -2,7 +2,7 @@ using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Infrastructure; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.ResourceApi; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/ProductApiService.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/ProductApiService.cs deleted file mode 100644 index f410db79..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/ProductApiService.cs +++ /dev/null @@ -1,78 +0,0 @@ -using CodeBeam.UltimateAuth.Core.Contracts; -using Microsoft.AspNetCore.Components.WebAssembly.Http; -using System.Net.Http.Json; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.ResourceApi; - -public class ProductApiService -{ - private readonly HttpClient _http; - - public ProductApiService(HttpClient http) - { - _http = http; - } - - private HttpRequestMessage CreateRequest(HttpMethod method, string url, object? body = null) - { - var request = new HttpRequestMessage(method, url); - request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); - - if (body is not null) - { - request.Content = JsonContent.Create(body); - } - - return request; - } - - public Task>> GetAllAsync() - => SendAsync>(CreateRequest(HttpMethod.Get, "/api/products")); - - public Task> GetAsync(int id) - => SendAsync(CreateRequest(HttpMethod.Get, $"/api/products/{id}")); - - public Task> CreateAsync(SampleProduct product) - => SendAsync(CreateRequest(HttpMethod.Post, $"/api/products", product)); - - public Task> UpdateAsync(int id, SampleProduct product) - => SendAsync(CreateRequest(HttpMethod.Put, $"/api/products/{id}", product)); - - public Task> DeleteAsync(int id) - => SendAsync(CreateRequest(HttpMethod.Delete, $"/api/products/{id}")); - - private async Task> SendAsync(HttpRequestMessage request) - { - var response = await _http.SendAsync(request); - - var result = new UAuthResult - { - Status = (int)response.StatusCode, - IsSuccess = response.IsSuccessStatusCode - }; - - if (response.IsSuccessStatusCode) - { - result.Value = await response.Content.ReadFromJsonAsync(); - return result; - } - - result.Problem = await TryReadProblem(response); - return result; - } - - private async Task TryReadProblem(HttpResponseMessage response) - { - try - { - return await response.Content.ReadFromJsonAsync(); - } - catch - { - return new UAuthProblem - { - Title = response.ReasonPhrase - }; - } - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/SampleProduct.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/SampleProduct.cs deleted file mode 100644 index bf145679..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/ResourceApi/SampleProduct.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.ResourceApi; - -public class SampleProduct -{ - public int Id { get; set; } - public string? Name { get; set; } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor deleted file mode 100644 index 2806b7d3..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace CodeBeam.UltimateAuth.Sample -@inherits ComponentBase - - - - @if (Variant == UAuthLogoVariant.Brand) - { - - - - } - else - { - - - - } - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor.cs deleted file mode 100644 index 030d9b66..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogo.razor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace CodeBeam.UltimateAuth.Sample; - -public partial class UAuthLogo : ComponentBase -{ - [Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand; - - [Parameter] public int Size { get; set; } = 32; - - [Parameter] public string? ShieldColor { get; set; } = "#00072d"; - [Parameter] public string? KeyColor { get; set; } = "#f6f5ae"; - - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } - - private string BuildStyle() - { - if (Variant == UAuthLogoVariant.Mono) - return $"color: {KeyColor}; {Style}"; - - return Style ?? ""; - } - - protected string KeyPath => @" -M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37 -A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99 -v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153 -V99.79h-8V93.32L108.19,89h12.24 -A11.67,11.67,0,0,0,132.1,77.37V51.11 -A11.67,11.67,0,0,0,120.43,39.44Z - -M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.84a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z - -M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.83a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z - -M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.84a2.91,2.91 0 0 1 -2.91,2.91 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.91 -v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z - -M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.83a2.91,2.91 0 0 1 -2.91,2.92 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.92 -v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z -"; -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogoVariant.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogoVariant.cs deleted file mode 100644 index fe3be220..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Brand/UAuthLogoVariant.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample; - -public enum UAuthLogoVariant -{ - Brand, - Mono -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Common/UAuthDialog.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Common/UAuthDialog.cs deleted file mode 100644 index caa73d6b..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Common/UAuthDialog.cs +++ /dev/null @@ -1,29 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Common; - -public static class UAuthDialog -{ - public static DialogParameters GetDialogParameters(UAuthState state, UserKey? userKey = null) - { - DialogParameters parameters = new DialogParameters(); - parameters.Add("AuthState", state); - if (userKey != null ) - { - parameters.Add("UserKey", userKey); - } - return parameters; - } - - public static DialogOptions GetDialogOptions(MaxWidth maxWidth = MaxWidth.Medium) - { - return new DialogOptions - { - MaxWidth = maxWidth, - FullWidth = true, - CloseButton = true - }; - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor index d1498eb6..91fce1e2 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor @@ -1,4 +1,5 @@ -@inherits LayoutComponentBase +@using CodeBeam.UltimateAuth.Sample.Shared +@inherits LayoutComponentBase @inject IUAuthClient UAuthClient @inject ISnackbar Snackbar @inject NavigationManager Nav diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs index abbeec3a..c8b0a98f 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs @@ -3,13 +3,12 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UAuth.Sample.IntWasm.Client.Common; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; using System.Security.Claims; using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using CodeBeam.UAuth.Sample.IntWasm.Client.Components.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Common; namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor index 43e409a7..67fd59d3 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor @@ -1,5 +1,6 @@ @page "/login" @using CodeBeam.UltimateAuth.Client.Runtime +@using CodeBeam.UltimateAuth.Sample.Shared @attribute [UAuthLoginPage] @inherits UAuthPageBase diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor index d8eb7138..e5dde04e 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor @@ -1,4 +1,5 @@ -@inject NavigationManager Nav +@using CodeBeam.UltimateAuth.Sample.Shared +@inject NavigationManager Nav diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor index 41c7e05b..17dff016 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor @@ -1,5 +1,6 @@ @page "/register" @using CodeBeam.UltimateAuth.Client.Runtime +@using CodeBeam.UltimateAuth.Sample.Shared @inherits UAuthPageBase @implements IDisposable diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs index adb7d26a..1d62bb98 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs @@ -1,7 +1,7 @@ using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; -using CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; using MudExtensions.Services; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs index 7790e14a..0e635ad4 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs @@ -1,10 +1,10 @@ using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; -using CodeBeam.UAuth.Sample.IntWasm.Client.ResourceApi; using CodeBeam.UAuth.Sample.IntWasm.Components; using CodeBeam.UltimateAuth.Client.AspNetCore; using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using MudBlazor.Services; using MudExtensions.Services; From b0462faa6e8189684f55bd3cdeccae737362dadf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Wed, 14 Oct 2026 21:30:08 +0300 Subject: [PATCH 3/8] DarkModeManager Duplication --- ...CodeBeam.UltimateAuth.Sample.Shared.csproj | 1 + .../Infrastructure/DarkModeManager.cs | 2 +- .../Components/Layout/MainLayout.razor.cs | 2 +- .../Components/Routes.razor | 4 +- .../Infrastructure/DarkModeManager.cs | 45 --------------- .../Program.cs | 3 +- .../uauthhub.db-shm | Bin 32768 -> 32768 bytes .../uauthhub.db-wal | Bin 721032 -> 745752 bytes .../Components/Layout/MainLayout.razor.cs | 2 +- .../Components/Routes.razor | 4 +- .../Infrastructure/DarkModeManager.cs | 45 --------------- .../Program.cs | 3 +- .../Components/Layout/MainLayout.razor.cs | 2 +- .../Components/Routes.razor | 2 +- .../Infrastructure/DarkModeManager.cs | 45 --------------- ...DevelopmentBypassUserIdentifierVerifier.cs | 23 ++++++++ .../DevelopmentCredentialResetNotifier.cs | 21 +++++++ .../Program.cs | 3 +- .../uauth.db-shm | Bin 32768 -> 32768 bytes .../uauth.db-wal | Bin 881712 -> 902312 bytes .../Brand/UAuthLogo.razor | 19 ------ .../Brand/UAuthLogo.razor.cs | 54 ------------------ .../Brand/UAuthLogoVariant.cs | 7 --- .../Common/UAuthDialog.cs | 29 ---------- .../Components/Layout/MainLayout.razor.cs | 2 +- .../Components/Pages/Home.razor.cs | 2 +- .../Components/Routes.razor | 2 +- .../Infrastructure/DarkModeManager.cs | 45 --------------- .../Program.cs | 3 +- .../Layout/MainLayout.razor.cs | 2 +- .../Program.cs | 2 +- .../Routes.razor | 2 +- .../CodeBeam.UAuth.Sample.IntWasm/Program.cs | 2 +- 33 files changed, 65 insertions(+), 313 deletions(-) rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client => CodeBeam.UltimateAuth.Sample.Shared}/Infrastructure/DarkModeManager.cs (93%) delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Infrastructure/DarkModeManager.cs delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Infrastructure/DarkModeManager.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DarkModeManager.cs create mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentBypassUserIdentifierVerifier.cs create mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentCredentialResetNotifier.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogoVariant.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Common/UAuthDialog.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Infrastructure/DarkModeManager.cs diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj index 361c6a59..f1d71e85 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/CodeBeam.UltimateAuth.Sample.Shared.csproj @@ -16,6 +16,7 @@ + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Infrastructure/DarkModeManager.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Infrastructure/DarkModeManager.cs similarity index 93% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Infrastructure/DarkModeManager.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Infrastructure/DarkModeManager.cs index 3f654e18..7b81d010 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Infrastructure/DarkModeManager.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Infrastructure/DarkModeManager.cs @@ -1,7 +1,7 @@ using CodeBeam.UltimateAuth.Client.Contracts; using CodeBeam.UltimateAuth.Client.Infrastructure; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; +namespace CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; public sealed class DarkModeManager { diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs index 4b196823..3445de47 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor index 9d7b5207..a9469874 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor @@ -1,5 +1,5 @@ -@using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Pages -@using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure +@using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Pages @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Infrastructure/DarkModeManager.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Infrastructure/DarkModeManager.cs deleted file mode 100644 index 70ab1af0..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Infrastructure/DarkModeManager.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Contracts; -using CodeBeam.UltimateAuth.Client.Infrastructure; - -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Infrastructure; - -public sealed class DarkModeManager -{ - private const string StorageKey = "uauth:theme:dark"; - - private readonly IClientStorage _storage; - - public DarkModeManager(IClientStorage storage) - { - _storage = storage; - } - - public async Task InitializeAsync() - { - var value = await _storage.GetAsync(StorageScope.Local, StorageKey); - - if (bool.TryParse(value, out var parsed)) - IsDarkMode = parsed; - } - - public bool IsDarkMode { get; set; } - - public event Action? Changed; - - public async Task ToggleAsync() - { - IsDarkMode = !IsDarkMode; - - await _storage.SetAsync(StorageScope.Local, StorageKey, IsDarkMode.ToString()); - Changed?.Invoke(); - } - - public void Set(bool value) - { - if (IsDarkMode == value) - return; - - IsDarkMode = value; - Changed?.Invoke(); - } -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Program.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Program.cs index fe875991..13f1ebb3 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Program.cs +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Program.cs @@ -1,12 +1,11 @@ using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Infrastructure; using CodeBeam.UltimateAuth.EntityFrameworkCore; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore; using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components; -using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Infrastructure; using CodeBeam.UltimateAuth.Server.Extensions; using Microsoft.EntityFrameworkCore; using MudBlazor.Services; diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm index c4334748a8233baae426588b88560f8b98583ce4..0bc9e6b36de9e93a70a20c72a803df438bb2b69a 100644 GIT binary patch delta 743 zcmb7=-AhzK7{;HO;b5?CXwkYww<1AZ7f9d=MP?~WwPk9SS(=%qTk86;do(jEGjl5J zW3{s5wtD(lCoj6_<0ASCVu>IKZ@TF&i10#tXBMH0y6A;xW}f%?&3lGp+uXK!%)hV& zx_l%CAxo8f7X)>+&D9(vAh$rZO`6 zo1Ci7V+%df2G6uEA!UVoeiYFdKD1C?P{iIGZP1K zP6mXdqQxODD$%Kp?AbBE4w&}zPGYJMF{W!*h+8vwhB>lR-Vz)|J(|&r0bHd{Sp6zZ zGiw&lp$xDa$IyTlL~#+r2KZTKb5AW!;Vfbp#5L6y{J}lP(TG;qxP%c+v22;@NQ$j^ zqynOV$qymdQ-{-NLm!54T_ctkH!w~oM{L7X276!OibFV0&2F}u)}$J*Ofy+5qVjvS zD<0zsarsQXt8qmI+BGL~FhP65Dujb%CVo@vio@tIaV{oxtj6lnOjM&wH?1{zfN458 zYP9|%%i0GQFYuBY5o;|TB4MJDM*44KxT8(hemq4A^BPeLO*Bg4uF`K&Ut7rC#69D@ zJ{-XbG@%>)xJ-0h4TWjUE!@xKd8oljoIwvR;EKry+bO?|xXIP$&LvBP5T?kHcFg__ DYdzQ8 delta 703 zcmb7=OKeR+9LB$y$suxkqKH1E37ea4SXikD5lO|ZYBadCRC}&IsM6M@`f~4}t)lAc zcvFwo(W+C8%%&@`Kw>G8F07;*o5rdUu_*tUYa!B2C;4*b`@Y{i&Pd6nRTSAE%5_orPU&k7nCHF>wHK+qdtCa_1RF5s)2rBRGU3sK;3(&`n8P|J*sn93L+* zZh<0Hpc==~iX?h0@S{ZX&|%b|0d0`DWW(7~3M)~I6KKbI^qSDgz!lt}nJ+frq4q>R zQy-#1s0wvBi4I)AWsAAEiUEriU@(onD+@#v%@lU%@8yz0rruTt zDkc&l6L$$4aW>&GhSSxXSl~Rz7+z7)CYIrz0rWsM{n!XzV#37Ea@@xgn)y0a_nFZ{ zN@oQg;Hi!J>*-1RptLzkPd7|4aSb=q?rS5te%!Lo%|bam9K{)Q;v%gb)V*<9dmXpa keKrmvhGS^KIds{+r-k|y?$};`X`OS#UNlnWE18sk00-8~DgXcg diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal index 05e590d5a80ef1657ef8909e218f98e2225fb95c..0abf9f51c191b90158532a35241e5e3337b7ffe9 100644 GIT binary patch delta 12280 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 diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs index 4b35a909..b56ce58f 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.UAuthHub.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor index 22f83d10..a62b6ec5 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor @@ -1,5 +1,5 @@ -@using CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages -@using CodeBeam.UltimateAuth.Sample.UAuthHub.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure +@using CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Infrastructure/DarkModeManager.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Infrastructure/DarkModeManager.cs deleted file mode 100644 index 95b63347..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Infrastructure/DarkModeManager.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Contracts; -using CodeBeam.UltimateAuth.Client.Infrastructure; - -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Infrastructure; - -public sealed class DarkModeManager -{ - private const string StorageKey = "uauth:theme:dark"; - - private readonly IClientStorage _storage; - - public DarkModeManager(IClientStorage storage) - { - _storage = storage; - } - - public async Task InitializeAsync() - { - var value = await _storage.GetAsync(StorageScope.Local, StorageKey); - - if (bool.TryParse(value, out var parsed)) - IsDarkMode = parsed; - } - - public bool IsDarkMode { get; set; } - - public event Action? Changed; - - public async Task ToggleAsync() - { - IsDarkMode = !IsDarkMode; - - await _storage.SetAsync(StorageScope.Local, StorageKey, IsDarkMode.ToString()); - Changed?.Invoke(); - } - - public void Set(bool value) - { - if (IsDarkMode == value) - return; - - IsDarkMode = value; - Changed?.Invoke(); - } -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Program.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Program.cs index 814fd843..592d01b9 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Program.cs +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Program.cs @@ -1,11 +1,10 @@ using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Infrastructure; using CodeBeam.UltimateAuth.InMemory; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Sample.UAuthHub.Components; -using CodeBeam.UltimateAuth.Sample.UAuthHub.Infrastructure; using CodeBeam.UltimateAuth.Server.Extensions; using MudBlazor.Services; using MudExtensions.Services; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs index 8ae19aa7..b4824365 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor index 60331591..b6eefdfc 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor @@ -1,5 +1,5 @@ @using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages -@using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DarkModeManager.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DarkModeManager.cs deleted file mode 100644 index befbcb29..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DarkModeManager.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Contracts; -using CodeBeam.UltimateAuth.Client.Infrastructure; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure; - -public sealed class DarkModeManager -{ - private const string StorageKey = "uauth:theme:dark"; - - private readonly IClientStorage _storage; - - public DarkModeManager(IClientStorage storage) - { - _storage = storage; - } - - public async Task InitializeAsync() - { - var value = await _storage.GetAsync(StorageScope.Local, StorageKey); - - if (bool.TryParse(value, out var parsed)) - IsDarkMode = parsed; - } - - public bool IsDarkMode { get; set; } - - public event Action? Changed; - - public async Task ToggleAsync() - { - IsDarkMode = !IsDarkMode; - - await _storage.SetAsync(StorageScope.Local, StorageKey, IsDarkMode.ToString()); - Changed?.Invoke(); - } - - public void Set(bool value) - { - if (IsDarkMode == value) - return; - - IsDarkMode = value; - Changed?.Invoke(); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentBypassUserIdentifierVerifier.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentBypassUserIdentifierVerifier.cs new file mode 100644 index 00000000..b7992299 --- /dev/null +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentBypassUserIdentifierVerifier.cs @@ -0,0 +1,23 @@ +using CodeBeam.UltimateAuth.Users; +using Microsoft.Extensions.Hosting; + +namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure; + +// TODO: Replace this demo bypass with a real verification challenge flow. +// Never register this implementation in production. +internal sealed class DevelopmentBypassUserIdentifierVerifier(IHostEnvironment environment) : IUserIdentifierVerifier +{ + public const string DemoProof = "demo-verification-bypass"; + + public Task VerifyAsync(UserIdentifierVerificationContext context, CancellationToken ct = default) + { + ct.ThrowIfCancellationRequested(); + + if (!environment.IsDevelopment()) + { + throw new InvalidOperationException("Development verification bypass cannot run outside Development."); + } + + return Task.FromResult(string.Equals(context.Proof, DemoProof, StringComparison.Ordinal)); + } +} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentCredentialResetNotifier.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentCredentialResetNotifier.cs new file mode 100644 index 00000000..6acf68b2 --- /dev/null +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Infrastructure/DevelopmentCredentialResetNotifier.cs @@ -0,0 +1,21 @@ +using CodeBeam.UltimateAuth.Credentials; + +namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure; + +internal sealed class DevelopmentCredentialResetNotifier(ILogger logger) : ICredentialResetNotifier +{ + public Task NotifyAsync(CredentialResetNotification notification, CancellationToken ct = default) + { + ct.ThrowIfCancellationRequested(); + + logger.LogWarning( + "DEVELOPMENT ONLY — Credential reset for tenant {Tenant}, " + + "user {UserKey}. Code: {Code}. Expires at: {ExpiresAt}", + notification.Tenant, + notification.UserKey, + notification.Token, + notification.ExpiresAt); + + return Task.CompletedTask; + } +} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs index 33b5d2af..b76c6436 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs @@ -1,10 +1,8 @@ using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Infrastructure; using CodeBeam.UltimateAuth.EntityFrameworkCore; using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Infrastructure; using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; using CodeBeam.UltimateAuth.Server.Extensions; @@ -13,6 +11,7 @@ using MudBlazor.Services; using MudExtensions.Services; using Scalar.AspNetCore; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; var builder = WebApplication.CreateBuilder(args); diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-shm b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-shm index 7ce3780f4c5345539db7569cb935fc3a17e5dc77..1623f1a4ec3bd7845570d4aa03c43de8ae56ec5e 100644 GIT binary patch delta 191 zcmZo@U}|V!N|1P@%K!pWK+MR%AaEN<`vdU?W&hKU(r!2GfAl=FamDYp{qri>&m|`7 zk*a=ULIbm)G|)gj)s~m1HPX5GPv-zJ>11p&E%i{_=kg;rYNnjXAWZC9|a52@* OpP1DcH?OG;VFCbLyEni9 diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-wal b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/uauth.db-wal index 6e7926c1937d74200f4d2350ffb3db1ae02c4d25..f62ad725bd6ceadc94e7c1be2fe51b421d44a30c 100644 GIT binary patch delta 13335 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 N+q$Z@6{%=f{{&f8t-=5R delta 12622 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 diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor deleted file mode 100644 index 2806b7d3..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor +++ /dev/null @@ -1,19 +0,0 @@ -@namespace CodeBeam.UltimateAuth.Sample -@inherits ComponentBase - - - - @if (Variant == UAuthLogoVariant.Brand) - { - - - - } - else - { - - - - } - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor.cs deleted file mode 100644 index 030d9b66..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogo.razor.cs +++ /dev/null @@ -1,54 +0,0 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Components.Web; - -namespace CodeBeam.UltimateAuth.Sample; - -public partial class UAuthLogo : ComponentBase -{ - [Parameter] public UAuthLogoVariant Variant { get; set; } = UAuthLogoVariant.Brand; - - [Parameter] public int Size { get; set; } = 32; - - [Parameter] public string? ShieldColor { get; set; } = "#00072d"; - [Parameter] public string? KeyColor { get; set; } = "#f6f5ae"; - - [Parameter] public string? Class { get; set; } - [Parameter] public string? Style { get; set; } - - private string BuildStyle() - { - if (Variant == UAuthLogoVariant.Mono) - return $"color: {KeyColor}; {Style}"; - - return Style ?? ""; - } - - protected string KeyPath => @" -M120.43,39.44H79.57A11.67,11.67,0,0,0,67.9,51.11V77.37 -A11.67,11.67,0,0,0,79.57,89H90.51l3.89,3.9v5.32l-3.8,3.81v81.41H99 -v-5.33h13.69V169H108.1v-3.8H99C99,150.76,111.9,153,111.9,153 -V99.79h-8V93.32L108.19,89h12.24 -A11.67,11.67,0,0,0,132.1,77.37V51.11 -A11.67,11.67,0,0,0,120.43,39.44Z - -M79.57,48.19h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.84a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.84a2.91,2.91 0 0 1 2.91,-2.92Z - -M79.57,68.62h5.84a2.92,2.92 0 0 1 2.92,2.92 -v5.83a2.92,2.92 0 0 1 -2.92,2.92 -h-5.84a2.91,2.91 0 0 1 -2.91,-2.92 -v-5.83a2.91,2.91 0 0 1 2.91,-2.92Z - -M114.59,48.19h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.84a2.91,2.91 0 0 1 -2.91,2.91 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.91 -v-5.84a2.92,2.92 0 0 1 2.92,-2.92Z - -M114.59,68.62h5.84a2.92,2.92 0 0 1 2.91,2.92 -v5.83a2.91,2.91 0 0 1 -2.91,2.92 -h-5.84a2.92,2.92 0 0 1 -2.92,-2.92 -v-5.83a2.92,2.92 0 0 1 2.92,-2.92Z -"; -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogoVariant.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogoVariant.cs deleted file mode 100644 index fe3be220..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Brand/UAuthLogoVariant.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample; - -public enum UAuthLogoVariant -{ - Brand, - Mono -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Common/UAuthDialog.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Common/UAuthDialog.cs deleted file mode 100644 index 58dae70b..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Common/UAuthDialog.cs +++ /dev/null @@ -1,29 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Core.Domain; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Common; - -public static class UAuthDialog -{ - public static DialogParameters GetDialogParameters(UAuthState state, UserKey? userKey = null) - { - DialogParameters parameters = new DialogParameters(); - parameters.Add("AuthState", state); - if (userKey != null ) - { - parameters.Add("UserKey", userKey); - } - return parameters; - } - - public static DialogOptions GetDialogOptions(MaxWidth maxWidth = MaxWidth.Medium) - { - return new DialogOptions - { - MaxWidth = maxWidth, - FullWidth = true, - CloseButton = true - }; - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs index 92d16814..dc7cf633 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using Microsoft.AspNetCore.Components; using MudBlazor; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs index ae2f478a..3400db36 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs @@ -3,7 +3,7 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorServer.Common; +using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor index 6586c3fc..71cd2ca8 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor @@ -1,5 +1,5 @@ @using CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages -@using CodeBeam.UltimateAuth.Sample.BlazorServer.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Infrastructure/DarkModeManager.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Infrastructure/DarkModeManager.cs deleted file mode 100644 index 9afcf32f..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Infrastructure/DarkModeManager.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Contracts; -using CodeBeam.UltimateAuth.Client.Infrastructure; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Infrastructure; - -public sealed class DarkModeManager -{ - private const string StorageKey = "uauth:theme:dark"; - - private readonly IClientStorage _storage; - - public DarkModeManager(IClientStorage storage) - { - _storage = storage; - } - - public async Task InitializeAsync() - { - var value = await _storage.GetAsync(StorageScope.Local, StorageKey); - - if (bool.TryParse(value, out var parsed)) - IsDarkMode = parsed; - } - - public bool IsDarkMode { get; set; } - - public event Action? Changed; - - public async Task ToggleAsync() - { - IsDarkMode = !IsDarkMode; - - await _storage.SetAsync(StorageScope.Local, StorageKey, IsDarkMode.ToString()); - Changed?.Invoke(); - } - - public void Set(bool value) - { - if (IsDarkMode == value) - return; - - IsDarkMode = value; - Changed?.Invoke(); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs index 2e5cef70..f9a82269 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs @@ -1,13 +1,12 @@ using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; -using CodeBeam.UltimateAuth.Core.Abstractions; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Infrastructure; using CodeBeam.UltimateAuth.Credentials; using CodeBeam.UltimateAuth.InMemory; using CodeBeam.UltimateAuth.Sample.BlazorServer.Components; using CodeBeam.UltimateAuth.Sample.BlazorServer.Infrastructure; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Server.Extensions; using CodeBeam.UltimateAuth.Users; using Microsoft.AspNetCore.HttpOverrides; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs index 1e788a96..c8a68d95 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs @@ -3,9 +3,9 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; using Microsoft.AspNetCore.Components; using MudBlazor; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; namespace CodeBeam.UAuth.Sample.IntWasm.Client.Layout; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs index 1d62bb98..53e43e82 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs @@ -1,6 +1,6 @@ -using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using MudBlazor.Services; diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor index e102e257..5c7ab182 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor @@ -1,5 +1,5 @@ @using CodeBeam.UAuth.Sample.IntWasm.Client.Pages -@using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs index 0e635ad4..5b91c365 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs @@ -1,9 +1,9 @@ -using CodeBeam.UAuth.Sample.IntWasm.Client.Infrastructure; using CodeBeam.UAuth.Sample.IntWasm.Components; using CodeBeam.UltimateAuth.Client.AspNetCore; using CodeBeam.UltimateAuth.Client.Blazor; using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using MudBlazor.Services; using MudExtensions.Services; From 089a8cba6e72a4812698fb6b96b44e5baeffd8b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Wed, 14 Oct 2026 23:31:34 +0300 Subject: [PATCH 4/8] Pages and Layouts --- .../Custom/UAuthPageComponent.razor | 0 .../Dialogs/AccountStatusDialog.razor | 0 .../Dialogs/AccountStatusDialog.razor.cs | 2 +- .../Dialogs/CreateUserDialog.razor | 0 .../Dialogs/CreateUserDialog.razor.cs | 2 +- .../Dialogs/CredentialDialog.razor | 0 .../Dialogs/CredentialDialog.razor.cs | 2 +- .../Dialogs/IdentifierDialog.razor | 0 .../Dialogs/IdentifierDialog.razor.cs | 2 +- .../Dialogs/PermissionDialog.razor | 0 .../Dialogs/PermissionDialog.razor.cs | 2 +- .../Dialogs/ProfileDialog.razor | 0 .../Dialogs/ProfileDialog.razor.cs | 2 +- .../Dialogs/ResetDialog.razor | 0 .../Dialogs/ResetDialog.razor.cs | 2 +- .../Dialogs/ResourceApiDialog.razor | 2 +- .../Dialogs/ResourceApiDialog.razor.cs | 2 +- .../{ => Components}/Dialogs/RoleDialog.razor | 0 .../Dialogs/RoleDialog.razor.cs | 2 +- .../Dialogs/SessionDialog.razor | 0 .../Dialogs/SessionDialog.razor.cs | 2 +- .../Dialogs/UserDetailDialog.razor | 0 .../Dialogs/UserDetailDialog.razor.cs | 2 +- .../Dialogs/UserRoleDialog.razor | 0 .../Dialogs/UserRoleDialog.razor.cs | 2 +- .../Dialogs/UsersDialog.razor | 0 .../Dialogs/UsersDialog.razor.cs | 2 +- .../LayoutComponents/SampleMainLayout.razor | 57 +++ .../SampleMainLayout.razor.cs} | 10 +- .../PageComponents}/NotAuthorized.razor | 0 .../PageComponents}/NotAuthorized.razor.cs | 2 +- .../SampleAuthorizedTestPage.razor | 30 ++ .../PageComponents/SampleHome.razor | 450 +++++++++++++++++ .../PageComponents/SampleHome.razor.cs} | 8 +- .../PageComponents/SampleLogin.razor | 124 +++++ .../PageComponents/SampleLogin.razor.cs} | 6 +- .../PageComponents/SamplePkceLogin.razor | 132 +++++ .../PageComponents/SamplePkceLogin.razor.cs} | 6 +- .../PageComponents/SampleRegister.razor | 59 +++ .../PageComponents/SampleRegister.razor.cs} | 4 +- .../SampleResetCredential.razor | 17 + .../SampleResetCredential.razor.cs} | 4 +- ...iService.cs => SampleProductApiService.cs} | 11 +- .../Components/Layout/MainLayout.razor | 3 +- .../Components/Pages/Home.razor | 1 + .../Components/Pages/NotAuthorized.razor | 3 +- .../Components/Layout/MainLayout.razor | 3 +- .../Components/Pages/Home.razor | 1 + .../Components/Pages/NotAuthorized.razor | 3 +- .../Components/Layout/MainLayout.razor | 63 +-- .../Components/Layout/MainLayout.razor.cs | 130 ----- .../Components/Pages/AuthorizedTestPage.razor | 25 +- .../Components/Pages/Home.razor | 442 +---------------- .../Components/Pages/Home.razor.cs | 222 --------- .../Components/Pages/Login.razor | 124 +---- .../Components/Pages/Login.razor.cs | 211 -------- .../Components/Pages/NotAuthorized.razor.cs | 15 - .../Components/Pages/Register.razor | 59 +-- .../Components/Pages/ResetCredential.razor | 17 +- .../Components/Pages/ResetCredential.razor.cs | 55 --- .../Components/_Imports.razor | 2 + .../Program.cs | 6 +- .../Custom/UAuthPageComponent.razor | 10 - .../Components/Layout/MainLayout.razor | 62 +-- .../Components/Pages/AuthorizedTestPage.razor | 30 +- .../Components/Pages/Home.razor | 442 +---------------- .../Components/Pages/Home.razor.cs | 222 --------- .../Components/Pages/Login.razor | 124 +---- .../Components/Pages/NotAuthorized.razor | 27 -- .../Components/Pages/NotAuthorized.razor.cs | 15 - .../Components/Pages/Register.razor | 59 +-- .../Components/Pages/Register.razor.cs | 45 -- .../Components/Pages/ResetCredential.razor | 17 +- .../Components/_Imports.razor | 2 + .../Program.cs | 10 +- .../App.razor | 2 +- .../Custom/UAuthPageComponent.razor | 10 - .../Infrastructure/DarkModeManager.cs | 45 -- .../Layout/MainLayout.razor | 62 +-- .../Layout/MainLayout.razor.cs | 130 ----- .../Pages/AuthorizedTestPage.razor | 25 +- .../Pages/Home.razor | 451 +---------------- .../Pages/Login.razor | 132 +---- .../Pages/Login.razor.cs | 215 --------- .../Pages/NotAuthorized.razor | 27 -- .../Pages/Register.razor | 59 +-- .../Pages/Register.razor.cs | 45 -- .../Pages/ResetCredential.razor | 17 +- .../Pages/ResetCredential.razor.cs | 55 --- .../Program.cs | 4 +- .../_Imports.razor | 2 + .../Custom/UAuthPageComponent.razor | 10 - .../Layout/MainLayout.razor | 68 +-- .../Layout/MainLayout.razor.cs | 130 ----- .../Pages/AuthorizedTestPage.razor | 25 +- .../Pages/Home.razor | 452 +----------------- .../Pages/Home.razor.cs | 227 --------- .../Pages/Login.razor | 134 +----- .../Pages/NotAuthorized.razor | 28 -- .../Pages/NotAuthorized.razor.cs | 15 - .../Pages/Register.razor | 61 +-- .../Pages/Register.razor.cs | 45 -- .../Pages/ResetCredential.razor | 17 +- .../Pages/ResetCredential.razor.cs | 55 --- .../Program.cs | 2 +- .../_Imports.razor | 2 + .../CodeBeam.UAuth.Sample.IntWasm/Program.cs | 2 +- 107 files changed, 988 insertions(+), 4964 deletions(-) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore => CodeBeam.UltimateAuth.Sample.Shared}/Components/Custom/UAuthPageComponent.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/AccountStatusDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/AccountStatusDialog.razor.cs (97%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/CreateUserDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/CreateUserDialog.razor.cs (95%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/CredentialDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/CredentialDialog.razor.cs (97%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/IdentifierDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/IdentifierDialog.razor.cs (99%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/PermissionDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/PermissionDialog.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ProfileDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ProfileDialog.razor.cs (97%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ResetDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ResetDialog.razor.cs (94%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ResourceApiDialog.razor (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/ResourceApiDialog.razor.cs (97%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/RoleDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/RoleDialog.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/SessionDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/SessionDialog.razor.cs (99%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UserDetailDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UserDetailDialog.razor.cs (97%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UserRoleDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UserRoleDialog.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UsersDialog.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/{ => Components}/Dialogs/UsersDialog.razor.cs (98%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs} (93%) rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents}/NotAuthorized.razor (100%) rename samples/{blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents}/NotAuthorized.razor.cs (80%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor rename samples/{blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs} (97%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs} (96%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor rename samples/{int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs} (96%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs} (90%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor rename samples/{blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs} (93%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/{ProductApiService.cs => SampleProductApiService.cs} (89%) delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Custom/UAuthPageComponent.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Custom/UAuthPageComponent.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Infrastructure/DarkModeManager.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor.cs delete mode 100644 samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Custom/UAuthPageComponent.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor.cs diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Custom/UAuthPageComponent.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Custom/UAuthPageComponent.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Custom/UAuthPageComponent.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Custom/UAuthPageComponent.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/AccountStatusDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/AccountStatusDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/AccountStatusDialog.razor.cs similarity index 97% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/AccountStatusDialog.razor.cs index a2dcc718..c7fc1d63 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/AccountStatusDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/AccountStatusDialog.razor.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class AccountStatusDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CreateUserDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CreateUserDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CreateUserDialog.razor.cs similarity index 95% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CreateUserDialog.razor.cs index 9b5b3b8e..56b88169 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CreateUserDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CreateUserDialog.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class CreateUserDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CredentialDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CredentialDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CredentialDialog.razor.cs similarity index 97% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CredentialDialog.razor.cs index 68ac8a0e..d860c4b4 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/CredentialDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/CredentialDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class CredentialDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/IdentifierDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/IdentifierDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/IdentifierDialog.razor.cs similarity index 99% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/IdentifierDialog.razor.cs index ebba43ec..0612671d 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/IdentifierDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/IdentifierDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class IdentifierDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/PermissionDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/PermissionDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/PermissionDialog.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/PermissionDialog.razor.cs index 615b4b68..aeb9c1c9 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/PermissionDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/PermissionDialog.razor.cs @@ -2,7 +2,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class PermissionDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ProfileDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ProfileDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ProfileDialog.razor.cs similarity index 97% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ProfileDialog.razor.cs index 7dfa0f58..673a3610 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ProfileDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ProfileDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class ProfileDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResetDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResetDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResetDialog.razor.cs similarity index 94% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResetDialog.razor.cs index 962b7297..96251caf 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResetDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResetDialog.razor.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class ResetDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor index 899fc6de..448d9c1d 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor @@ -1,5 +1,5 @@ @using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi -@inject ProductApiService Api +@inject SampleProductApiService Api @inject ISnackbar Snackbar diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor.cs similarity index 97% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor.cs index 52efdf3b..5c861ecc 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/ResourceApiDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/ResourceApiDialog.razor.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class ResourceApiDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/RoleDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/RoleDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/RoleDialog.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/RoleDialog.razor.cs index cfb78161..6447c7c4 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/RoleDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/RoleDialog.razor.cs @@ -3,7 +3,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class RoleDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/SessionDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/SessionDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/SessionDialog.razor.cs similarity index 99% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/SessionDialog.razor.cs index ee4b392f..2c5d3934 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/SessionDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/SessionDialog.razor.cs @@ -5,7 +5,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class SessionDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserDetailDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserDetailDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserDetailDialog.razor.cs similarity index 97% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserDetailDialog.razor.cs index 9eb1e498..9f4baa1a 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserDetailDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserDetailDialog.razor.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class UserDetailDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserRoleDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserRoleDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserRoleDialog.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserRoleDialog.razor.cs index 0f078f48..47a2c4ae 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UserRoleDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UserRoleDialog.razor.cs @@ -4,7 +4,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class UserRoleDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UsersDialog.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UsersDialog.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UsersDialog.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UsersDialog.razor.cs index 4550ad3a..e945d65a 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Dialogs/UsersDialog.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Dialogs/UsersDialog.razor.cs @@ -6,7 +6,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; public partial class UsersDialog { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor new file mode 100644 index 00000000..4d367b16 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor @@ -0,0 +1,57 @@ +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar +@inject NavigationManager Nav + + + + + UltimateAuth + + @Title + + + + + + + + + +
+ + + @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") + + +
+
+ + + @state.Identity?.DisplayName + @string.Join(", ", state.Claims.Roles) + + + + + + + + @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) + { + + + } + +
+
+ + + + +
+
+ + + @ChildContent + +
diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs similarity index 93% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs index dc7cf633..9b2b00a4 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs @@ -7,9 +7,9 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Layout; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents; -public partial class MainLayout +public partial class SampleMainLayout { [CascadingParameter] public UAuthState UAuth { get; set; } = default!; @@ -17,6 +17,12 @@ public partial class MainLayout [CascadingParameter] public DarkModeManager DarkModeManager { get; set; } = default!; + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; + + [Parameter] + public string? Title { get; set; } + private async Task Refresh() { await UAuthClient.Flows.RefreshAsync(); diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor similarity index 100% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs similarity index 80% rename from samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs index f46ca21f..f077c666 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs @@ -1,4 +1,4 @@ -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; public partial class NotAuthorized { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor new file mode 100644 index 00000000..20d3062f --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor @@ -0,0 +1,30 @@ +@using CodeBeam.UltimateAuth.Core.Defaults +@inherits UAuthPageBase + + + + + + + Everything is Ok + + + If you see this section, it means you succesfully logged in. + + + + Go Home Page + + + + + + This is admin view content. + + + + UltimateAuth protects this resource based on your session and permissions. + + + + diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor new file mode 100644 index 00000000..ec51e981 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor @@ -0,0 +1,450 @@ +@inherits UAuthPageBase + +@inject IUAuthClient UAuthClient +@inject UAuthClientDiagnostics Diagnostics +@inject AuthenticationStateProvider AuthStateProvider +@inject ISnackbar Snackbar +@inject IDialogService DialogService +@using CodeBeam.UltimateAuth.Client.Diagnostics +@using CodeBeam.UltimateAuth.Core.Contracts +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Custom +@using Microsoft.AspNetCore.Components.Authorization + +@if (AuthState?.Identity?.UserStatus == UserStatus.SelfSuspended) +{ + + + + Your account is suspended. Please active it before continue. + + + + Set Active + Logout + + + + return; +} + +@if (AuthState?.Identity?.UserStatus == UserStatus.Suspended) +{ + + + + Your account is suspended. Please contact with administrator. + + + + Logout + + + + return; +} + + + + + + + + + + + Session + + + + + + + Validate + + + + + + Manual Refresh + + + + + + Logout + + + + + + Account + + + + + Manage Sessions + + + + Manage Profile + + + + Manage Identifiers + + + + Manage Credentials + + + + Suspend | Delete Account + + + + Admin + + + + + + + + + @if (_showAdminPreview) + { + + Admin operations are shown for preview. Sign in as an Admin to execute them. + + } + + @if (AuthState?.IsInRole("Admin") == true || _showAdminPreview) + { + + + + @* *@ + @* *@ + User Management + @* *@ + + + + + + @* *@ + Role Management + @* *@ + + + + } + + + Resource Api + + + + + Manage Resource + + + + + + + + + + + + @((AuthState?.Identity?.DisplayName ?? "?").Substring(0, Math.Min(2, (AuthState?.Identity?.DisplayName ?? "?").Length))) + + + + @AuthState?.Identity?.DisplayName + + @foreach (var role in AuthState?.Claims?.Roles ?? Enumerable.Empty()) + { + + @role + + } + + + + + + + + + + @if (_selectedAuthState == "UAuthState") + { + + +
+ + + Tenant + + @AuthState?.Identity?.Tenant.Value +
+ +
+ + +
+ + + User Id + + @AuthState?.Identity?.UserKey.Value +
+
+ + +
+ + + Authenticated + + @(AuthState?.IsAuthenticated == true ? "Yes" : "No") +
+
+ + +
+ + + Session State + + @AuthState?.Identity?.SessionState?.ToDescriptionString() +
+
+ + +
+ + + Username + + @AuthState?.Identity?.PrimaryUserName +
+
+ + +
+ + + Display Name + + @AuthState?.Identity?.DisplayName +
+
+ + + + + + + Email + + @AuthState?.Identity?.PrimaryEmail + + + + + + Phone + + @AuthState?.Identity?.PrimaryPhone + + + + + + + + Authenticated At + + @* TODO: Add IUAuthDateTimeFormatter *@ + @FormatLocalTime(AuthState?.Identity?.AuthenticatedAt) + + + + + + Last Validated At + + @* TODO: Validation call should update last validated at *@ + @FormatLocalTime(AuthState?.LastValidatedAt) + +
+ } + else if (_selectedAuthState == "AspNetCoreState") + { + + +
+ + + Authenticated + + @(_aspNetCoreState?.Identity?.IsAuthenticated == true ? "Yes" : "No") +
+
+ + +
+ + + User Id + + @_aspNetCoreState?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value +
+
+ + +
+ + + Username + + @_aspNetCoreState?.Identity?.Name +
+
+ + +
+ + + Authentication Type + + @_aspNetCoreState?.Identity?.AuthenticationType +
+
+
+ } +
+
+
+ + + + + + @GetHealthText() + + + Lifecycle + + + + + + Started + @Diagnostics.StartCount + + @if (Diagnostics.StartedAt is not null) + { + + + + @FormatRelative(Diagnostics.StartedAt) + + + } + + + + + Stopped + @Diagnostics.StopCount + + + + + + Terminated + @Diagnostics.TerminatedCount + + @if (Diagnostics.TerminatedAt is not null) + { + + + + + @FormatRelative(Diagnostics.TerminatedAt) + + + + } + + + + + + Refresh Metrics + + + + + + + Total Attempts + @Diagnostics.RefreshAttemptCount + + + + + + + Success + + @Diagnostics.RefreshSuccessCount + + + + + + Automatic + @Diagnostics.AutomaticRefreshCount + + + + + + Manual + @Diagnostics.ManualRefreshCount + + + + + + Touched/Rotated + @Diagnostics.RefreshTouchedCount / @Diagnostics.RefreshRotatedCount + + + + + + No-Op + @Diagnostics.RefreshNoOpCount + + + + + + Reauth Required + @Diagnostics.RefreshReauthRequiredCount + + + + + + + +
+
+
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs similarity index 97% rename from samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs index 9e8133ac..e2aa3f42 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs @@ -3,16 +3,16 @@ using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.Shared.Common; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; using CodeBeam.UltimateAuth.Users.Contracts; using Microsoft.AspNetCore.Components.Authorization; using MudBlazor; using System.Security.Claims; +using CodeBeam.UltimateAuth.Sample.Shared.Common; +using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; -public partial class Home : UAuthPageBase +public partial class SampleHome : UAuthPageBase { private string _selectedAuthState = "UAuthState"; private ClaimsPrincipal? _aspNetCoreState; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor new file mode 100644 index 00000000..34219171 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor @@ -0,0 +1,124 @@ +@inherits UAuthPageBase + +@implements IDisposable +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar +@inject IUAuthClientProductInfoProvider ClientProductInfoProvider +@inject IDeviceIdProvider DeviceIdProvider +@inject IDialogService DialogService + + + + + + + + + + + + + + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs similarity index 96% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs index a90b7e04..4853e261 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs @@ -2,12 +2,12 @@ using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; +using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; -public partial class Login : UAuthPageBase +public partial class SampleLogin : UAuthPageBase { private string? _username; private string? _password; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor new file mode 100644 index 00000000..3850685d --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor @@ -0,0 +1,132 @@ +@inherits UAuthPageBase + +@implements IDisposable +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar +@inject IUAuthClientProductInfoProvider ClientProductInfoProvider +@inject IDeviceIdProvider DeviceIdProvider +@inject IDialogService DialogService + + + + + + + + + + + + + + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs similarity index 96% rename from samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs index 29a2aead..734bf9e0 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs @@ -2,12 +2,12 @@ using CodeBeam.UltimateAuth.Client.Runtime; using CodeBeam.UltimateAuth.Core.Contracts; using CodeBeam.UltimateAuth.Core.Domain; +using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; using MudBlazor; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; -public partial class Login : UAuthPageBase +public partial class SamplePkceLogin : UAuthPageBase { private string? _username; private string? _password; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor new file mode 100644 index 00000000..98c53f24 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor @@ -0,0 +1,59 @@ +@inherits UAuthPageBase + +@implements IDisposable +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar +@inject IUAuthClientProductInfoProvider ClientProductInfoProvider +@inject IDeviceIdProvider DeviceIdProvider +@inject IDialogService DialogService + + + + + + + + + + + + + + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs similarity index 90% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs index 41eadd64..e439cf69 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs @@ -2,9 +2,9 @@ using CodeBeam.UltimateAuth.Users.Contracts; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; -public partial class Register +public partial class SampleRegister { private string? _username; private string? _password; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor new file mode 100644 index 00000000..38d911f5 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor @@ -0,0 +1,17 @@ +@inherits UAuthPageBase + +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar + + + + + + + + + Change Password + + + + \ No newline at end of file diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs similarity index 93% rename from samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs index 44c1f1a0..c29f1add 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs @@ -1,9 +1,9 @@ using CodeBeam.UltimateAuth.Credentials.Contracts; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; -public partial class ResetCredential +public partial class SampleResetCredential { private MudForm _form = null!; private string? _code; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProductApiService.cs similarity index 89% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProductApiService.cs index 95176ea1..fb7c954f 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/ProductApiService.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/ResourceApi/SampleProductApiService.cs @@ -4,19 +4,22 @@ namespace CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; -public class ProductApiService +public class SampleProductApiService { private readonly HttpClient _http; - public ProductApiService(IHttpClientFactory factory) + public SampleProductApiService(HttpClient factory) { - _http = factory.CreateClient("resourceApi"); + _http = factory; } private HttpRequestMessage CreateRequest(HttpMethod method, string url, object? body = null) { var request = new HttpRequestMessage(method, url); - request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); + if (OperatingSystem.IsBrowser()) + { + request.SetBrowserRequestCredentials(BrowserRequestCredentials.Include); + } if (body is not null) { diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor index 8eec2be6..cbe248e0 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor @@ -1,4 +1,5 @@ -@inherits UAuthHubLayoutBase +@using CodeBeam.UltimateAuth.Sample.Shared +@inherits UAuthHubLayoutBase @inject IUAuthClient UAuthClient @inject ISnackbar Snackbar @inject NavigationManager Nav diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor index b1720a39..dfd4c249 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor @@ -9,6 +9,7 @@ @using CodeBeam.UltimateAuth.Client.Runtime @using CodeBeam.UltimateAuth.Core.Abstractions @using CodeBeam.UltimateAuth.Core.Contracts +@using CodeBeam.UltimateAuth.Sample.Shared @using CodeBeam.UltimateAuth.Server.Services @using CodeBeam.UltimateAuth.Server.Stores @using Microsoft.Extensions.Options diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor index 2c0e9b77..d6dee0ec 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor @@ -1,4 +1,5 @@ -@inject NavigationManager Nav +@using CodeBeam.UltimateAuth.Sample.Shared +@inject NavigationManager Nav diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor index 8eec2be6..cbe248e0 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor @@ -1,4 +1,5 @@ -@inherits UAuthHubLayoutBase +@using CodeBeam.UltimateAuth.Sample.Shared +@inherits UAuthHubLayoutBase @inject IUAuthClient UAuthClient @inject ISnackbar Snackbar @inject NavigationManager Nav diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor index b1720a39..dfd4c249 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor @@ -9,6 +9,7 @@ @using CodeBeam.UltimateAuth.Client.Runtime @using CodeBeam.UltimateAuth.Core.Abstractions @using CodeBeam.UltimateAuth.Core.Contracts +@using CodeBeam.UltimateAuth.Sample.Shared @using CodeBeam.UltimateAuth.Server.Services @using CodeBeam.UltimateAuth.Server.Stores @using Microsoft.Extensions.Options diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor index 2c0e9b77..d6dee0ec 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor @@ -1,4 +1,5 @@ -@inject NavigationManager Nav +@using CodeBeam.UltimateAuth.Sample.Shared +@inject NavigationManager Nav diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor index 2e4a24bb..ea3fe463 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor @@ -1,62 +1,9 @@ -@inherits LayoutComponentBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav - - - - - UltimateAuth - - Blazor Server EFCore Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
+@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents +@inherits LayoutComponentBase + + @Body +
An unhandled error has occurred. diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs deleted file mode 100644 index b4824365..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,130 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Layout; - -public partial class MainLayout -{ - [CascadingParameter] - public UAuthState UAuth { get; set; } = default!; - - [CascadingParameter] - public DarkModeManager DarkModeManager { get; set; } = default!; - - private async Task Refresh() - { - await UAuthClient.Flows.RefreshAsync(); - } - - private async Task Logout() - { - await UAuthClient.Flows.LogoutAsync(); - } - - private Color GetBadgeColor() - { - if (UAuth is null || !UAuth.IsAuthenticated) - return Color.Error; - - if (UAuth.IsStale) - return Color.Warning; - - var state = UAuth.Identity?.SessionState; - - if (state is null || state == SessionState.Active) - return Color.Success; - - if (state == SessionState.Invalid) - return Color.Error; - - return Color.Warning; - } - - private void HandleSignInClick() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login?focus=1", replace: true, forceLoad: true); - return; - } - - GoToLoginWithReturn(); - } - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private void GoToLoginWithReturn() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login", replace: true); - return; - } - - var current = Nav.ToBaseRelativePath(uri.ToString()); - if (string.IsNullOrWhiteSpace(current)) - current = "home"; - - var returnUrl = Uri.EscapeDataString("/" + current.TrimStart('/')); - Nav.NavigateTo($"/login?returnUrl={returnUrl}", replace: true); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/AuthorizedTestPage.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/AuthorizedTestPage.razor index a5e4fde7..0a953043 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/AuthorizedTestPage.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/AuthorizedTestPage.razor @@ -1,27 +1,4 @@ @page "/authorized-test" @attribute [UAuthAuthorize] -@inherits UAuthPageBase - - - - - - Everything is Ok - - - If you see this section, it means you succesfully logged in. - - - - Go Profile - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor index 162c37ea..945a4332 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor @@ -1,444 +1,4 @@ @page "/home" @attribute [UAuthAuthorize] -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject UAuthClientDiagnostics Diagnostics -@inject AuthenticationStateProvider AuthStateProvider -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@using System.Security.Claims -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Custom -@using Microsoft.AspNetCore.Authorization - -@if (AuthState?.Identity?.UserStatus == UserStatus.SelfSuspended) -{ - - - - Your account is suspended. Please active it before continue. - - - - Set Active - Logout - - - - return; -} - -@if (AuthState?.Identity?.UserStatus == UserStatus.Suspended) -{ - - - - Your account is suspended. Please contact with administrator. - - - - Logout - - - - return; -} - - - - - - - - - - - Session - - - - - - - Validate - - - - - - Manual Refresh - - - - - - Logout - - - - - - Account - - - - - Manage Sessions - - - - Manage Profile - - - - Manage Identifiers - - - - Manage Credentials - - - - Suspend | Delete Account - - - - Admin - - - - - - - - - @if (_showAdminPreview) - { - - Admin operations are shown for preview. Sign in as an Admin to execute them. - - } - - @if (AuthState?.IsInRole("Admin") == true || _showAdminPreview) - { - - - - @* *@ - @* *@ - User Management - @* *@ - - - - - - @* *@ - Role Management - @* *@ - - - - } - - - - - - - - - - - @((AuthState?.Identity?.DisplayName ?? "?").Substring(0, Math.Min(2, (AuthState?.Identity?.DisplayName ?? "?").Length))) - - - - @AuthState?.Identity?.DisplayName - - @foreach (var role in AuthState?.Claims?.Roles ?? Enumerable.Empty()) - { - - @role - - } - - - - - - - - - - @if (_selectedAuthState == "UAuthState") - { - - -
- - - Tenant - - @AuthState?.Identity?.Tenant.Value -
- -
- - -
- - - User Id - - @AuthState?.Identity?.UserKey.Value -
-
- - -
- - - Authenticated - - @(AuthState?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - Session State - - @AuthState?.Identity?.SessionState?.ToDescriptionString() -
-
- - -
- - - Username - - @AuthState?.Identity?.PrimaryUserName -
-
- - -
- - - Display Name - - @AuthState?.Identity?.DisplayName -
-
- - - - - - - Email - - @AuthState?.Identity?.PrimaryEmail - - - - - - Phone - - @AuthState?.Identity?.PrimaryPhone - - - - - - - - Authenticated At - - @* TODO: Add IUAuthDateTimeFormatter *@ - @FormatLocalTime(AuthState?.Identity?.AuthenticatedAt) - - - - - - Last Validated At - - @* TODO: Validation call should update last validated at *@ - @FormatLocalTime(AuthState?.LastValidatedAt) - -
- } - else if (_selectedAuthState == "AspNetCoreState") - { - - -
- - - Authenticated - - @(_aspNetCoreState?.Identity?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - User Id - - @_aspNetCoreState?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value -
-
- - -
- - - Username - - @_aspNetCoreState?.Identity?.Name -
-
- - -
- - - Authentication Type - - @_aspNetCoreState?.Identity?.AuthenticationType -
-
-
- } -
-
-
- - - - - - @GetHealthText() - - - Lifecycle - - - - - - Started - @Diagnostics.StartCount - - @if (Diagnostics.StartedAt is not null) - { - - - - @FormatRelative(Diagnostics.StartedAt) - - - } - - - - - Stopped - @Diagnostics.StopCount - - - - - - Terminated - @Diagnostics.TerminatedCount - - @if (Diagnostics.TerminatedAt is not null) - { - - - - - @FormatRelative(Diagnostics.TerminatedAt) - - - - } - - - - - - Refresh Metrics - - - - - - - Total Attempts - @Diagnostics.RefreshAttemptCount - - - - - - - Success - - @Diagnostics.RefreshSuccessCount - - - - - - Automatic - @Diagnostics.AutomaticRefreshCount - - - - - - Manual - @Diagnostics.ManualRefreshCount - - - - - - Touched/Rotated - @Diagnostics.RefreshTouchedCount / @Diagnostics.RefreshRotatedCount - - - - - - No-Op - @Diagnostics.RefreshNoOpCount - - - - - - Reauth Required - @Diagnostics.RefreshReauthRequiredCount - - - - - - - -
-
-
+ \ No newline at end of file diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs deleted file mode 100644 index 24e2046a..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Home.razor.cs +++ /dev/null @@ -1,222 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.Shared.Common; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components.Authorization; -using MudBlazor; -using System.Security.Claims; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; - -public partial class Home : UAuthPageBase -{ - private string _selectedAuthState = "UAuthState"; - private ClaimsPrincipal? _aspNetCoreState; - - private bool _showAdminPreview = false; - - protected override async Task OnInitializedAsync() - { - var initial = await AuthStateProvider.GetAuthenticationStateAsync(); - _aspNetCoreState = initial.User; - AuthStateProvider.AuthenticationStateChanged += OnAuthStateChanged; - Diagnostics.Changed += OnDiagnosticsChanged; - } - - private void OnAuthStateChanged(Task task) - { - _ = HandleAuthStateChangedAsync(task); - } - - private async Task HandleAuthStateChangedAsync(Task task) - { - try - { - var state = await task; - _aspNetCoreState = state.User; - await InvokeAsync(StateHasChanged); - } - catch - { - - } - } - - private void OnDiagnosticsChanged() - { - InvokeAsync(StateHasChanged); - } - - private async Task Logout() => await UAuthClient.Flows.LogoutAsync(); - - private async Task RefreshSession() => await UAuthClient.Flows.RefreshAsync(false); - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private Color GetHealthColor() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return Color.Warning; - - if (Diagnostics.TerminatedCount > 0) - return Color.Error; - - return Color.Success; - } - - private string GetHealthText() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return "Reauthentication Required"; - - if (Diagnostics.TerminatedCount > 0) - return "Session Terminated"; - - return "Healthy"; - } - - private string? FormatRelative(DateTimeOffset? utc) - { - if (utc is null) - return null; - - var diff = DateTimeOffset.UtcNow - utc.Value; - - if (diff.TotalSeconds < 5) - return "just now"; - - if (diff.TotalSeconds < 60) - return $"{(int)diff.Seconds} secs ago"; - - if (diff.TotalMinutes < 60) - return $"{(int)diff.TotalMinutes} min ago"; - - if (diff.TotalHours < 24) - return $"{(int)diff.TotalHours} hrs ago"; - - return utc.Value.ToLocalTime().ToString("dd MMM yyyy"); - } - - private string? FormatLocalTime(DateTimeOffset? utc) - { - return utc?.ToLocalTime().ToString("dd MMM yyyy • HH:mm:ss"); - } - - private async Task OpenProfileDialog() - { - await DialogService.ShowAsync("Manage Profile", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifierDialog() - { - await DialogService.ShowAsync("Manage Identifiers", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenSessionDialog() - { - await DialogService.ShowAsync("Manage Sessions", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentialDialog() - { - await DialogService.ShowAsync("Session Diagnostics", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenAccountStatusDialog() - { - await DialogService.ShowAsync("Manage Account", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.ExtraSmall)); - } - - private async Task OpenUserDialog() - { - await DialogService.ShowAsync("User Management", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.Large)); - } - - private async Task OpenRoleDialog() - { - await DialogService.ShowAsync("Role Management", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private DialogParameters GetDialogParameters() - { - return new DialogParameters - { - ["AuthState"] = AuthState - }; - } - - private async Task SetAccountActiveAsync() - { - ChangeUserStatusSelfRequest request = new() { NewStatus = SelfAssignableUserStatus.Active }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Account activated successfully.", Severity.Success); - } - else - { - Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Activation failed.", Severity.Error); - } - } - - public override void Dispose() - { - base.Dispose(); - AuthStateProvider.AuthenticationStateChanged -= OnAuthStateChanged; - Diagnostics.Changed -= OnDiagnosticsChanged; - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor index 5eec659a..65d20ded 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor @@ -1,126 +1,4 @@ @page "/login" @attribute [UAuthLoginPage] -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs deleted file mode 100644 index 4c764bf5..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Login.razor.cs +++ /dev/null @@ -1,211 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; - -public partial class Login : UAuthPageBase -{ - private string? _username; - private string? _password; - private UAuthClientProductInfo? _productInfo; - private MudTextField _usernameField = default!; - - private CancellationTokenSource? _lockoutCts; - private PeriodicTimer? _lockoutTimer; - private DateTimeOffset? _lockoutUntil; - private TimeSpan _remaining; - private bool _isLocked; - private DateTimeOffset? _lockoutStartedAt; - private TimeSpan _lockoutDuration; - private double _progressPercent; - private int? _remainingAttempts = null; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - protected override Task OnUAuthPayloadAsync(AuthFlowPayload payload) - { - HandleLoginPayload(payload); - return Task.CompletedTask; - } - - protected override async Task OnFocusRequestedAsync() - { - await _usernameField.FocusAsync(); - } - - private void HandleLoginPayload(AuthFlowPayload payload) - { - if (payload.Flow != AuthFlowType.Login) - return; - - if (payload.Reason == AuthFailureReason.LockedOut && payload.LockoutUntilUtc is { } until) - { - _lockoutUntil = until; - StartCountdown(); - } - - _remainingAttempts = payload.RemainingAttempts; - ShowLoginError(payload.Reason, payload.RemainingAttempts); - } - - private void ShowLoginError(AuthFailureReason? reason, int? remainingAttempts) - { - string message = reason switch - { - AuthFailureReason.InvalidCredentials when remainingAttempts is > 0 - => $"Invalid username or password. {remainingAttempts} attempt(s) remaining.", - - AuthFailureReason.InvalidCredentials - => "Invalid username or password.", - - AuthFailureReason.RequiresMfa - => "Multi-factor authentication required.", - - AuthFailureReason.LockedOut - => "Your account is locked.", - - _ => "Login failed." - }; - - Snackbar.Add(message, Severity.Error); - } - - private async Task ProgrammaticLogin() - { - var request = new LoginRequest - { - Identifier = "admin", - Secret = "admin", - }; - await UAuthClient.Flows.LoginAsync(request, ReturnUrl ?? "/home"); - } - - private async void StartCountdown() - { - if (_lockoutUntil is null) - return; - - _isLocked = true; - _lockoutStartedAt = DateTimeOffset.UtcNow; - _lockoutDuration = _lockoutUntil.Value - DateTimeOffset.UtcNow; - UpdateRemaining(); - - _lockoutCts?.Cancel(); - _lockoutCts = new CancellationTokenSource(); - - _lockoutTimer?.Dispose(); - _lockoutTimer = new PeriodicTimer(TimeSpan.FromSeconds(1)); - - try - { - while (await _lockoutTimer.WaitForNextTickAsync(_lockoutCts.Token)) - { - UpdateRemaining(); - - if (_remaining <= TimeSpan.Zero) - { - ResetLockoutState(); - await InvokeAsync(StateHasChanged); - break; - } - - await InvokeAsync(StateHasChanged); - } - } - catch (OperationCanceledException) - { - - } - } - - private void ResetLockoutState() - { - _isLocked = false; - _lockoutUntil = null; - _progressPercent = 0; - _remainingAttempts = null; - } - - private void UpdateRemaining() - { - if (_lockoutUntil is null || _lockoutStartedAt is null) - return; - - var now = DateTimeOffset.UtcNow; - - _remaining = _lockoutUntil.Value - now; - - if (_remaining <= TimeSpan.Zero) - { - _remaining = TimeSpan.Zero; - return; - } - - var elapsed = now - _lockoutStartedAt.Value; - - if (_lockoutDuration.TotalSeconds > 0) - { - var percent = 100 - (elapsed.TotalSeconds / _lockoutDuration.TotalSeconds * 100); - _progressPercent = Math.Max(0, percent); - } - } - - private void HandleTry(IUAuthTryResult result) - { - if (result is TryLoginResult pkce) - { - if (!result.IsSuccess) - { - if (result.Reason == AuthFailureReason.LockedOut && result.LockoutUntilUtc is { } until) - { - _lockoutUntil = until; - StartCountdown(); - } - - _remainingAttempts = result.RemainingAttempts; - ShowLoginError(result.Reason, result.RemainingAttempts); - } - } - else - { - Snackbar.Add("Unexpected result type.", Severity.Error); - } - } - - private async Task OpenResetDialog() - { - await DialogService.ShowAsync("Reset Credentials", GetDialogParameters(), GetDialogOptions()); - } - - private DialogOptions GetDialogOptions() - { - return new DialogOptions - { - MaxWidth = MaxWidth.Medium, - FullWidth = true, - CloseButton = true - }; - } - - private DialogParameters GetDialogParameters() - { - return new DialogParameters - { - ["AuthState"] = AuthState - }; - } - - public override void Dispose() - { - base.Dispose(); - _lockoutCts?.Cancel(); - _lockoutTimer?.Dispose(); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor.cs deleted file mode 100644 index b38fbe97..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/NotAuthorized.razor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; - -public partial class NotAuthorized -{ - private string LoginHref - { - get - { - var returnUrl = Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri)); - return $"/login?returnUrl=/{returnUrl}"; - } - } - - private void GoBack() => Nav.NavigateTo("/", replace: false); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor index 20b38b75..745143b0 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/Register.razor @@ -1,60 +1,3 @@ @page "/register" -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor index 2623395b..f2c1a536 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor @@ -1,18 +1,3 @@ @page "/reset" -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - - - - - - Change Password - - - - \ No newline at end of file + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor.cs deleted file mode 100644 index 1569f1f4..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/ResetCredential.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Credentials.Contracts; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; - -public partial class ResetCredential -{ - private MudForm _form = null!; - private string? _code; - private string? _newPassword; - private string? _newPasswordCheck; - - private async Task ResetPasswordAsync() - { - await _form.ValidateAsync(); - if (!_form.IsValid) - { - Snackbar.Add("Please fix the validation errors.", Severity.Error); - return; - } - - if (_newPassword != _newPasswordCheck) - { - Snackbar.Add("Passwords do not match.", Severity.Error); - return; - } - - if (string.IsNullOrEmpty(_code) || string.IsNullOrEmpty(_newPassword) || string.IsNullOrEmpty(Identifier)) - { - Snackbar.Add("Missing required information. Please ensure you have a valid reset code and new password.", Severity.Error); - return; - } - - var request = new CompleteResetCredentialRequest - { - ResetToken = _code, - NewSecret = _newPassword, - Identifier = Identifier // Coming from UAuthFlowPageBase automatically if begin reset is successful - }; - - var result = await UAuthClient.Credentials.CompleteResetAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Credential reset successfully. Please log in with your new password.", Severity.Success); - Navigation.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.Problem?.Detail ?? result.Problem?.Title ?? "Failed to reset credential. Please try again.", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor index 59225b8c..33c08f5c 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor @@ -19,5 +19,7 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents + @using MudBlazor @using MudExtensions diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs index b76c6436..0be8bbef 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Program.cs @@ -2,16 +2,17 @@ using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.EntityFrameworkCore; -using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components; using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore; +using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using CodeBeam.UltimateAuth.Server.Extensions; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.EntityFrameworkCore; using MudBlazor.Services; using MudExtensions.Services; using Scalar.AspNetCore; -using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; var builder = WebApplication.CreateBuilder(args); @@ -65,6 +66,7 @@ }); builder.Services.AddScopedUltimateAuthSampleSeed(); +builder.Services.AddScoped(); builder.Services.Configure(options => { diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Custom/UAuthPageComponent.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Custom/UAuthPageComponent.razor deleted file mode 100644 index 5af543e4..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Custom/UAuthPageComponent.razor +++ /dev/null @@ -1,10 +0,0 @@ - - - @ChildContent - - - -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor index 7239bf28..ac8e53e1 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor @@ -1,61 +1,9 @@ -@inherits LayoutComponentBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav +@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents +@inherits LayoutComponentBase - - - - UltimateAuth - - Blazor Server Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
+ + @Body +
diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/AuthorizedTestPage.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/AuthorizedTestPage.razor index 0b3772f8..0a953043 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/AuthorizedTestPage.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/AuthorizedTestPage.razor @@ -1,32 +1,4 @@ @page "/authorized-test" -@using CodeBeam.UltimateAuth.Core.Defaults @attribute [UAuthAuthorize] -@inherits UAuthPageBase - - - - - - Everything is Ok - - - If you see this section, it means you succesfully logged in. - - - - Go Home Page - - - - - - This is admin view content. - - - - UltimateAuth protects this resource based on your session and permissions. - - - - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor index 0e90fd7a..3e74e98b 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor @@ -1,444 +1,4 @@ @page "/home" @attribute [UAuthAuthorize] -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject UAuthClientDiagnostics Diagnostics -@inject AuthenticationStateProvider AuthStateProvider -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@using System.Security.Claims -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Custom -@using Microsoft.AspNetCore.Authorization - -@if (AuthState?.Identity?.UserStatus == UserStatus.SelfSuspended) -{ - - - - Your account is suspended. Please active it before continue. - - - - Set Active - Logout - - - - return; -} - -@if (AuthState?.Identity?.UserStatus == UserStatus.Suspended) -{ - - - - Your account is suspended. Please contact with administrator. - - - - Logout - - - - return; -} - - - - - - - - - - - Session - - - - - - - Validate - - - - - - Manual Refresh - - - - - - Logout - - - - - - Account - - - - - Manage Sessions - - - - Manage Profile - - - - Manage Identifiers - - - - Manage Credentials - - - - Suspend | Delete Account - - - - Admin - - - - - - - - - @if (_showAdminPreview) - { - - Admin operations are shown for preview. Sign in as an Admin to execute them. - - } - - @if (AuthState?.IsInRole("Admin") == true || _showAdminPreview) - { - - - - @* *@ - @* *@ - User Management - @* *@ - - - - - - @* *@ - Role Management - @* *@ - - - - } - - - - - - - - - - - @((AuthState?.Identity?.DisplayName ?? "?").Substring(0, Math.Min(2, (AuthState?.Identity?.DisplayName ?? "?").Length))) - - - - @AuthState?.Identity?.DisplayName - - @foreach (var role in AuthState?.Claims?.Roles ?? Enumerable.Empty()) - { - - @role - - } - - - - - - - - - - @if (_selectedAuthState == "UAuthState") - { - - -
- - - Tenant - - @AuthState?.Identity?.Tenant.Value -
- -
- - -
- - - User Id - - @AuthState?.Identity?.UserKey.Value -
-
- - -
- - - Authenticated - - @(AuthState?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - Session State - - @AuthState?.Identity?.SessionState?.ToDescriptionString() -
-
- - -
- - - Username - - @AuthState?.Identity?.PrimaryUserName -
-
- - -
- - - Display Name - - @AuthState?.Identity?.DisplayName -
-
- - - - - - - Email - - @AuthState?.Identity?.PrimaryEmail - - - - - - Phone - - @AuthState?.Identity?.PrimaryPhone - - - - - - - - Authenticated At - - @* TODO: Add IUAuthDateTimeFormatter *@ - @FormatLocalTime(AuthState?.Identity?.AuthenticatedAt) - - - - - - Last Validated At - - @* TODO: Validation call should update last validated at *@ - @FormatLocalTime(AuthState?.LastValidatedAt) - -
- } - else if (_selectedAuthState == "AspNetCoreState") - { - - -
- - - Authenticated - - @(_aspNetCoreState?.Identity?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - User Id - - @_aspNetCoreState?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value -
-
- - -
- - - Username - - @_aspNetCoreState?.Identity?.Name -
-
- - -
- - - Authentication Type - - @_aspNetCoreState?.Identity?.AuthenticationType -
-
-
- } -
-
-
- - - - - - @GetHealthText() - - - Lifecycle - - - - - - Started - @Diagnostics.StartCount - - @if (Diagnostics.StartedAt is not null) - { - - - - @FormatRelative(Diagnostics.StartedAt) - - - } - - - - - Stopped - @Diagnostics.StopCount - - - - - - Terminated - @Diagnostics.TerminatedCount - - @if (Diagnostics.TerminatedAt is not null) - { - - - - - @FormatRelative(Diagnostics.TerminatedAt) - - - - } - - - - - - Refresh Metrics - - - - - - - Total Attempts - @Diagnostics.RefreshAttemptCount - - - - - - - Success - - @Diagnostics.RefreshSuccessCount - - - - - - Automatic - @Diagnostics.AutomaticRefreshCount - - - - - - Manual - @Diagnostics.ManualRefreshCount - - - - - - Touched/Rotated - @Diagnostics.RefreshTouchedCount / @Diagnostics.RefreshRotatedCount - - - - - - No-Op - @Diagnostics.RefreshNoOpCount - - - - - - Reauth Required - @Diagnostics.RefreshReauthRequiredCount - - - - - - - -
-
-
+ diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs deleted file mode 100644 index 3400db36..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Home.razor.cs +++ /dev/null @@ -1,222 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.Shared.Common; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components.Authorization; -using MudBlazor; -using System.Security.Claims; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; - -public partial class Home : UAuthPageBase -{ - private string _selectedAuthState = "UAuthState"; - private ClaimsPrincipal? _aspNetCoreState; - - private bool _showAdminPreview = false; - - protected override async Task OnInitializedAsync() - { - var initial = await AuthStateProvider.GetAuthenticationStateAsync(); - _aspNetCoreState = initial.User; - AuthStateProvider.AuthenticationStateChanged += OnAuthStateChanged; - Diagnostics.Changed += OnDiagnosticsChanged; - } - - private void OnAuthStateChanged(Task task) - { - _ = HandleAuthStateChangedAsync(task); - } - - private async Task HandleAuthStateChangedAsync(Task task) - { - try - { - var state = await task; - _aspNetCoreState = state.User; - await InvokeAsync(StateHasChanged); - } - catch - { - - } - } - - private void OnDiagnosticsChanged() - { - InvokeAsync(StateHasChanged); - } - - private async Task Logout() => await UAuthClient.Flows.LogoutAsync(); - - private async Task RefreshSession() => await UAuthClient.Flows.RefreshAsync(false); - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private Color GetHealthColor() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return Color.Warning; - - if (Diagnostics.TerminatedCount > 0) - return Color.Error; - - return Color.Success; - } - - private string GetHealthText() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return "Reauthentication Required"; - - if (Diagnostics.TerminatedCount > 0) - return "Session Terminated"; - - return "Healthy"; - } - - private string? FormatRelative(DateTimeOffset? utc) - { - if (utc is null) - return null; - - var diff = DateTimeOffset.UtcNow - utc.Value; - - if (diff.TotalSeconds < 5) - return "just now"; - - if (diff.TotalSeconds < 60) - return $"{(int)diff.Seconds} secs ago"; - - if (diff.TotalMinutes < 60) - return $"{(int)diff.TotalMinutes} min ago"; - - if (diff.TotalHours < 24) - return $"{(int)diff.TotalHours} hrs ago"; - - return utc.Value.ToLocalTime().ToString("dd MMM yyyy"); - } - - private string? FormatLocalTime(DateTimeOffset? utc) - { - return utc?.ToLocalTime().ToString("dd MMM yyyy • HH:mm:ss"); - } - - private async Task OpenProfileDialog() - { - await DialogService.ShowAsync("Manage Profile", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifierDialog() - { - await DialogService.ShowAsync("Manage Identifiers", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenSessionDialog() - { - await DialogService.ShowAsync("Manage Sessions", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentialDialog() - { - await DialogService.ShowAsync("Session Diagnostics", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenAccountStatusDialog() - { - await DialogService.ShowAsync("Manage Account", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.ExtraSmall)); - } - - private async Task OpenUserDialog() - { - await DialogService.ShowAsync("User Management", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.Large)); - } - - private async Task OpenRoleDialog() - { - await DialogService.ShowAsync("Role Management", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private DialogParameters GetDialogParameters() - { - return new DialogParameters - { - ["AuthState"] = AuthState - }; - } - - private async Task SetAccountActiveAsync() - { - ChangeUserStatusSelfRequest request = new() { NewStatus = SelfAssignableUserStatus.Active }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Account activated successfully.", Severity.Success); - } - else - { - Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Activation failed.", Severity.Error); - } - } - - public override void Dispose() - { - base.Dispose(); - AuthStateProvider.AuthenticationStateChanged -= OnAuthStateChanged; - Diagnostics.Changed -= OnDiagnosticsChanged; - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor index 5eec659a..65d20ded 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Login.razor @@ -1,126 +1,4 @@ @page "/login" @attribute [UAuthLoginPage] -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor deleted file mode 100644 index d8eb7138..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor +++ /dev/null @@ -1,27 +0,0 @@ -@inject NavigationManager Nav - - - - - - - Access Denied - - - You don’t have permission to view this page. - If you think this is a mistake, sign in with a different account or request access. - - - - Sign In - Go Back - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor.cs deleted file mode 100644 index 9d05edad..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/NotAuthorized.razor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; - -public partial class NotAuthorized -{ - private string LoginHref - { - get - { - var returnUrl = Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri)); - return $"/login?returnUrl=/{returnUrl}"; - } - } - - private void GoBack() => Nav.NavigateTo("/", replace: false); -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor index 20b38b75..48326f69 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor @@ -1,60 +1,3 @@ @page "/register" -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor.cs deleted file mode 100644 index 6adc7dc6..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/Register.razor.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Users.Contracts; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; - -public partial class Register -{ - private string? _username; - private string? _password; - private string? _passwordCheck; - private string? _email; - private UAuthClientProductInfo? _productInfo; - private MudForm _form = null!; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - private async Task HandleRegisterAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - var request = new CreateUserRequest - { - UserName = _username, - Password = _password, - Email = _email, - }; - - var result = await UAuthClient.Users.CreateAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("User created successfully.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to create user.", Severity.Error); - } - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor index 2623395b..f2c1a536 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/ResetCredential.razor @@ -1,18 +1,3 @@ @page "/reset" -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - - - - - - Change Password - - - - \ No newline at end of file + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor index 2c3cb6dd..6364729c 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor @@ -18,5 +18,7 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents + @using MudBlazor @using MudExtensions diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs index f9a82269..07ae777a 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Program.cs @@ -7,8 +7,11 @@ using CodeBeam.UltimateAuth.Sample.BlazorServer.Infrastructure; using CodeBeam.UltimateAuth.Sample.Seed.Extensions; using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using CodeBeam.UltimateAuth.Server.Extensions; using CodeBeam.UltimateAuth.Users; +using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components.Infrastructure; using Microsoft.AspNetCore.HttpOverrides; using MudBlazor.Services; using MudExtensions.Services; @@ -65,13 +68,18 @@ builder.Services.AddUltimateAuthClientBlazor(o => { - o.AutoRefresh.Interval = TimeSpan.FromSeconds(5); + //o.AutoRefresh.Interval = TimeSpan.FromSeconds(5); o.Reauth.Behavior = ReauthBehavior.RaiseEvent; //o.UAuthStateRefreshMode = UAuthStateRefreshMode.Validate; }); builder.Services.AddUltimateAuthSampleSeed(); +//builder.Services.AddHttpClient(client => +//{ +// client.BaseAddress = new Uri("https://localhost:7213"); +//}); + // Customize UltimateAuth if (builder.Environment.IsDevelopment()) { diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor index 783b707b..2cde04c2 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor @@ -1,5 +1,5 @@ @using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Infrastructure +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure @inject ISnackbar Snackbar @inject DarkModeManager DarkModeManager diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Custom/UAuthPageComponent.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Custom/UAuthPageComponent.razor deleted file mode 100644 index 5af543e4..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Components/Custom/UAuthPageComponent.razor +++ /dev/null @@ -1,10 +0,0 @@ - - - @ChildContent - - - -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Infrastructure/DarkModeManager.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Infrastructure/DarkModeManager.cs deleted file mode 100644 index de933317..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Infrastructure/DarkModeManager.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Contracts; -using CodeBeam.UltimateAuth.Client.Infrastructure; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Infrastructure; - -public sealed class DarkModeManager -{ - private const string StorageKey = "uauth:theme:dark"; - - private readonly IClientStorage _storage; - - public DarkModeManager(IClientStorage storage) - { - _storage = storage; - } - - public async Task InitializeAsync() - { - var value = await _storage.GetAsync(StorageScope.Local, StorageKey); - - if (bool.TryParse(value, out var parsed)) - IsDarkMode = parsed; - } - - public bool IsDarkMode { get; set; } - - public event Action? Changed; - - public async Task ToggleAsync() - { - IsDarkMode = !IsDarkMode; - - await _storage.SetAsync(StorageScope.Local, StorageKey, IsDarkMode.ToString()); - Changed?.Invoke(); - } - - public void Set(bool value) - { - if (IsDarkMode == value) - return; - - IsDarkMode = value; - Changed?.Invoke(); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor index 2788afc2..9bb0843c 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor @@ -1,61 +1,9 @@ -@inherits LayoutComponentBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav +@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents +@inherits LayoutComponentBase - - - - UltimateAuth - - Blazor WASM Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
+ + @Body +
diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor.cs deleted file mode 100644 index 06946b76..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,130 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Infrastructure; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Layout; - -public partial class MainLayout -{ - [CascadingParameter] - public UAuthState UAuth { get; set; } = default!; - - [CascadingParameter] - public DarkModeManager DarkModeManager { get; set; } = default!; - - private async Task Refresh() - { - await UAuthClient.Flows.RefreshAsync(); - } - - private async Task Logout() - { - await UAuthClient.Flows.LogoutAsync(); - } - - private Color GetBadgeColor() - { - if (UAuth is null || !UAuth.IsAuthenticated) - return Color.Error; - - if (UAuth.IsStale) - return Color.Warning; - - var state = UAuth.Identity?.SessionState; - - if (state is null || state == SessionState.Active) - return Color.Success; - - if (state == SessionState.Invalid) - return Color.Error; - - return Color.Warning; - } - - private void HandleSignInClick() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login?uauth_focus=1", replace: true, forceLoad: true); - return; - } - - GoToLoginWithReturn(); - } - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private void GoToLoginWithReturn() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login", replace: true); - return; - } - - var current = Nav.ToBaseRelativePath(uri.ToString()); - if (string.IsNullOrWhiteSpace(current)) - current = "home"; - - var returnUrl = Uri.EscapeDataString("/" + current.TrimStart('/')); - Nav.NavigateTo($"/login?returnUrl={returnUrl}", replace: true); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/AuthorizedTestPage.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/AuthorizedTestPage.razor index cf9519f6..0a953043 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/AuthorizedTestPage.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/AuthorizedTestPage.razor @@ -1,27 +1,4 @@ @page "/authorized-test" @attribute [UAuthAuthorize] -@inherits UAuthPageBase - - - - - - Everything is Ok - - - If you see this section, it means you succesfully logged in. - - - - Go Profile - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - \ No newline at end of file + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor index 8b20171f..945a4332 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Home.razor @@ -1,453 +1,4 @@ @page "/home" @attribute [UAuthAuthorize] -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject UAuthClientDiagnostics Diagnostics -@inject AuthenticationStateProvider AuthStateProvider -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@using System.Security.Claims -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Components.Custom -@using Microsoft.AspNetCore.Authorization - -@if (AuthState?.Identity?.UserStatus == UserStatus.SelfSuspended) -{ - - - - Your account is suspended. Please active it before continue. - - - - Set Active - Logout - - - - return; -} - -@if (AuthState?.Identity?.UserStatus == UserStatus.Suspended) -{ - - - - Your account is suspended. Please contact with administrator. - - - - Logout - - - - return; -} - - - - - - - - - - - Session - - - - - - - Validate - - - - - - Manual Refresh - - - - - - Logout - - - - - - Account - - - - - Manage Sessions - - - - Manage Profile - - - - Manage Identifiers - - - - Manage Credentials - - - - Suspend | Delete Account - - - - Admin - - - - - - - - - @if (_showAdminPreview) - { - - Admin operations are shown for preview. Sign in as an Admin to execute them. - - } - - @if (AuthState?.IsInRole("Admin") == true || _showAdminPreview) - { - - - - @* *@ - @* *@ - User Management - @* *@ - - - - - - @* *@ - Role Management - @* *@ - - - - } - - - Resource Api - - - - - Manage Resource - - - - - - - - - - - - @((AuthState?.Identity?.DisplayName ?? "?").Substring(0, Math.Min(2, (AuthState?.Identity?.DisplayName ?? "?").Length))) - - - - @AuthState?.Identity?.DisplayName - - @foreach (var role in AuthState?.Claims?.Roles ?? Enumerable.Empty()) - { - - @role - - } - - - - - - - - - - @if (_selectedAuthState == "UAuthState") - { - - -
- - - Tenant - - @AuthState?.Identity?.Tenant.Value -
- -
- - -
- - - User Id - - @AuthState?.Identity?.UserKey.Value -
-
- - -
- - - Authenticated - - @(AuthState?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - Session State - - @AuthState?.Identity?.SessionState?.ToDescriptionString() -
-
- - -
- - - Username - - @AuthState?.Identity?.PrimaryUserName -
-
- - -
- - - Display Name - - @AuthState?.Identity?.DisplayName -
-
- - - - - - - Email - - @AuthState?.Identity?.PrimaryEmail - - - - - - Phone - - @AuthState?.Identity?.PrimaryPhone - - - - - - - - Authenticated At - - @* TODO: Add IUAuthDateTimeFormatter *@ - @FormatLocalTime(AuthState?.Identity?.AuthenticatedAt) - - - - - - Last Validated At - - @* TODO: Validation call should update last validated at *@ - @FormatLocalTime(AuthState?.LastValidatedAt) - -
- } - else if (_selectedAuthState == "AspNetCoreState") - { - - -
- - - Authenticated - - @(_aspNetCoreState?.Identity?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - User Id - - @_aspNetCoreState?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value -
-
- - -
- - - Username - - @_aspNetCoreState?.Identity?.Name -
-
- - -
- - - Authentication Type - - @_aspNetCoreState?.Identity?.AuthenticationType -
-
-
- } -
-
-
- - - - - - @GetHealthText() - - - Lifecycle - - - - - - Started - @Diagnostics.StartCount - - @if (Diagnostics.StartedAt is not null) - { - - - - @FormatRelative(Diagnostics.StartedAt) - - - } - - - - - Stopped - @Diagnostics.StopCount - - - - - - Terminated - @Diagnostics.TerminatedCount - - @if (Diagnostics.TerminatedAt is not null) - { - - - - - @FormatRelative(Diagnostics.TerminatedAt) - - - - } - - - - - - Refresh Metrics - - - - - - - Total Attempts - @Diagnostics.RefreshAttemptCount - - - - - - - Success - - @Diagnostics.RefreshSuccessCount - - - - - - Automatic - @Diagnostics.AutomaticRefreshCount - - - - - - Manual - @Diagnostics.ManualRefreshCount - - - - - - Touched/Rotated - @Diagnostics.RefreshTouchedCount / @Diagnostics.RefreshRotatedCount - - - - - - No-Op - @Diagnostics.RefreshNoOpCount - - - - - - Reauth Required - @Diagnostics.RefreshReauthRequiredCount - - - - - - - -
-
-
+ \ No newline at end of file diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor index 595addf8..12aa98c8 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor @@ -1,134 +1,4 @@ @page "/login" @attribute [UAuthLoginPage] -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs deleted file mode 100644 index a45edb56..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Login.razor.cs +++ /dev/null @@ -1,215 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; - -public partial class Login : UAuthPageBase -{ - private string? _username; - private string? _password; - private UAuthClientProductInfo? _productInfo; - private MudTextField _usernameField = default!; - - private CancellationTokenSource? _lockoutCts; - private PeriodicTimer? _lockoutTimer; - private DateTimeOffset? _lockoutUntil; - private TimeSpan _remaining; - private bool _isLocked; - private DateTimeOffset? _lockoutStartedAt; - private TimeSpan _lockoutDuration; - private double _progressPercent; - private int? _remainingAttempts = null; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - protected override Task OnUAuthPayloadAsync(AuthFlowPayload payload) - { - HandleLoginPayload(payload); - return Task.CompletedTask; - } - - protected override async Task OnFocusRequestedAsync() - { - await _usernameField.FocusAsync(); - } - - private void HandleLoginPayload(AuthFlowPayload payload) - { - if (payload.Flow != AuthFlowType.Login) - return; - - if (payload.Reason == AuthFailureReason.LockedOut && payload.LockoutUntilUtc is { } until) - { - _lockoutUntil = until; - StartCountdown(); - } - - _remainingAttempts = payload.RemainingAttempts; - - ShowLoginError(payload.Reason, payload.RemainingAttempts); - } - - private void ShowLoginError(AuthFailureReason? reason, int? remainingAttempts) - { - string message = reason switch - { - AuthFailureReason.InvalidCredentials when remainingAttempts is > 0 - => $"Invalid username or password. {remainingAttempts} attempt(s) remaining.", - - AuthFailureReason.InvalidCredentials - => "Invalid username or password.", - - AuthFailureReason.RequiresMfa - => "Multi-factor authentication required.", - - AuthFailureReason.LockedOut - => "Your account is locked.", - - _ => "Login failed." - }; - - Snackbar.Add(message, Severity.Error); - } - - private async Task StartPkceLogin() - { - string? returnUrl = null; - if (!string.IsNullOrEmpty(ReturnUrl)) - returnUrl = Navigation.BaseUri + ReturnUrl.TrimStart('/'); - - await UAuthClient.Flows.BeginPkceAsync(returnUrl); - } - - private async Task ProgrammaticLogin() - { - var deviceId = await DeviceIdProvider.GetOrCreateAsync(); - var request = new LoginRequest - { - Identifier = "admin", - Secret = "admin", - }; - await UAuthClient.Flows.LoginAsync(request, ReturnUrl ?? "/home"); - } - - private async Task HandleLoginResult(IUAuthTryResult result) - { - if (!result.IsSuccess) - { - if (result.Reason == AuthFailureReason.LockedOut && result.LockoutUntilUtc is { } until) - { - _lockoutUntil = until; - StartCountdown(); - } - - _remainingAttempts = result.RemainingAttempts; - ShowLoginError(result.Reason, result.RemainingAttempts); - } - } - - private async void StartCountdown() - { - if (_lockoutUntil is null) - return; - - _isLocked = true; - _lockoutStartedAt = DateTimeOffset.UtcNow; - _lockoutDuration = _lockoutUntil.Value - DateTimeOffset.UtcNow; - UpdateRemaining(); - - _lockoutCts?.Cancel(); - _lockoutCts = new CancellationTokenSource(); - - _lockoutTimer?.Dispose(); - _lockoutTimer = new PeriodicTimer(TimeSpan.FromSeconds(1)); - - try - { - while (await _lockoutTimer.WaitForNextTickAsync(_lockoutCts.Token)) - { - UpdateRemaining(); - - if (_remaining <= TimeSpan.Zero) - { - ResetLockoutState(); - await InvokeAsync(StateHasChanged); - break; - } - - await InvokeAsync(StateHasChanged); - } - } - catch (OperationCanceledException) - { - - } - } - - private void ResetLockoutState() - { - _isLocked = false; - _lockoutUntil = null; - _progressPercent = 0; - _remainingAttempts = null; - } - - private void UpdateRemaining() - { - if (_lockoutUntil is null || _lockoutStartedAt is null) - return; - - var now = DateTimeOffset.UtcNow; - - _remaining = _lockoutUntil.Value - now; - - if (_remaining <= TimeSpan.Zero) - { - _remaining = TimeSpan.Zero; - return; - } - - var elapsed = now - _lockoutStartedAt.Value; - - if (_lockoutDuration.TotalSeconds > 0) - { - var percent = 100 - (elapsed.TotalSeconds / _lockoutDuration.TotalSeconds * 100); - _progressPercent = Math.Max(0, percent); - } - } - - private async Task OpenResetDialog() - { - await DialogService.ShowAsync("Reset Credentials", GetDialogParameters(), GetDialogOptions()); - } - - private DialogOptions GetDialogOptions() - { - return new DialogOptions - { - MaxWidth = MaxWidth.Medium, - FullWidth = true, - CloseButton = true - }; - } - - private DialogParameters GetDialogParameters() - { - return new DialogParameters - { - ["AuthState"] = AuthState - }; - } - - public override void Dispose() - { - base.Dispose(); - _lockoutCts?.Cancel(); - _lockoutTimer?.Dispose(); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor deleted file mode 100644 index d8eb7138..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/NotAuthorized.razor +++ /dev/null @@ -1,27 +0,0 @@ -@inject NavigationManager Nav - - - - - - - Access Denied - - - You don’t have permission to view this page. - If you think this is a mistake, sign in with a different account or request access. - - - - Sign In - Go Back - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor index 20b38b75..745143b0 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor @@ -1,60 +1,3 @@ @page "/register" -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor.cs deleted file mode 100644 index 8219cee3..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/Register.razor.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Users.Contracts; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; - -public partial class Register -{ - private string? _username; - private string? _password; - private string? _passwordCheck; - private string? _email; - private UAuthClientProductInfo? _productInfo; - private MudForm _form = null!; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - private async Task HandleRegisterAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - var request = new CreateUserRequest - { - UserName = _username, - Password = _password, - Email = _email, - }; - - var result = await UAuthClient.Users.CreateAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("User created successfully.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to create user.", Severity.Error); - } - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor index 2623395b..f2c1a536 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor @@ -1,18 +1,3 @@ @page "/reset" -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - - - - - - Change Password - - - - \ No newline at end of file + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor.cs deleted file mode 100644 index 8a02dcf0..00000000 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/ResetCredential.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Credentials.Contracts; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; - -public partial class ResetCredential -{ - private MudForm _form = null!; - private string? _code; - private string? _newPassword; - private string? _newPasswordCheck; - - private async Task ResetPasswordAsync() - { - await _form.ValidateAsync(); - if (!_form.IsValid) - { - Snackbar.Add("Please fix the validation errors.", Severity.Error); - return; - } - - if (_newPassword != _newPasswordCheck) - { - Snackbar.Add("Passwords do not match.", Severity.Error); - return; - } - - if (string.IsNullOrEmpty(_code) || string.IsNullOrEmpty(_newPassword) || string.IsNullOrEmpty(Identifier)) - { - Snackbar.Add("Missing required information. Please ensure you have a valid reset code and new password.", Severity.Error); - return; - } - - var request = new CompleteResetCredentialRequest - { - ResetToken = _code, - NewSecret = _newPassword, - Identifier = Identifier // Coming from UAuthFlowPageBase automatically if begin reset is successful - }; - - var result = await UAuthClient.Credentials.CompleteResetAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Credential reset successfully. Please log in with your new password.", Severity.Success); - Navigation.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.Problem?.Detail ?? result.Problem?.Title ?? "Failed to reset credential. Please try again.", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs index 6ebe7002..6ae1f810 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs @@ -1,7 +1,7 @@ using CodeBeam.UltimateAuth.Client.Blazor.Extensions; using CodeBeam.UltimateAuth.Core.Domain; using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm; -using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Infrastructure; +using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; using CodeBeam.UltimateAuth.Sample.Shared.ResourceApi; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; @@ -31,7 +31,7 @@ o.AutoRefresh.Interval = TimeSpan.FromSeconds(5); }); -builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(sp => { diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor index 9eaccb01..3d7c59ed 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor @@ -18,5 +18,7 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents + @using MudBlazor @using MudExtensions diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Custom/UAuthPageComponent.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Custom/UAuthPageComponent.razor deleted file mode 100644 index 5af543e4..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Components/Custom/UAuthPageComponent.razor +++ /dev/null @@ -1,10 +0,0 @@ - - - @ChildContent - - - -@code { - [Parameter] - public RenderFragment? ChildContent { get; set; } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor index 91fce1e2..7100ee94 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor @@ -1,69 +1,9 @@ -@using CodeBeam.UltimateAuth.Sample.Shared +@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents @inherits LayoutComponentBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav -@if (!RendererInfo.IsInteractive) -{ - - - -} - - - - - UltimateAuth - - Blazor WASM Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
+ + @Body +
diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs deleted file mode 100644 index c8a68d95..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,130 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using Microsoft.AspNetCore.Components; -using MudBlazor; -using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Layout; - -public partial class MainLayout -{ - [CascadingParameter] - public UAuthState UAuth { get; set; } = default!; - - [CascadingParameter] - public DarkModeManager DarkModeManager { get; set; } = default!; - - private async Task Refresh() - { - await UAuthClient.Flows.RefreshAsync(); - } - - private async Task Logout() - { - await UAuthClient.Flows.LogoutAsync(); - } - - private Color GetBadgeColor() - { - if (UAuth is null || !UAuth.IsAuthenticated) - return Color.Error; - - if (UAuth.IsStale) - return Color.Warning; - - var state = UAuth.Identity?.SessionState; - - if (state is null || state == SessionState.Active) - return Color.Success; - - if (state == SessionState.Invalid) - return Color.Error; - - return Color.Warning; - } - - private void HandleSignInClick() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login?uauth_focus=1", replace: true, forceLoad: true); - return; - } - - GoToLoginWithReturn(); - } - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private void GoToLoginWithReturn() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login", replace: true); - return; - } - - var current = Nav.ToBaseRelativePath(uri.ToString()); - if (string.IsNullOrWhiteSpace(current)) - current = "home"; - - var returnUrl = Uri.EscapeDataString("/" + current.TrimStart('/')); - Nav.NavigateTo($"/login?returnUrl={returnUrl}", replace: true); - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/AuthorizedTestPage.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/AuthorizedTestPage.razor index 962555ed..0a953043 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/AuthorizedTestPage.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/AuthorizedTestPage.razor @@ -1,27 +1,4 @@ @page "/authorized-test" @attribute [UAuthAuthorize] -@inherits UAuthPageBase - - - - - - Everything is Ok - - - If you see this section, it means you succesfully logged in. - - - - Go Home Page - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - \ No newline at end of file + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor index 2503b3af..945a4332 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor @@ -1,454 +1,4 @@ @page "/home" @attribute [UAuthAuthorize] -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject UAuthClientDiagnostics Diagnostics -@inject AuthenticationStateProvider AuthStateProvider -@inject ISnackbar Snackbar -@inject IDialogService DialogService -@using System.Security.Claims -@using CodeBeam.UltimateAuth.Client.Diagnostics -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Core.Defaults -@using CodeBeam.UAuth.Sample.IntWasm.Client.Components.Custom -@using Microsoft.AspNetCore.Authorization - -@if (AuthState?.Identity?.UserStatus == UserStatus.SelfSuspended) -{ - - - - Your account is suspended. Please active it before continue. - - - - Set Active - Logout - - - - return; -} - -@if (AuthState?.Identity?.UserStatus == UserStatus.Suspended) -{ - - - - Your account is suspended. Please contact with administrator. - - - - Logout - - - - return; -} - - - - - - - - - - - Session - - - - - - - Validate - - - - - - Manual Refresh - - - - - - Logout - - - - - - Account - - - - - Manage Sessions - - - - Manage Profile - - - - Manage Identifiers - - - - Manage Credentials - - - - Suspend | Delete Account - - - - Admin - - - - - - - - - @if (_showAdminPreview) - { - - Admin operations are shown for preview. Sign in as an Admin to execute them. - - } - - @if (AuthState?.IsInRole("Admin") == true || _showAdminPreview) - { - - - - @* *@ - @* *@ - User Management - @* *@ - - - - - - @* *@ - Role Management - @* *@ - - - - } - - - Resource Api - - - - - Manage Resource - - - - - - - - - - - - @((AuthState?.Identity?.DisplayName ?? "?").Substring(0, Math.Min(2, (AuthState?.Identity?.DisplayName ?? "?").Length))) - - - - @AuthState?.Identity?.DisplayName - - @foreach (var role in AuthState?.Claims?.Roles ?? Enumerable.Empty()) - { - - @role - - } - - - - - - - - - - @if (_selectedAuthState == "UAuthState") - { - - -
- - - Tenant - - @AuthState?.Identity?.Tenant.Value -
- -
- - -
- - - User Id - - @AuthState?.Identity?.UserKey.Value -
-
- - -
- - - Authenticated - - @(AuthState?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - Session State - - @AuthState?.Identity?.SessionState?.ToDescriptionString() -
-
- - -
- - - Username - - @AuthState?.Identity?.PrimaryUserName -
-
- - -
- - - Display Name - - @AuthState?.Identity?.DisplayName -
-
- - - - - - - Email - - @AuthState?.Identity?.PrimaryEmail - - - - - - Phone - - @AuthState?.Identity?.PrimaryPhone - - - - - - - - Authenticated At - - @* TODO: Add IUAuthDateTimeFormatter *@ - @FormatLocalTime(AuthState?.Identity?.AuthenticatedAt) - - - - - - Last Validated At - - @* TODO: Validation call should update last validated at *@ - @FormatLocalTime(AuthState?.LastValidatedAt) - -
- } - else if (_selectedAuthState == "AspNetCoreState") - { - - -
- - - Authenticated - - @(_aspNetCoreState?.Identity?.IsAuthenticated == true ? "Yes" : "No") -
-
- - -
- - - User Id - - @_aspNetCoreState?.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value -
-
- - -
- - - Username - - @_aspNetCoreState?.Identity?.Name -
-
- - -
- - - Authentication Type - - @_aspNetCoreState?.Identity?.AuthenticationType -
-
-
- } -
-
-
- - - - - - @GetHealthText() - - - Lifecycle - - - - - - Started - @Diagnostics.StartCount - - @if (Diagnostics.StartedAt is not null) - { - - - - @FormatRelative(Diagnostics.StartedAt) - - - } - - - - - Stopped - @Diagnostics.StopCount - - - - - - Terminated - @Diagnostics.TerminatedCount - - @if (Diagnostics.TerminatedAt is not null) - { - - - - - @FormatRelative(Diagnostics.TerminatedAt) - - - - } - - - - - - Refresh Metrics - - - - - - - Total Attempts - @Diagnostics.RefreshAttemptCount - - - - - - - Success - - @Diagnostics.RefreshSuccessCount - - - - - - Automatic - @Diagnostics.AutomaticRefreshCount - - - - - - Manual - @Diagnostics.ManualRefreshCount - - - - - - Touched/Rotated - @Diagnostics.RefreshTouchedCount / @Diagnostics.RefreshRotatedCount - - - - - - No-Op - @Diagnostics.RefreshNoOpCount - - - - - - Reauth Required - @Diagnostics.RefreshReauthRequiredCount - - - - - - - -
-
-
+ \ No newline at end of file diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs deleted file mode 100644 index c8b0a98f..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Home.razor.cs +++ /dev/null @@ -1,227 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Users.Contracts; -using Microsoft.AspNetCore.Components.Authorization; -using MudBlazor; -using System.Security.Claims; -using CodeBeam.UltimateAuth.Sample.Shared.Dialogs; -using CodeBeam.UltimateAuth.Sample.Shared.Common; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; - -public partial class Home : UAuthPageBase -{ - private string _selectedAuthState = "UAuthState"; - private ClaimsPrincipal? _aspNetCoreState; - - private bool _showAdminPreview = false; - - protected override async Task OnInitializedAsync() - { - var initial = await AuthStateProvider.GetAuthenticationStateAsync(); - _aspNetCoreState = initial.User; - AuthStateProvider.AuthenticationStateChanged += OnAuthStateChanged; - Diagnostics.Changed += OnDiagnosticsChanged; - } - - private void OnAuthStateChanged(Task task) - { - _ = HandleAuthStateChangedAsync(task); - } - - private async Task HandleAuthStateChangedAsync(Task task) - { - try - { - var state = await task; - _aspNetCoreState = state.User; - await InvokeAsync(StateHasChanged); - } - catch - { - - } - } - - private void OnDiagnosticsChanged() - { - InvokeAsync(StateHasChanged); - } - - private async Task Logout() => await UAuthClient.Flows.LogoutAsync(); - - private async Task RefreshSession() => await UAuthClient.Flows.RefreshAsync(false); - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private Color GetHealthColor() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return Color.Warning; - - if (Diagnostics.TerminatedCount > 0) - return Color.Error; - - return Color.Success; - } - - private string GetHealthText() - { - if (Diagnostics.RefreshReauthRequiredCount > 0) - return "Reauthentication Required"; - - if (Diagnostics.TerminatedCount > 0) - return "Session Terminated"; - - return "Healthy"; - } - - private string? FormatRelative(DateTimeOffset? utc) - { - if (utc is null) - return null; - - var diff = DateTimeOffset.UtcNow - utc.Value; - - if (diff.TotalSeconds < 5) - return "just now"; - - if (diff.TotalSeconds < 60) - return $"{(int)diff.Seconds} secs ago"; - - if (diff.TotalMinutes < 60) - return $"{(int)diff.TotalMinutes} min ago"; - - if (diff.TotalHours < 24) - return $"{(int)diff.TotalHours} hrs ago"; - - return utc.Value.ToLocalTime().ToString("dd MMM yyyy"); - } - - private string? FormatLocalTime(DateTimeOffset? utc) - { - return utc?.ToLocalTime().ToString("dd MMM yyyy • HH:mm:ss"); - } - - private async Task OpenProfileDialog() - { - await DialogService.ShowAsync("Manage Profile", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenIdentifierDialog() - { - await DialogService.ShowAsync("Manage Identifiers", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenSessionDialog() - { - await DialogService.ShowAsync("Manage Sessions", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenCredentialDialog() - { - await DialogService.ShowAsync("Session Diagnostics", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenAccountStatusDialog() - { - await DialogService.ShowAsync("Manage Account", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.ExtraSmall)); - } - - private async Task OpenUserDialog() - { - await DialogService.ShowAsync("User Management", GetDialogParameters(), UAuthDialog.GetDialogOptions(MaxWidth.Large)); - } - - private async Task OpenRoleDialog() - { - await DialogService.ShowAsync("Role Management", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private async Task OpenResourceApiDialog() - { - await DialogService.ShowAsync("Resource Api", GetDialogParameters(), UAuthDialog.GetDialogOptions()); - } - - private DialogParameters GetDialogParameters() - { - return new DialogParameters - { - ["AuthState"] = AuthState - }; - } - - private async Task SetAccountActiveAsync() - { - ChangeUserStatusSelfRequest request = new() { NewStatus = SelfAssignableUserStatus.Active }; - var result = await UAuthClient.Users.ChangeMyStatusAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Account activated successfully.", Severity.Success); - } - else - { - Snackbar.Add(result?.Problem?.Detail ?? result?.Problem?.Title ?? "Activation failed.", Severity.Error); - } - } - - public override void Dispose() - { - base.Dispose(); - AuthStateProvider.AuthenticationStateChanged -= OnAuthStateChanged; - Diagnostics.Changed -= OnDiagnosticsChanged; - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor index 67fd59d3..12aa98c8 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Login.razor @@ -1,136 +1,4 @@ @page "/login" -@using CodeBeam.UltimateAuth.Client.Runtime -@using CodeBeam.UltimateAuth.Sample.Shared @attribute [UAuthLoginPage] -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor deleted file mode 100644 index e5dde04e..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor +++ /dev/null @@ -1,28 +0,0 @@ -@using CodeBeam.UltimateAuth.Sample.Shared -@inject NavigationManager Nav - - - - - - - Access Denied - - - You don’t have permission to view this page. - If you think this is a mistake, sign in with a different account or request access. - - - - Sign In - Go Back - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor.cs deleted file mode 100644 index a59522db..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/NotAuthorized.razor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; - -public partial class NotAuthorized -{ - private string LoginHref - { - get - { - var returnUrl = Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri)); - return $"/login?returnUrl=/{returnUrl}"; - } - } - - private void GoBack() => Nav.NavigateTo("/", replace: false); -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor index 17dff016..745143b0 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor @@ -1,62 +1,3 @@ @page "/register" -@using CodeBeam.UltimateAuth.Client.Runtime -@using CodeBeam.UltimateAuth.Sample.Shared -@inherits UAuthPageBase -@implements IDisposable -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService - - - - - - - - - - - - - - + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor.cs deleted file mode 100644 index a1917203..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/Register.razor.cs +++ /dev/null @@ -1,45 +0,0 @@ -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Users.Contracts; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; - -public partial class Register -{ - private string? _username; - private string? _password; - private string? _passwordCheck; - private string? _email; - private UAuthClientProductInfo? _productInfo; - private MudForm _form = null!; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - private async Task HandleRegisterAsync() - { - await _form.ValidateAsync(); - - if (!_form.IsValid) - return; - - var request = new CreateUserRequest - { - UserName = _username, - Password = _password, - Email = _email, - }; - - var result = await UAuthClient.Users.CreateAsync(request); - if (result.IsSuccess) - { - Snackbar.Add("User created successfully.", Severity.Success); - } - else - { - Snackbar.Add(result.ErrorText ?? "Failed to create user.", Severity.Error); - } - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor index 2623395b..f2c1a536 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor @@ -1,18 +1,3 @@ @page "/reset" -@inherits UAuthPageBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar - - - - - - - - - Change Password - - - - \ No newline at end of file + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor.cs deleted file mode 100644 index 4e8847fe..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/ResetCredential.razor.cs +++ /dev/null @@ -1,55 +0,0 @@ -using CodeBeam.UltimateAuth.Credentials.Contracts; -using MudBlazor; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; - -public partial class ResetCredential -{ - private MudForm _form = null!; - private string? _code; - private string? _newPassword; - private string? _newPasswordCheck; - - private async Task ResetPasswordAsync() - { - await _form.ValidateAsync(); - if (!_form.IsValid) - { - Snackbar.Add("Please fix the validation errors.", Severity.Error); - return; - } - - if (_newPassword != _newPasswordCheck) - { - Snackbar.Add("Passwords do not match.", Severity.Error); - return; - } - - if (string.IsNullOrEmpty(_code) || string.IsNullOrEmpty(_newPassword) || string.IsNullOrEmpty(Identifier)) - { - Snackbar.Add("Missing required information. Please ensure you have a valid reset code and new password.", Severity.Error); - return; - } - - var request = new CompleteResetCredentialRequest - { - ResetToken = _code, - NewSecret = _newPassword, - Identifier = Identifier // Coming from UAuthFlowPageBase automatically if begin reset is successful - }; - - var result = await UAuthClient.Credentials.CompleteResetAsync(request); - - if (result.IsSuccess) - { - Snackbar.Add("Credential reset successfully. Please log in with your new password.", Severity.Success); - Navigation.NavigateTo("/login"); - } - else - { - Snackbar.Add(result.Problem?.Detail ?? result.Problem?.Title ?? "Failed to reset credential. Please try again.", Severity.Error); - } - } - - private string PasswordMatch(string arg) => _newPassword != arg ? "Passwords don't match" : string.Empty; -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs index 53e43e82..7bc8faa0 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs @@ -13,7 +13,7 @@ }); builder.Services.AddMudExtensions(); builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor index 6fb3b530..b94c0fa4 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor @@ -15,5 +15,7 @@ @using CodeBeam.UltimateAuth.Client @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents + @using MudBlazor @using MudExtensions diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs index 5b91c365..00518b57 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs @@ -33,7 +33,7 @@ // It gives full AspNetCore compatibility but affects performance significantly. //builder.Services.AddUltimateAuthResourceApi(o => o.UAuthHubBaseUrl = "https://localhost:6112/auth"); -builder.Services.AddScoped(); +builder.Services.AddScoped(); builder.Services.AddHttpClient("resourceApi", client => { From 0fe205c2ef4c570307ae6b397f33342deb828039 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Thu, 15 Oct 2026 00:19:10 +0300 Subject: [PATCH 5/8] Interactive Wasm Setup Fix & Docs Sample Page Description --- .../Pages/Samples.razor | 131 +++++++++++++++--- .../wwwroot/exampleJsInterop.js | 6 - .../uauthhub.db-shm | Bin 32768 -> 32768 bytes .../uauthhub.db-wal | Bin 745752 -> 927032 bytes .../Program.cs | 2 +- .../Program.cs | 4 +- .../CodeBeam.UAuth.Sample.IntWasm/Program.cs | 7 +- 7 files changed, 119 insertions(+), 31 deletions(-) delete mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/Pages/Samples.razor b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/Pages/Samples.razor index a1974cbd..dee6fad4 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/Pages/Samples.razor +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/Pages/Samples.razor @@ -5,7 +5,7 @@ Samples Explore working examples and see UltimateAuth in action. - Interactive online samples are coming soon. + Identity Lab (hosted live demo) is coming soon. @@ -15,6 +15,14 @@ + + + Sample.Shared + Shared component designs across all modern .NET platforms. + View Source Code on GitHub + + + Blazor Server (EF Core) @@ -31,9 +39,9 @@ - + - Blazor WASM (Standalone) + Blazor Standalone WASM Client-side sample using Hybrid authentication model. View Source Code on GitHub @@ -41,7 +49,23 @@ - UAuthHub + Blazor Interactive WASM + Client-side interactive render mode sample using Hybrid authentication model. + View Source Code on GitHub + + + + + + UAuthHub (EF Core) + Complete Auth server with UI, working together with WASM client and EF Core. + View Source Code on GitHub + + + + + + UAuthHub (InMemory) Complete Auth server with UI, working together with WASM client. View Source Code on GitHub @@ -54,20 +78,91 @@ View Source Code on GitHub - - - - WASM Sample Setup:
- Start the following projects together:
- (1) UAuthHub
- (2) ResourceApi
- (3) BlazorStandaloneWasm
- After opening the solution, configure multiple startup projects in Visual Studio. -
- - - Each sample refreshes (clear + seed) it's data on each restart. When you close application it will be reset. - + + + + + + + + + Running the Samples + + + + The samples are preconfigured with different hosting and storage setups. + Follow the project combinations below to run them locally. + + + + + + Blazor Server + Standalone + + + + Run either Blazor Server (InMemory) or Blazor Server (EF Core) independently. + No additional projects are required. + + + + + + + + Blazor Standalone WASM + 3 Projects + + + Start these projects together: + + + 1. UAuthHub + 2. ResourceApi + 3. BlazorStandaloneWasm + + + Preconfigured with InMemory storage. + + + + + + + Blazor Interactive WASM + 3 Projects + + + Start these projects together: + + + 1. UAuthHub EF Core + 2. Resource API EF Core + 3. Blazor Interactive WASM + + + Preconfigured with EF Core storage. + + + + + Storage flexibility: + These are sample configurations, not framework limitations. + Both WASM hosting models can use InMemory or EF Core backends. + The combinations above are simply the preconfigured examples provided in this repository. + + + + In Visual Studio, open Configure Startup Projects, select Multiple startup projects, and set the required projects to Start. + + + + Sample Data: + Sample data is reset and seeded again on each restart in the provided demo configurations. + + +
diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js deleted file mode 100644 index ea8d76ad..00000000 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/exampleJsInterop.js +++ /dev/null @@ -1,6 +0,0 @@ -// This is a JavaScript module that is loaded on demand. It can export any number of -// functions, and may import other JavaScript modules if required. - -export function showPrompt(message) { - return prompt(message, 'Type anything here'); -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm index 0bc9e6b36de9e93a70a20c72a803df438bb2b69a..7173a4ebea7d24d5082a8c956a40ae9380bf409f 100644 GIT binary patch delta 599 zcmb7=%PWLY7>D2YJ4Ts}S<3yg7|LyflyZqkA(uu?DMB#|A*B?i$`Jbb@`!oOBr>o>K?*008e)M?ntyW^9A&`h9qKOzHmWU(%+L>t| zOjw98BAkfeZJ1#SqGaZoXcY}?D2t`SwWwoO6vGt> zh&#qgv{%_Q+?BDl+NQA?ST<_B#qPoj@nZkb*alpRml_YUSy(Z4!cj}bIarlLQ+*=h zo-iI{vcf#9iPc6A;=VHRumJ0_*U(J812N#J)Nqr`D9eUJSrXGNwAzv`2ac4RY@^2= mt31&``9$ThPRbscSu*&=c$XLPRLv=HB?I^M=;-D2W4{5E)xIqN delta 446 zcmZo@U}|V!s+V}A%K!pmK+MR%Ag~ok`vY-plmFbiF?s(ver?*h{JF&5)fqP`#r7Ae zld2wQ6c}s-lK+taOt}6o(`FHtX*QD;SavWPY!+nEWSo4(am{2Qmb%IRoYrg>V$oon ze8~kO@W&M@aKRlS@XG@tu=$+VHAb-7&1Zad7=gN1Fq(o5V^o+d$g*;BNnjIL&O=U~>cBn+0H*1a A$p8QV diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal index 0abf9f51c191b90158532a35241e5e3337b7ffe9..48e3f293ac3afe18e71215e318c9ed67218074c6 100644 GIT binary patch delta 15227 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 P>1vbU<6>pJb^Lz=i&8#Z diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs index 6ae1f810..4fb69e88 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Program.cs @@ -28,7 +28,7 @@ o.Login.AllowCredentialPost = true; o.Pkce.ReturnUrl = "https://localhost:6130/home"; // This application domain + path - o.AutoRefresh.Interval = TimeSpan.FromSeconds(5); + //o.AutoRefresh.Interval = TimeSpan.FromSeconds(5); }); builder.Services.AddScoped(); diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs index 7bc8faa0..415c3f67 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs @@ -17,9 +17,9 @@ builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); -builder.Services.AddHttpClient("resourceApi", client => +builder.Services.AddHttpClient(client => { - client.BaseAddress = new Uri("https://localhost:6122"); + client.BaseAddress = new Uri("https://localhost:6122"); // EFCore Resource API URL }); builder.Services.AddUltimateAuthClientBlazor(o => diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs index 00518b57..d921a287 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs @@ -29,15 +29,14 @@ builder.Services.AddScoped(); builder.Services.AddUltimateAuthAspNetCoreCompatibility(); + // If you want to use the UltimateAuthClientBlazor without the AspNetCore compatibility layer, you can register the services like this instead: // It gives full AspNetCore compatibility but affects performance significantly. //builder.Services.AddUltimateAuthResourceApi(o => o.UAuthHubBaseUrl = "https://localhost:6112/auth"); -builder.Services.AddScoped(); - -builder.Services.AddHttpClient("resourceApi", client => +builder.Services.AddHttpClient(client => { - client.BaseAddress = new Uri("https://localhost:6122"); // Resource API URL + client.BaseAddress = new Uri("https://localhost:6122"); // EFCore Resource API URL }); var app = builder.Build(); From b22b6bf8a59cb5ca86cadf87784be07219a9f83a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Thu, 15 Oct 2026 19:05:31 +0300 Subject: [PATCH 6/8] CSS & Layout --- .../Layout/SampleHubMainLayout.razor | 101 ++++++++++++++ .../Layout/SampleHubMainLayout.razor.cs} | 10 +- .../SampleMainLayout.razor | 0 .../SampleMainLayout.razor.cs | 2 +- .../NotAuthorized.razor | 0 .../NotAuthorized.razor.cs | 2 +- .../SampleAuthorizedTestPage.razor | 0 .../{PageComponents => Page}/SampleHome.razor | 0 .../SampleHome.razor.cs | 2 +- .../Components/Page/SampleLandingPage.razor | 4 + .../Page/SampleLandingPage.razor.cs} | 4 +- .../SampleLogin.razor | 0 .../SampleLogin.razor.cs | 2 +- .../SamplePkceLogin.razor | 0 .../SamplePkceLogin.razor.cs | 2 +- .../SampleRegister.razor | 0 .../SampleRegister.razor.cs | 2 +- .../SampleResetCredential.razor | 0 .../SampleResetCredential.razor.cs | 2 +- .../Components/SampleRoutes.razor | 81 +++++++++++ .../wwwroot/sample.css | 91 ++++++++++++ .../Components/App.razor | 1 + .../Components/Layout/MainLayout.razor | 105 +------------- .../Components/Layout/MainLayout.razor.cs | 130 ------------------ .../Components/Pages/NotAuthorized.razor | 28 ---- .../Components/Pages/NotAuthorized.razor.cs | 15 -- .../Components/Routes.razor | 75 +--------- .../Components/_Imports.razor | 3 + .../wwwroot/app.css | 97 ------------- .../Components/App.razor | 2 +- .../Components/Layout/MainLayout.razor | 105 +------------- .../Components/Pages/NotAuthorized.razor | 28 ---- .../Components/Pages/NotAuthorized.razor.cs | 15 -- .../Components/Routes.razor | 75 +--------- .../Components/_Imports.razor | 3 + .../wwwroot/app.css | 97 ------------- .../Components/App.razor | 1 + .../Components/Layout/MainLayout.razor | 3 +- .../Components/Pages/LandingPage.razor | 3 +- .../Components/Pages/LandingPage.razor.cs | 17 --- .../Components/Routes.razor | 75 +--------- .../Components/_Imports.razor | 4 +- .../wwwroot/app.css | 92 ------------- .../Components/App.razor | 2 +- .../Components/Layout/MainLayout.razor | 3 +- .../Components/Pages/LandingPage.razor | 3 +- .../Components/Pages/LandingPage.razor.cs | 17 --- .../Components/Routes.razor | 75 +--------- .../Components/_Imports.razor | 4 +- .../wwwroot/app.css | 91 ------------ .../App.razor | 75 +--------- .../Layout/MainLayout.razor | 3 +- .../Pages/LandingPage.razor | 3 +- .../_Imports.razor | 4 +- .../wwwroot/css/app.css | 92 ------------- .../wwwroot/index.html | 1 + .../Layout/MainLayout.razor | 3 +- .../Pages/LandingPage.razor | 3 +- .../Pages/LandingPage.razor.cs | 17 --- .../Routes.razor | 75 +--------- .../_Imports.razor | 4 +- .../Components/App.razor | 1 + .../CodeBeam.UAuth.Sample.IntWasm/Program.cs | 11 +- .../wwwroot/app.css | 92 ------------- .../ServiceCollectionExtensions.cs | 7 +- 65 files changed, 356 insertions(+), 1509 deletions(-) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor rename samples/{UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor.cs} (93%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{LayoutComponents => Layout}/SampleMainLayout.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{LayoutComponents => Layout}/SampleMainLayout.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/NotAuthorized.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/NotAuthorized.razor.cs (96%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleAuthorizedTestPage.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleHome.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleHome.razor.cs (98%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor rename samples/{blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor.cs => CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor.cs} (80%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleLogin.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleLogin.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SamplePkceLogin.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SamplePkceLogin.razor.cs (98%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleRegister.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleRegister.razor.cs (93%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleResetCredential.razor (100%) rename samples/CodeBeam.UltimateAuth.Sample.Shared/Components/{PageComponents => Page}/SampleResetCredential.razor.cs (96%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/Components/SampleRoutes.razor create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/sample.css delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor.cs delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor.cs delete mode 100644 samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor.cs delete mode 100644 samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor.cs diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor new file mode 100644 index 00000000..fd0bbd96 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor @@ -0,0 +1,101 @@ +@inherits UAuthHubLayoutBase +@inject IUAuthClient UAuthClient +@inject ISnackbar Snackbar +@inject NavigationManager Nav + +@if (!IsHubActive) +{ + + + UltimateAuth + + @Title + + + + + + + + + + + + Access Denied + + + This page cannot be accessed directly. + UAuthHub login flows can only be initiated by an authorized client application. + + + + + + UltimateAuth protects this resource based on your session and permissions. + + + + + return; +} + + + + + UltimateAuth + + UAuthHub Sample + + + + + + + + + +
+ + + @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") + + +
+
+ + + @state.Identity?.DisplayName + @string.Join(", ", state.Claims.Roles) + + + + + + + + @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) + { + + + } + +
+
+ + + + +
+
+ + + @ChildContent + +
+ + +
diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor.cs similarity index 93% rename from samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor.cs index b56ce58f..c59556ab 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleHubMainLayout.razor.cs @@ -7,9 +7,9 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Layout; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Layout; -public partial class MainLayout +public partial class SampleHubMainLayout { [CascadingParameter] public UAuthState UAuth { get; set; } = default!; @@ -17,6 +17,12 @@ public partial class MainLayout [CascadingParameter] public DarkModeManager DarkModeManager { get; set; } = default!; + [Parameter] + public RenderFragment ChildContent { get; set; } = default!; + + [Parameter] + public string? Title { get; set; } = "UAuthHub Sample"; + private async Task Refresh() { await UAuthClient.Flows.RefreshAsync(); diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleMainLayout.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleMainLayout.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleMainLayout.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleMainLayout.razor.cs index 9b2b00a4..b98cb058 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/LayoutComponents/SampleMainLayout.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Layout/SampleMainLayout.razor.cs @@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Components; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Layout; public partial class SampleMainLayout { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/NotAuthorized.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/NotAuthorized.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/NotAuthorized.razor.cs similarity index 96% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/NotAuthorized.razor.cs index f077c666..eb018194 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/NotAuthorized.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/NotAuthorized.razor.cs @@ -1,4 +1,4 @@ -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class NotAuthorized { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleAuthorizedTestPage.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleAuthorizedTestPage.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleAuthorizedTestPage.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleHome.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleHome.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleHome.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleHome.razor.cs index e2aa3f42..f7ab64a6 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleHome.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleHome.razor.cs @@ -10,7 +10,7 @@ using CodeBeam.UltimateAuth.Sample.Shared.Common; using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class SampleHome : UAuthPageBase { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor new file mode 100644 index 00000000..29c446cd --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor @@ -0,0 +1,4 @@ +@using Microsoft.AspNetCore.Components.Authorization + +@inject NavigationManager Nav +@inject AuthenticationStateProvider AuthProvider diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor.cs similarity index 80% rename from samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor.cs index e5844e6d..7c20f85c 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLandingPage.razor.cs @@ -1,8 +1,8 @@ using CodeBeam.UltimateAuth.Core.Defaults; -namespace CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; -public partial class LandingPage +public partial class SampleLandingPage { protected override async Task OnAfterRenderAsync(bool firstRender) { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLogin.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLogin.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLogin.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLogin.razor.cs index 4853e261..334cd26e 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleLogin.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleLogin.razor.cs @@ -5,7 +5,7 @@ using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class SampleLogin : UAuthPageBase { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SamplePkceLogin.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SamplePkceLogin.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SamplePkceLogin.razor.cs similarity index 98% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SamplePkceLogin.razor.cs index 734bf9e0..4e473d18 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SamplePkceLogin.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SamplePkceLogin.razor.cs @@ -5,7 +5,7 @@ using CodeBeam.UltimateAuth.Sample.Shared.Components.Dialogs; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class SamplePkceLogin : UAuthPageBase { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleRegister.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleRegister.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleRegister.razor.cs similarity index 93% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleRegister.razor.cs index e439cf69..bf8814cf 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleRegister.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleRegister.razor.cs @@ -2,7 +2,7 @@ using CodeBeam.UltimateAuth.Users.Contracts; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class SampleRegister { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleResetCredential.razor similarity index 100% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleResetCredential.razor diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleResetCredential.razor.cs similarity index 96% rename from samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleResetCredential.razor.cs index c29f1add..bfca22df 100644 --- a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/PageComponents/SampleResetCredential.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/Page/SampleResetCredential.razor.cs @@ -1,7 +1,7 @@ using CodeBeam.UltimateAuth.Credentials.Contracts; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents; +namespace CodeBeam.UltimateAuth.Sample.Shared.Components.Page; public partial class SampleResetCredential { diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/SampleRoutes.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/SampleRoutes.razor new file mode 100644 index 00000000..278fb57d --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/Components/SampleRoutes.razor @@ -0,0 +1,81 @@ +@using System.Reflection +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Page +@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure +@implements IDisposable + +@inject ISnackbar Snackbar +@inject DarkModeManager DarkModeManager + + + + + + + + + + + + @* Advanced: you can fully control routing by providing your own Router in UAuthApp component. *@ + @* + + + + + + + + + + + + + + + + *@ + + + + + + + + +@code { + [Parameter, EditorRequired] + public Assembly AppAssembly { get; set; } = default!; + + [Parameter, EditorRequired] + public Type DefaultLayout { get; set; } = default!; + + private Task HandleReauth() + { + Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); + return Task.CompletedTask; + } + + protected override void OnInitialized() + { + DarkModeManager.Changed += OnThemeChanged; + } + + private void OnThemeChanged() + { + _ = InvokeAsync(StateHasChanged); + } + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + await DarkModeManager.InitializeAsync(); + StateHasChanged(); + } + } + + public void Dispose() + { + DarkModeManager.Changed -= OnThemeChanged; + } +} diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/sample.css b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/sample.css new file mode 100644 index 00000000..3749f2be --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared/wwwroot/sample.css @@ -0,0 +1,91 @@ +.uauth-stack { + min-height: 60vh; + max-height: calc(100vh - var(--mud-appbar-height)); + width: 30vw; + min-width: 300px; +} + +.uauth-menu-popover { + width: 300px; +} + +.uauth-login-paper { + min-height: 70vh; +} + + .uauth-login-paper.mud-theme-primary { + background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); + color: white; + } + +.uauth-brand-glow { + filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); +} + +.uauth-logo-slide { + animation: uauth-logo-float 30s ease-in-out infinite; +} + +.uauth-text-transform-none .mud-button { + text-transform: none; +} + +.uauth-dialog { + height: 68vh; + max-height: 68vh; + overflow: auto; +} + +.text-secondary { + color: var(--mud-palette-text-secondary); +} + +.uauth-blur { + backdrop-filter: blur(10px); +} + +.uauth-blur-slight { + backdrop-filter: blur(4px); +} + +@keyframes uauth-logo-float { + 0% { + transform: translateY(0) rotateY(0); + } + + 10% { + transform: translateY(0) rotateY(0); + } + + 15% { + transform: translateY(200px) rotateY(360deg); + } + + 35% { + transform: translateY(200px) rotateY(360deg); + } + + 40% { + transform: translateY(200px) rotateY(720deg); + } + + 60% { + transform: translateY(200px) rotateY(720deg); + } + + 65% { + transform: translateY(0) rotateY(360deg); + } + + 85% { + transform: translateY(0) rotateY(360deg); + } + + 90% { + transform: translateY(0) rotateY(0); + } + + 100% { + transform: translateY(0) rotateY(0); + } +} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/App.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/App.razor index 3156b071..39166419 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/App.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/App.razor @@ -9,6 +9,7 @@ + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor index cbe248e0..cb4663ea 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor @@ -1,102 +1,5 @@ -@using CodeBeam.UltimateAuth.Sample.Shared -@inherits UAuthHubLayoutBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav +@inherits UAuthHubLayoutBase -@if (!IsHubActive) -{ - - - UltimateAuth - - UAuthHub Sample - - - - - - - - - - - - Access Denied - - - This page cannot be accessed directly. - UAuthHub login flows can only be initiated by an authorized client application. - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - - return; -} - - - - - UltimateAuth - - UAuthHub Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
- - -
- An unhandled error has occurred. - Reload - 🗙 -
+ + @Body + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs deleted file mode 100644 index 3445de47..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Layout/MainLayout.razor.cs +++ /dev/null @@ -1,130 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Errors; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Core.Errors; -using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure; -using Microsoft.AspNetCore.Components; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Layout; - -public partial class MainLayout -{ - [CascadingParameter] - public UAuthState UAuth { get; set; } = default!; - - [CascadingParameter] - public DarkModeManager DarkModeManager { get; set; } = default!; - - private async Task Refresh() - { - await UAuthClient.Flows.RefreshAsync(); - } - - private async Task Logout() - { - await UAuthClient.Flows.LogoutAsync(); - } - - private Color GetBadgeColor() - { - if (UAuth is null || !UAuth.IsAuthenticated) - return Color.Error; - - if (UAuth.IsStale) - return Color.Warning; - - var state = UAuth.Identity?.SessionState; - - if (state is null || state == SessionState.Active) - return Color.Success; - - if (state == SessionState.Invalid) - return Color.Error; - - return Color.Warning; - } - - private void HandleSignInClick() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login?uauth_focus=1", replace: true, forceLoad: true); - return; - } - - GoToLoginWithReturn(); - } - - private async Task Validate() - { - try - { - var result = await UAuthClient.Flows.ValidateAsync(); - - if (result.IsValid) - { - if (result.Snapshot?.Identity.UserStatus == UserStatus.SelfSuspended) - { - Snackbar.Add("Your account is suspended by you.", Severity.Warning); - return; - } - Snackbar.Add($"Session active • Tenant: {result.Snapshot?.Identity?.Tenant.Value} • User: {result.Snapshot?.Identity?.PrimaryUserName}", Severity.Success); - } - else - { - switch (result.State) - { - case SessionState.Expired: - Snackbar.Add("Session expired. Please sign in again.", Severity.Warning); - break; - - case SessionState.DeviceMismatch: - Snackbar.Add("Session invalid for this device.", Severity.Error); - break; - - default: - Snackbar.Add($"Session state: {result.State}", Severity.Error); - break; - } - } - } - catch (UAuthTransportException) - { - Snackbar.Add("Network error.", Severity.Error); - } - catch (UAuthProtocolException) - { - Snackbar.Add("Invalid response.", Severity.Error); - } - catch (UAuthException ex) - { - Snackbar.Add($"UAuth error: {ex.Message}", Severity.Error); - } - catch (Exception ex) - { - Snackbar.Add($"Unexpected error: {ex.Message}", Severity.Error); - } - } - - private void GoToLoginWithReturn() - { - var uri = Nav.ToAbsoluteUri(Nav.Uri); - - if (uri.AbsolutePath.EndsWith("/login", StringComparison.OrdinalIgnoreCase)) - { - Nav.NavigateTo("/login", replace: true); - return; - } - - var current = Nav.ToBaseRelativePath(uri.ToString()); - if (string.IsNullOrWhiteSpace(current)) - current = "home"; - - var returnUrl = Uri.EscapeDataString("/" + current.TrimStart('/')); - Nav.NavigateTo($"/login?returnUrl={returnUrl}", replace: true); - } -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor deleted file mode 100644 index d6dee0ec..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor +++ /dev/null @@ -1,28 +0,0 @@ -@using CodeBeam.UltimateAuth.Sample.Shared -@inject NavigationManager Nav - - - - - - - Access Denied - - - You don’t have permission to view this page. - If you think this is a mistake, sign in with a different account or request access. - - - - Sign In - Go Back - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor.cs deleted file mode 100644 index 9d96c733..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/NotAuthorized.razor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Pages; - -public partial class NotAuthorized -{ - private string LoginHref - { - get - { - var returnUrl = Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri)); - return $"/login?returnUrl=/{returnUrl}"; - } - } - - private void GoBack() => Nav.NavigateTo("/", replace: false); -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor index a9469874..1b979547 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Routes.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@using CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Pages -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor index 56f13ea9..1629aac3 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor @@ -13,5 +13,8 @@ @using CodeBeam.UltimateAuth.Client @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout + @using MudBlazor @using MudExtensions diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/wwwroot/app.css b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/wwwroot/app.css index 17fcfd6a..5588cc12 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/wwwroot/app.css +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/wwwroot/app.css @@ -49,100 +49,3 @@ h1:focus { .darker-border-checkbox.form-check-input { border-color: #929292; } - -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - - .uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; - } - - .uauth-login-paper.mud-theme-secondary { - background: linear-gradient(145deg, var(--mud-palette-secondary), rgba(0, 0, 0, 0.85) ); - color: white; - } - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/App.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/App.razor index 48e265d0..c5b1817e 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/App.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/App.razor @@ -9,7 +9,7 @@ - + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor index cbe248e0..20691087 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Layout/MainLayout.razor @@ -1,102 +1,5 @@ -@using CodeBeam.UltimateAuth.Sample.Shared -@inherits UAuthHubLayoutBase -@inject IUAuthClient UAuthClient -@inject ISnackbar Snackbar -@inject NavigationManager Nav +@inherits UAuthHubLayoutBase -@if (!IsHubActive) -{ - - - UltimateAuth - - UAuthHub Sample - - - - - - - - - - - - Access Denied - - - This page cannot be accessed directly. - UAuthHub login flows can only be initiated by an authorized client application. - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - - return; -} - - - - - UltimateAuth - - UAuthHub Sample - - - - - - - - - -
- - - @((state.Identity?.DisplayName ?? "?").Trim() is var n ? (n.Length >= 2 ? n[..2] : n[..1]) : "?") - - -
-
- - - @state.Identity?.DisplayName - @string.Join(", ", state.Claims.Roles) - - - - - - - - @if (state.Identity?.SessionState is not null && state.Identity.SessionState != SessionState.Active) - { - - - } - -
-
- - - - -
-
- - - @Body - -
- - -
- An unhandled error has occurred. - Reload - 🗙 -
+ + @Body + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor deleted file mode 100644 index d6dee0ec..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor +++ /dev/null @@ -1,28 +0,0 @@ -@using CodeBeam.UltimateAuth.Sample.Shared -@inject NavigationManager Nav - - - - - - - Access Denied - - - You don’t have permission to view this page. - If you think this is a mistake, sign in with a different account or request access. - - - - Sign In - Go Back - - - - - - UltimateAuth protects this resource based on your session and permissions. - - - - diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor.cs deleted file mode 100644 index 4e750030..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/NotAuthorized.razor.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages; - -public partial class NotAuthorized -{ - private string LoginHref - { - get - { - var returnUrl = Uri.EscapeDataString(Nav.ToBaseRelativePath(Nav.Uri)); - return $"/login?returnUrl=/{returnUrl}"; - } - } - - private void GoBack() => Nav.NavigateTo("/", replace: false); -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor index a62b6ec5..1b979547 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Routes.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@using CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor index f530884f..8b565a7f 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor @@ -14,5 +14,8 @@ @using CodeBeam.UltimateAuth.Client @using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout + @using MudBlazor @using MudExtensions diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/wwwroot/app.css b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/wwwroot/app.css index 17fcfd6a..5588cc12 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/wwwroot/app.css +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/wwwroot/app.css @@ -49,100 +49,3 @@ h1:focus { .darker-border-checkbox.form-check-input { border-color: #929292; } - -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - - .uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; - } - - .uauth-login-paper.mud-theme-secondary { - background: linear-gradient(145deg, var(--mud-palette-secondary), rgba(0, 0, 0, 0.85) ); - color: white; - } - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/App.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/App.razor index 6acc099e..8a0d2a78 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/App.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/App.razor @@ -9,6 +9,7 @@ + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor index ea3fe463..c78d7ae6 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Layout/MainLayout.razor @@ -1,5 +1,4 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents -@inherits LayoutComponentBase +@inherits LayoutComponentBase @Body diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor index 1e4a9016..a02d91bf 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor @@ -1,4 +1,3 @@ @page "/" -@inject NavigationManager Nav -@inject AuthenticationStateProvider AuthProvider + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor.cs deleted file mode 100644 index 5733e2eb..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Pages/LandingPage.razor.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CodeBeam.UltimateAuth.Core.Defaults; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages; - -public partial class LandingPage -{ - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (!firstRender) - return; - - var state = await AuthProvider.GetAuthenticationStateAsync(); - var isAuthenticated = state.User.Identity?.IsAuthenticated == true; - - Nav.NavigateTo(isAuthenticated ? "/home" : $"{UAuthConstants.Routes.LoginRedirect}?fresh=true"); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor index b6eefdfc..1b979547 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/Routes.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore.Components.Pages -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router (in the commented code below) *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor index 33c08f5c..22b7f9e4 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/Components/_Imports.razor @@ -19,7 +19,9 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor -@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Page +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout @using MudBlazor @using MudExtensions diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/wwwroot/app.css b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/wwwroot/app.css index 2b9a4745..2bd9b789 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/wwwroot/app.css +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer.EFCore/wwwroot/app.css @@ -49,95 +49,3 @@ h1:focus { .darker-border-checkbox.form-check-input { border-color: #929292; } - -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - -.uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; -} - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/App.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/App.razor index 087e4279..1dd1096b 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/App.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/App.razor @@ -7,7 +7,7 @@ - + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor index ac8e53e1..1251541a 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Layout/MainLayout.razor @@ -1,5 +1,4 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents -@inherits LayoutComponentBase +@inherits LayoutComponentBase @Body diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor index 1e4a9016..a02d91bf 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor @@ -1,4 +1,3 @@ @page "/" -@inject NavigationManager Nav -@inject AuthenticationStateProvider AuthProvider + diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor.cs b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor.cs deleted file mode 100644 index ab16ba5e..00000000 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Pages/LandingPage.razor.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CodeBeam.UltimateAuth.Core.Defaults; - -namespace CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages; - -public partial class LandingPage -{ - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (!firstRender) - return; - - var state = await AuthProvider.GetAuthenticationStateAsync(); - var isAuthenticated = state.User.Identity?.IsAuthenticated == true; - - Nav.NavigateTo(isAuthenticated ? "/home" : $"{UAuthConstants.Routes.LoginRedirect}?fresh=true"); - } -} diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor index 71cd2ca8..312137a2 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/Routes.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UltimateAuth.Sample.BlazorServer.Components.Pages -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + \ No newline at end of file diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor index 6364729c..8f58fb15 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/Components/_Imports.razor @@ -18,7 +18,9 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor -@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Page +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout @using MudBlazor @using MudExtensions diff --git a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/wwwroot/app.css b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/wwwroot/app.css index 2b9a4745..397f67d8 100644 --- a/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/wwwroot/app.css +++ b/samples/blazor-server/CodeBeam.UltimateAuth.Sample.BlazorServer/wwwroot/app.css @@ -50,94 +50,3 @@ h1:focus { border-color: #929292; } -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - -.uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; -} - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor index 2cde04c2..1b979547 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/App.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm.Pages -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor index 9bb0843c..5bbc27a0 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Layout/MainLayout.razor @@ -1,5 +1,4 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents -@inherits LayoutComponentBase +@inherits LayoutComponentBase @Body diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor index 1e4a9016..a02d91bf 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/Pages/LandingPage.razor @@ -1,4 +1,3 @@ @page "/" -@inject NavigationManager Nav -@inject AuthenticationStateProvider AuthProvider + diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor index 3d7c59ed..3826aa6f 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/_Imports.razor @@ -18,7 +18,9 @@ @using CodeBeam.UltimateAuth.Client.Diagnostics @using CodeBeam.UltimateAuth.Client.Blazor -@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Page +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout @using MudBlazor @using MudExtensions diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/css/app.css b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/css/app.css index 897c71bd..0fb0cf5c 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/css/app.css +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/css/app.css @@ -112,95 +112,3 @@ code { .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { text-align: start; } - -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - - .uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; - } - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/index.html b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/index.html index 26cd7ae0..05649156 100644 --- a/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/index.html +++ b/samples/blazor-standalone-wasm/CodeBeam.UltimateAuth.Sample.BlazorStandaloneWasm/wwwroot/index.html @@ -8,6 +8,7 @@ + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor index 7100ee94..d7761a1b 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Layout/MainLayout.razor @@ -1,5 +1,4 @@ -@using CodeBeam.UltimateAuth.Sample.Shared.Components.LayoutComponents -@inherits LayoutComponentBase +@inherits LayoutComponentBase @Body diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor index 1e4a9016..a02d91bf 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor @@ -1,4 +1,3 @@ @page "/" -@inject NavigationManager Nav -@inject AuthenticationStateProvider AuthProvider + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor.cs deleted file mode 100644 index ac24e527..00000000 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Pages/LandingPage.razor.cs +++ /dev/null @@ -1,17 +0,0 @@ -using CodeBeam.UltimateAuth.Core.Defaults; - -namespace CodeBeam.UAuth.Sample.IntWasm.Client.Pages; - -public partial class LandingPage -{ - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (!firstRender) - return; - - var state = await AuthProvider.GetAuthenticationStateAsync(); - var isAuthenticated = state.User.Identity?.IsAuthenticated == true; - - Nav.NavigateTo(isAuthenticated ? "/home" : $"{UAuthConstants.Routes.LoginRedirect}?fresh=true"); - } -} diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor index 5c7ab182..312137a2 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Routes.razor @@ -1,73 +1,2 @@ -@using CodeBeam.UAuth.Sample.IntWasm.Client.Pages -@using CodeBeam.UltimateAuth.Sample.Shared.Infrastructure -@inject ISnackbar Snackbar -@inject DarkModeManager DarkModeManager - - - - - - - - - - - - - - - - @* Advanced: you can fully control routing by providing your own Router *@ - @* - - - - - - - - - - - - - - - - *@ - - -@code { - private async Task HandleReauth() - { - Snackbar.Add("Reauthentication required. Please log in again.", Severity.Warning); - } - - #region DarkMode - - protected override void OnInitialized() - { - DarkModeManager.Changed += OnThemeChanged; - } - - private void OnThemeChanged() - { - InvokeAsync(StateHasChanged); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) - { - await DarkModeManager.InitializeAsync(); - StateHasChanged(); - } - } - - public void Dispose() - { - DarkModeManager.Changed -= OnThemeChanged; - } - - #endregion -} + + \ No newline at end of file diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor index b94c0fa4..819b9c9e 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/_Imports.razor @@ -15,7 +15,9 @@ @using CodeBeam.UltimateAuth.Client @using CodeBeam.UltimateAuth.Client.Blazor -@using CodeBeam.UltimateAuth.Sample.Shared.Components.PageComponents +@using CodeBeam.UltimateAuth.Sample.Shared.Components +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Page +@using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout @using MudBlazor @using MudExtensions diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Components/App.razor b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Components/App.razor index 6ba144f0..794bd19e 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Components/App.razor +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Components/App.razor @@ -9,6 +9,7 @@ + diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs index d921a287..10c609ad 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/Program.cs @@ -10,14 +10,21 @@ var builder = WebApplication.CreateBuilder(args); +# region Essentials & UI & MudBlazor - Extensions + builder.Services.AddRazorComponents() .AddInteractiveWebAssemblyComponents(); builder.Services.AddMudServices(o => { o.SnackbarConfiguration.PreventDuplicates = false; }); + builder.Services.AddMudExtensions(); +builder.Services.AddScoped(); + +# endregion + builder.Services.AddUltimateAuthClientBlazor(o => { o.Endpoints.BasePath = "https://localhost:6112/auth"; // UAuthHub EFCore URL @@ -26,12 +33,10 @@ o.Pkce.ReturnUrl = "https://localhost:6132/home"; // This application domain + path }); -builder.Services.AddScoped(); - builder.Services.AddUltimateAuthAspNetCoreCompatibility(); // If you want to use the UltimateAuthClientBlazor without the AspNetCore compatibility layer, you can register the services like this instead: -// It gives full AspNetCore compatibility but affects performance significantly. +// It gives full AspNetCore compatibility but decreases performance significantly. //builder.Services.AddUltimateAuthResourceApi(o => o.UAuthHubBaseUrl = "https://localhost:6112/auth"); builder.Services.AddHttpClient(client => diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/wwwroot/app.css b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/wwwroot/app.css index 5b69be65..91f03d8f 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/wwwroot/app.css +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm/wwwroot/app.css @@ -112,95 +112,3 @@ code { .form-floating > .form-control-plaintext:focus::placeholder, .form-floating > .form-control:focus::placeholder { text-align: start; } - -.uauth-stack { - min-height: 60vh; - max-height: calc(100vh - var(--mud-appbar-height)); - width: 30vw; - min-width: 300px; -} - -.uauth-menu-popover { - width: 300px; -} - -.uauth-login-paper { - min-height: 70vh; -} - - .uauth-login-paper.mud-theme-primary { - background: linear-gradient(145deg, var(--mud-palette-primary), rgba(0, 0, 0, 0.85) ); - color: white; - } - -.uauth-brand-glow { - filter: drop-shadow(0 0 25px rgba(255,255,255,0.15)); -} - -.uauth-logo-slide { - animation: uauth-logo-float 30s ease-in-out infinite; -} - -.uauth-text-transform-none .mud-button { - text-transform: none; -} - -.uauth-dialog { - height: 68vh; - max-height: 68vh; - overflow: auto; -} - -.text-secondary { - color: var(--mud-palette-text-secondary); -} - -.uauth-blur { - backdrop-filter: blur(10px); -} - -.uauth-blur-slight { - backdrop-filter: blur(4px); -} - -@keyframes uauth-logo-float { - 0% { - transform: translateY(0) rotateY(0); - } - - 10% { - transform: translateY(0) rotateY(0); - } - - 15% { - transform: translateY(200px) rotateY(360deg); - } - - 35% { - transform: translateY(200px) rotateY(360deg); - } - - 40% { - transform: translateY(200px) rotateY(720deg); - } - - 60% { - transform: translateY(200px) rotateY(720deg); - } - - 65% { - transform: translateY(0) rotateY(360deg); - } - - 85% { - transform: translateY(0) rotateY(360deg); - } - - 90% { - transform: translateY(0) rotateY(0); - } - - 100% { - transform: translateY(0) rotateY(0); - } -} diff --git a/src/client/CodeBeam.UltimateAuth.Client.AspNetCore/ServiceCollectionExtensions.cs b/src/client/CodeBeam.UltimateAuth.Client.AspNetCore/ServiceCollectionExtensions.cs index b546b9d5..88381382 100644 --- a/src/client/CodeBeam.UltimateAuth.Client.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/client/CodeBeam.UltimateAuth.Client.AspNetCore/ServiceCollectionExtensions.cs @@ -5,12 +5,9 @@ namespace CodeBeam.UltimateAuth.Client.AspNetCore; public static class UAuthAspNetCoreExtensions { - public static IServiceCollection AddUltimateAuthAspNetCoreCompatibility( - this IServiceCollection services) + public static IServiceCollection AddUltimateAuthAspNetCoreCompatibility(this IServiceCollection services) { - services.AddAuthentication("UAuth.Noop") - .AddScheme("UAuth.Noop", _ => { }); - + services.AddAuthentication("UAuth.Noop").AddScheme("UAuth.Noop", _ => { }); services.AddAuthorization(); return services; From f90dbc2a4457f3cd3cdc22c168b79e73fbd97d2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Fri, 16 Oct 2026 09:27:12 +0300 Subject: [PATCH 7/8] Shared.Hub Project --- UltimateAuth.slnx | 1 + ...Beam.UltimateAuth.Sample.Shared.Hub.csproj | 23 ++ .../Components/Page/SampleHubHome.razor | 92 ++++++ .../Components/Page/SampleHubHome.razor.cs} | 4 +- .../_Imports.razor | 15 + .../wwwroot/background.png | Bin 0 -> 378 bytes ...UltimateAuth.Sample.UAuthHub.EFCore.csproj | 2 +- .../Components/Pages/Home.razor | 102 +------ .../Components/_Imports.razor | 1 + .../uauthhub.db-shm | Bin 32768 -> 32768 bytes .../uauthhub.db-wal | Bin 927032 -> 927032 bytes ...deBeam.UltimateAuth.Sample.UAuthHub.csproj | 2 +- .../Components/Pages/Home.razor | 101 +------ .../Components/Pages/Home.razor.cs | 262 ------------------ .../Components/_Imports.razor | 1 + 15 files changed, 140 insertions(+), 466 deletions(-) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/CodeBeam.UltimateAuth.Sample.Shared.Hub.csproj create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor rename samples/{UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor.cs => CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor.cs} (98%) create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/_Imports.razor create mode 100644 samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/wwwroot/background.png delete mode 100644 samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor.cs diff --git a/UltimateAuth.slnx b/UltimateAuth.slnx index 751ea927..38a6f7cc 100644 --- a/UltimateAuth.slnx +++ b/UltimateAuth.slnx @@ -13,6 +13,7 @@ + diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/CodeBeam.UltimateAuth.Sample.Shared.Hub.csproj b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/CodeBeam.UltimateAuth.Sample.Shared.Hub.csproj new file mode 100644 index 00000000..5aa2b7e0 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/CodeBeam.UltimateAuth.Sample.Shared.Hub.csproj @@ -0,0 +1,23 @@ + + + + net10.0 + enable + enable + + + + + + + + + + + + + + + + + diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor new file mode 100644 index 00000000..da02651b --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor @@ -0,0 +1,92 @@ +@inherits UAuthHubPageBase +@implements IDisposable + +@inject IUAuthClient UAuthClient +@inject IAuthStore AuthStore +@inject IHubFlowService HubFlowService +@inject IPkceService PkceService +@inject IHubCredentialResolver HubCredentialResolver +@inject IClientStorage BrowserStorage +@inject ISnackbar Snackbar +@inject IUAuthClientProductInfoProvider ClientProductInfoProvider +@inject IDeviceIdProvider DeviceIdProvider +@inject IDialogService DialogService +@inject IOptions Options + + + + + + + + + + + + + + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor.cs b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor.cs similarity index 98% rename from samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor.cs rename to samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor.cs index 11625cbc..75ebd9f5 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor.cs +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/Components/Page/SampleHubHome.razor.cs @@ -7,9 +7,9 @@ using CodeBeam.UltimateAuth.Server.Stores; using MudBlazor; -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.Components.Pages; +namespace CodeBeam.UltimateAuth.Sample.Shared.Hub.Components.Page; -public partial class Home +public partial class SampleHubHome { private string? _username; private string? _password; diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/_Imports.razor b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/_Imports.razor new file mode 100644 index 00000000..6785c741 --- /dev/null +++ b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/_Imports.razor @@ -0,0 +1,15 @@ +@using Microsoft.AspNetCore.Components.Web +@using Microsoft.Extensions.Options + +@using MudBlazor +@using MudExtensions + +@using CodeBeam.UltimateAuth.Core.Abstractions +@using CodeBeam.UltimateAuth.Core.Contracts +@using CodeBeam.UltimateAuth.Client +@using CodeBeam.UltimateAuth.Client.Blazor +@using CodeBeam.UltimateAuth.Client.Infrastructure +@using CodeBeam.UltimateAuth.Client.Runtime +@using CodeBeam.UltimateAuth.Client.Options +@using CodeBeam.UltimateAuth.Server.Services +@using CodeBeam.UltimateAuth.Server.Stores diff --git a/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/wwwroot/background.png b/samples/CodeBeam.UltimateAuth.Sample.Shared.Hub/wwwroot/background.png new file mode 100644 index 0000000000000000000000000000000000000000..e15a3bde6e2bdb380df6a0b46d7ed00bdeb0aaa8 GIT binary patch literal 378 zcmeAS@N?(olHy`uVBq!ia0vp^x**KK1SGdsl%54rjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucLCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33 zJwr2>%=KS^ie7oTIEF;HpS|GCbyPusHSqiXaCu3qf)82(9Gq&mZq2{Kq}M*X&MWtJ zSi1Jo7ZzfImg%g=t(qo=wsSR2lZoP(Rj#3wacN=q0?Br(rXzgZEGK2$ID{|A=5S{xJEuzSH>!M+7wSY6hB<=-E^*n0W7 S8wY^CX7F_Nb6Mw<&;$S{dxtsz literal 0 HcmV?d00001 diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj index a0aba4c9..afc22ae3 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore.csproj @@ -27,7 +27,7 @@ - + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor index dfd4c249..a01be437 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/Pages/Home.razor @@ -1,104 +1,6 @@ @page "/" @page "/login" -@attribute [UAuthLoginPage] -@inherits UAuthHubPageBase - -@implements IDisposable -@using CodeBeam.UltimateAuth.Client.Infrastructure -@using CodeBeam.UltimateAuth.Client.Options -@using CodeBeam.UltimateAuth.Client.Runtime -@using CodeBeam.UltimateAuth.Core.Abstractions -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.Shared -@using CodeBeam.UltimateAuth.Server.Services -@using CodeBeam.UltimateAuth.Server.Stores -@using Microsoft.Extensions.Options -@inject IUAuthClient UAuthClient -@inject IAuthStore AuthStore -@inject IHubFlowService HubFlowService -@inject IPkceService PkceService -@inject IHubCredentialResolver HubCredentialResolver -@inject IClientStorage BrowserStorage -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService -@inject IOptions Options - - - - - - - - - - - - - + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor index 1629aac3..0921e441 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/Components/_Imports.razor @@ -15,6 +15,7 @@ @using CodeBeam.UltimateAuth.Sample.Shared.Components @using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout +@using CodeBeam.UltimateAuth.Sample.Shared.Hub.Components.Page @using MudBlazor @using MudExtensions diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-shm index 7173a4ebea7d24d5082a8c956a40ae9380bf409f..87c20d78256897cc37327ca34eb3a891e3c2def8 100644 GIT binary patch delta 64 wcmZo@U}|V!njj%j`1r(}z&Q@HZ06iql5_7|f;aE+f9=1MUg442n6RK801pi!DF6Tf delta 64 vcmZo@U}|V!njj%@S=Wz6_PAcy>6UL?+ntJLXKlUtUcR=+5|7lzga!2gUAY`% diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.EFCore/uauthhub.db-wal index 48e3f293ac3afe18e71215e318c9ed67218074c6..3a16e535c9a5ba559eb8b76e1327e06a57361818 100644 GIT binary patch delta 13779 zcmeHOd0Z3M+73$~34{R=v>=Ouw+M{PB$LcULC7)@Py|F2tqUjuBAX&AwhCw$+Pc-H z!B$(a?kgJQC>2Ga)}>n9(YkQ+r=mMLWJp6KJ9?y|y_!GSJ{ECc=M-%gFzK&inEj|&7EKvE*yU7p6zL1_> zSV(wn8FCYIYz2I?`|DBZ^+neD7)ODlQEGQIx#sCP{wjT%_YI7YdlT|r68M+tsbENo zp_u@J=tU6!QwhE(Cn>A+39c_Bkg-OVy>riI`nDTTgO#I;H3V6=Dt9DKtv;1xHA7z> zg8)`MI~v&|#qoi`R{ixv#MtY@PM#cYEOyKC$s&P8?^7~um*Efpvv5uCGF1DzT=G$(V{u#Alsy=KBf_U+lsE}!=7J70B zA&Pj~cb|U4rtKT`ImZyqE2mCZ^t}yAS|)6V0!9w_Jjm~Me@tKc08v4b%IN-9mt#2< zViZv-a$()81%aT>$pV2~dYbp0;y^?<4uYYOx4*yiZm4XjvOl+i4bB;oK=Cb-o-&{)`F=s zQL)d}>k_qZL@=1Y097#l*QcJA;hDEM1)Wd@OCROORFpO;LG@M?lE>Nyr|tUdEDrJ( z3i&K_1BFr);&LQhc<{`bVh++3 zg`7S2c*(+3A#*`_9158>=kl}F=P&)hL3~gM6EwL;N+;WHpdlB9cx<}W!*$qa_c=&+ z6jISR!;LmkRTM&vr=`iXm`o93K@#%{P`~*uX8=^$00}* z;eWF1t*rAUn*b4yLOxhLD}UMO{0t5vMIrO5PORO3W1I>k=0S+DQlycURZr^uyMU=5 zpkmdnRTqjX7k2>j7o!T6m4=8jzDO_R6ws)GhY!=DR*mba1=ZV8NN$H+%a-)aY@N6Q zg)BQ%(KObs`#Es`6biB0F3voNC*I(+^hO~Uq8#onS$^jz@cspbq=q_Aj|(ck!$Cq& zh$8k^k42|5x`7y1Ya}A~_U$|JUg^v_4ibt&ZeDSlBkN@d}kSHR<2G}>%jO8HF5E9+GWO_$8jb7VvQQry%B09B77u#Ps7!_|l zzIm~7kWyJ{#8jVDZC2 zaut|g0s~~s8QUKd*VK;cvmLBi!=HuuQVgXa6cPd_C29(XJ)8np$Y~PS5L${PHLQfC zq%A(q-@*52-^Z}qeAQ{b@L3+dev9>T&d27A57CBXG+Mqmxw_<}?6DTqA3!ayN0g!}iORXLB@*E%&b41jPAI>eAYo{}lGyLJQbXXwP5QuVPp;~u9Xy|dk_elX4!&wFB~emJDK3GzgHyCd0qauB;&MVw%VjExRw$c2 zpNO~h?C&^T_qPNa*Z+mEHp(BR$aaAlY_^q=UjL~h~Z%*heb>aw{kanoe%qg3sPWthJJ=t$+h|KCaf z_Bp3A{^HWvDOt-zuqLgr4|!NU_8}-N=1;>4{H)?F%<-p{;Rnre%j@N}VcXZb>RW=o zKe<;9s|7jd&~yxaV85B477zf6Z=vE<`|XH2>-wFb^f@Ztn`2va!V?I<4v{TFg3-@T zjcD*3eihWY*)}?~lhbDTKo_>trcXOyv;5Lr5X0I=)69Y}>2anVJ`7wh`>6~Kk|pNK z!#>4a^-e`1jL5YV#dnPo2w+PpAk`%7Z!}7rmK*9sttN3st5xD8tzjsZ)X3xtMi+ZW z;ICWiCJ?F+(`2xONSe;Icr}~Z0|1jG2gA7pqn`flLl|-uH;M1!ONFgCNYACZN^5xpvPjdv9?_W|5Cek7t?LKv_sxz znr+fTj(5DbIrH9;(S{Ys%F)~89HuGvn$M0dWlNj$*x?)x%XH9B@cz-ESCONoGt6Un zoYH(g07GR+Xr)?0Nokb^XBi6i@-)ffjEZ4!1;N5(rlb<3Oxu#sUw>lj(Z6j%7dcwA zGpsr7VX^p{SOfEg5>rK9)?x!oxVQ+_a62Yo6*K{NNhB^+O4K+- zu@ufQN(HV|DpV4=T&`A0*%rU{-)ZZFE~s2B{7#wZ2!Da=|F0$c9VGF%O=Nox;y$&% zWS7l#S)sFKdKik`8iU0Smu#-!qgqyNbAo35?^)i1&0Mog`c^WkbB{|U9%-QdFuF3k z_&hH;;UDrHxc?I>E_#<727a)h=@x!q2tq?CSq-j$+cKPD zSvjtfl1f}7p%|G$D$}ZDnihUIyF@^xB1Zl(KeVL(pN!Oe2WC8U`W?P_lO65|BqVRj zNE7QX&{k<@HHI4FV^j+xQ5+|AYvCkw5`}NzB(o~+wa9C%SxxwxZo2Oen6c;G+5IG`Mq4@bqKUdRKn4_dYhA1PU0?24 zW%sU6vtz}TM)DF@!fIS2HtfkW1iMp+XC{ zQ*s6;HEOj)D}$$qw65z;+W=kQ5`pI%k>H=S``>kTGpcQ>{tmIX-v~~sWPaM@T{+ai z4mOybfp+a+E7(fBPaJe#Kd|E${BdrQHU>U5iz{BAp$q=tIPTwcd<1>c!lI(1iCLwp z7Zcu+(7h39C0>fbo5EB2%Yo^Rv>lQ5h-Ox#>Y{h=!!$ErwEw6NC(2V!-2PTtPD=P7xBdmZfBj zRK>QJ4h-!<5H!ue{1w1|#v{-(&kydq>>Bz_%jJ-6k%utQcv}DImbGgwHNEpdore%< zK@zXsQ`YS5&<_-biq2!Yj7yKR`fv;TSh44q1#tZHQedJM^k=Kzwy>= z@G|$=^DVG_hFc*-NpfC-Yw|2X9th78e&|pj%j!QQCn8D_8>H-;6CR!%kfIqEGzI#O zo)V`_Pl`<*Et`;<(odZ;fE}O8WDQAH#e_$)bjIY-{fET_3>}m*jExFWs~I&VhsX9T z1@F%&TEgH;sg%Lx8o64gV5D-bM%AA06f(YCMi7i{oxO14|IIL-VA&N8BTx1Qi8D|y zYOQ;Y=@++30lY2kq2o;+%iI=rKWFb96AI>kg+fa14{3B-TD**dm^_xj`v0o1*jw)84j5aT66OxE@40u-O*RU2{`I>vD2ZY+twrmK5qPTsK9@C|_k&Mxwv z70Qe>+=0HpJd~QKhyf5~*wGrHbF+iWZXN2q4wR1)Ex?@GSgxya5cU7#31#H}?MqL0 z&o0fUdAfHCMDa%7*b7ek4}Us;252Zijr(fPr0lxu#mB(Yd8oLkH^tlXUB+$TSStDl zo^(U)fA)UKM;jgt83g>w(P1RnSAs$-CY=Uh)u_17!47OeExnQ}Ym>)oLv`+b&L-O` zK~96Husu(dZ5EAe*ApfN4ZC`E<0s#${6X=3RI~M$8f%Ml*E?=6wL>EGOuIbPVfFQ8 zuWlaWTuh7_XB#`<%FETuL7lgq6V|y+crq>dU8CZa%_pymF*{$kcG;jg2X*Gzf6QqN zQ94(@0Nfx@OQ*Tp)r|Ts*{wo}N}V3<$-Fl=^Ap1bQz53S8xJ>NI}+{EjKTl%vy#Ct z-gdtOh$OqMm@hmcA>q*}JRhM{a0O7y;X@Ot3ce>$%H(oVOGq>tZObV#F#+mnZ7o7R ziZ8dRJ=}|X4`9wHFh@MmJlWhZ?4wi81>qpE2%SKj?eML2mTNvYEEuq=OkM!);eXRb zH}O#>m|uoMvfgX@G zi}|ReGKMBpQk*6jElz0^G_H`UWw?r_6s!W?JZaRry@pNFltw$}H}%=T9?rJeR6u6~ zzrx%0KUS%3K3{(m->#3WUhvi47!^mr-l*R{zLK_g_GVeI;Tw|pXJbdEmHA*7(8TYC z;@pF0eC)N+dK!r7hT>Mv-`I)h?O6-bB&aySHrrV}Xlq|ksDfg**1RG77Vjw}tB)HP z&jOpx!)C)qbS6ejv=H&&*&TevCJ<;S6-BC4hJC6^4%-uW!mm`TSX@G@HE_2oRWmI8 z>dwws|1wEW8eR=bC2;8G7vQZr$NzeAwKFkjWlOK2HD`D@gvp!O?2fr{4Fk^3Xg1rS z3(uhoG`oYt$XQ7i&b)Yo;Y!}vnIlGx5eNi4p5{x%_jGZ~_${|E2%W`sCQM*Hajb+8h>h$=8Y~oWw20CNEcA;)rfRZ2fLfY9&T! zW6?v>&LW}g(d&82;&LJ|W!}x9#{iLxDp>JiY1XE@kvIsSB(}hYNh!I8WE2#xV6^atQ>s+s3_-zV znp7)DxkN%KwbZNGjiyww$&o~=CSRI0O_dN$MoZGur)E&2gYvS~X$&EaON!3v7cp2V zB|>yt>iOOU|KieX%SqCngiJyb3aa(fE6>AEo-N;?Ukq_GR?dmbqV?}==^h3W-$#98 zSI{S{r+&=j*UL12bmW4@O;z7EB*WjiSRwu!=5J&HqnYrBP2SvB3dc{Q>wS4(&9;9C z2t+lw^qQF;qUOs%buDW91s>>pSGYy_Mv2oCRj}y$x``ic=&lF%|0+I-X2n}>{02iAe$~ksvVmT60-}UX5-v98*K1g^%Y?V zAZEzD&|`j1Pgz~{x8o6I*D@0(?uz|cuWv|0zVB?6`8YbdY?}UAJ~Fy_((;d&XOG&Y z7cJ$99NQ$8Ub{W=>^?BYP9H9^5INhTHadSeq(CV?P^Ay7L=cXra**CARRiJm_tI0E;dP>5*o%|1zo=P&0Vt|)}p zw85v(?y}P$teXYmk$WdY>z@g4syRqs6tXJo?U0;vzeR(52@2UhFXfak9sH7mc%YDD z%ll2V7CT-66=P6{aJAiwojs$@a*%!~r2g!Z@)v6k2ZDx76tXwFGNs5>Zo@(ThC=B2 z&jU_nC(Q$*6)42%me5sM*ncet>5oEU6HW*-1`pT?0{5YiOuAmE(5+g+K?b6b`3GuU zWm#cmAniN~@%i*tzlAbuu<7IxVNl52+>M7m zzdYj(Xu5zxnoGY(_qBLuHwPJlLcXtYOV>0-l>zrBDCF*v{)fKy`}r^j2|yw1PWvW& z^x$9^2yPgQ!r*y2s-x%W5*-1r4)M$c=@G1qahFwrwsA3W@J`Vv|o& zVF?iFP{@kZ^^SPG#TT5E;V7i`#N9fdGnQLHAV490AwD<0z31)1L4r`o#v|Pojo$X%*1}gXe-oxxLo^$T2E`q9wo?24qkaV!zeE*3 zKINdxIf2;^py{G@GUlaGDHLK#sliD~qQNPtSb;NAMvbdzN=&FIwOU1LTVtd2j&-+@ z9UUbm#4?;DAih0|<-*30#X6x&D?3njGIZ!NH*RUBC;;K?@(fw{_vgp2x6V?!Cdo4_AA zy7|rpYmm>_bQ+!}YHgGSmhTZfVNUlL2v!H#Y;*7uGh(SsDiz~|SOY^w%}_XWg%(%P z60Mq%Do6#*u$GU1BF~V%34Y;9w2E0@H=r*+v`uT={G5 zo`&SD^MPnB3Tevrf4}iNdJh;-Y7>Rgo!H+5-&yE{K{f%MP@9QMHj15>PZz9kbyItS zz)x+S2)(pQtys&*HMo|6WKNMv5?3loC9V-O8j_ZhatWhq-L;MTZQZ&UKxe*$0c45; z|3lFk(~14NN;&^aK*@7-c*1K#=Y2JQ z`gu@oXN%C_kf1l#_boVD3Tjk5i95n5$Fcu@ zb6HG}4UKGqWP$ZG!xm#bp+5x}kzrvM=@G)?!7P@iVi;0MNZ|2AtHh9Gj4s`UCs7!*VtgbFtip&h&0D8|nJv$hY@~I+nV3O6lLQ1jFYwC)6)`sZ zusjpAYzZn;^nms-O0{y&2U^8i-Pp#4z6BO2n#y@)Z0u81UEwHv4rHC|-i_4rk zo0W}h6Ee##C9a?8z^0>j9&T$(1O8m+mcTYajSdNJOw!M@k3PK6 z8x*gDJm=oVp-Gd1X1+KZ@5$QLN~kr%-f&nc{6VONwv`E~0#_>`%MQ-Yd<9IGc~Xs9 zA!o#LcsC+p{wq_+a7HbW;Dko0prvZ5SRx}^ts1=F*3r9zRsZo8(Gi1qJ^p{4)DsNm zk^69WfR6SteAM~%VEmGjnPs_jA-mD7u!-zOpU9onA+2Y%DK4}6_Z;f}CZ1GA>8j_) z*Jg=w|27I-Jc*viVT!=YZKIZ@gQm;qu*<{14b|OhZv$Qhq1AQPQolt|xK53a8XXxPNEgSGu!13TEyg(ge4rwRhCS$;65 z=~jNARWdcH)hcnCVBjrHNkM*K)LNWSYZ*gF@u`yjx*09v-b!sL@K5gi0#G85IqS4m2aj6(lSbGNgo2E3~9kt(3J=;p=O7Zm&Rve^KxM zouW-#$0+SG^S!2V{)}Gh(3i5TV)8w zq`YS53(~H_VXrot&fRnGW?WkKi54daM<6sU907TP`aMwxb?@lsHnuj&Re$mR?_UA_ z*-Ele7tZz(&x16tr7J+m3*Ng}o-#-}f|->#lb$sxG;CZ{@|36yi8wqUz-P?3@xDs$ z)Zy8bDrXMFlN!rNt6L4EHw={u;`lwX^ z%F2pX`euiQX0x^<-W-!LEjle|IuVtUIcZ#CYSxskP1?!P)Hb9%2!EoN=4GJtOK79wK9zi)+9&;tmb!SJ2`1Bkuh>oS8C7C_@C)U z-CWlTSua!KK>TdfiYo-dFoOQD5V%{|L&F<2%q*!3Iybx^J`)sgKp{2V$S2b9gTHVP zqlTGg)fzulT=&6jjScZt#Eja*;r)h0u}?c&Fx@-X_(_HsS}=#09CpiN0%*DhA%^C) z+2XR_$_gLiZgKkjsE}}XgJ=OmYzMC6o!uj8p9(S zHTr@jZslAIckgT09>YIIT$y_!@jW33>uZOooRIdxnALkcEZG=_hGC~PY>C`PedfBc zz7N^Y5D4G@*x*ek7xCGb&}Ph4p$-WOg(x_V>pz&PGZdFV-BmUwUahsC5@OV!b-}C&j|rBP3GM^1iSV6L`6F zP6sq2lj=;<-)rRutM3yU{M+S%9M}kYNzwu zb=C2LDF){^FRJ&_^{R0PM1o*1=0!3}nTFKBHx>;+;}iqi3gi?m#pSRGLQH5?GFVz| zeJdf-p`5lnV`)k{6Aie-yfVrygt?GNJ@31EZ z+*TeaWRF$$?AY5yT2QW*x+#~IgxVJ*pV|OX%QryGg&((R}!5u zIx0G0dgiF9c&Ktjm?Rr6st^1%96Wh<>decx1)SgvX3BCP+Nc>=(y#l>TXnt>Ed~>= zG!w3b23ssloHxbX(JZmmV7xgK=L!piye?>JiYo2zxqo0bG0Am3wVMruZL+U0H}Kkn zJw5LiIyHH=8o}Qb$j zExy&%zu|YCccyEWGHP$l|3FE_R(`7mwf%&!ZO%kv2cn9KVHlIwn~jIW_fwDL*=k5!$7aG!V6dzcM;o6Yq*QJdio_l>|yg5 z5R*^=*7^B$aq}&ggArLmb8Ng^u8_f-7Hl75XxQkW(5i8zT&c#T1fe9g8WkxMOWPmz zBNZ}wCLKc0N|Ppy(N51)XHKWp!4V^Zr-f!wnW4!^!8wX?u1m|Y#qYDFm-DFqtuhlKY;josBNO|Iz64Vpt7cGku(UM zxyD;YZ_Rih=oki^n()g;9rdNF4`q5Rjb8+I?)zQbv;zjC5?=2Y%m>IQJ|D5|?| z<%)rgfi+gI6gWPpfEmYcESi+Rq82pW5}wD@UGX`b#;B2h@{7WcVkhhm0KCVqFctfc qOa_;23}1Mm??<0*;Cy3B+(I<_PXdM=VHJv>i}E?{x&z+aMgIj#q#9uW diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj index 361680e0..2012f030 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub.csproj @@ -19,7 +19,7 @@ - + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor index dfd4c249..3e521e95 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor @@ -1,104 +1,5 @@ @page "/" @page "/login" @attribute [UAuthLoginPage] -@inherits UAuthHubPageBase -@implements IDisposable -@using CodeBeam.UltimateAuth.Client.Infrastructure -@using CodeBeam.UltimateAuth.Client.Options -@using CodeBeam.UltimateAuth.Client.Runtime -@using CodeBeam.UltimateAuth.Core.Abstractions -@using CodeBeam.UltimateAuth.Core.Contracts -@using CodeBeam.UltimateAuth.Sample.Shared -@using CodeBeam.UltimateAuth.Server.Services -@using CodeBeam.UltimateAuth.Server.Stores -@using Microsoft.Extensions.Options -@inject IUAuthClient UAuthClient -@inject IAuthStore AuthStore -@inject IHubFlowService HubFlowService -@inject IPkceService PkceService -@inject IHubCredentialResolver HubCredentialResolver -@inject IClientStorage BrowserStorage -@inject ISnackbar Snackbar -@inject IUAuthClientProductInfoProvider ClientProductInfoProvider -@inject IDeviceIdProvider DeviceIdProvider -@inject IDialogService DialogService -@inject IOptions Options - - - - - - - - - - - - - - + diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor.cs b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor.cs deleted file mode 100644 index c4b475d3..00000000 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/Pages/Home.razor.cs +++ /dev/null @@ -1,262 +0,0 @@ -using CodeBeam.UltimateAuth.Client; -using CodeBeam.UltimateAuth.Client.Blazor; -using CodeBeam.UltimateAuth.Client.Runtime; -using CodeBeam.UltimateAuth.Core.Contracts; -using CodeBeam.UltimateAuth.Core.Defaults; -using CodeBeam.UltimateAuth.Core.Domain; -using CodeBeam.UltimateAuth.Server.Stores; -using MudBlazor; - -namespace CodeBeam.UltimateAuth.Sample.UAuthHub.Components.Pages; - -public partial class Home -{ - private string? _username; - private string? _password; - - private UAuthClientProductInfo? _productInfo; - private UAuthLoginForm _loginForm = null!; - - private CancellationTokenSource? _lockoutCts; - private PeriodicTimer? _lockoutTimer; - private DateTimeOffset? _lockoutUntil; - private TimeSpan _remaining; - private bool _isLocked; - private DateTimeOffset? _lockoutStartedAt; - private TimeSpan _lockoutDuration; - private double _progressPercent; - private int? _remainingAttempts = null; - private bool _errorHandled; - - protected override async Task OnInitializedAsync() - { - _productInfo = ClientProductInfoProvider.Get(); - } - - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (string.IsNullOrWhiteSpace(HubKey)) - return; - - if (HubState is null || !HubState.Exists) - { - return; - } - - if (HubState.IsExpired) - { - await ContinuePkceAsync(); - return; - } - - if (HubState.Error != null && !_errorHandled) - { - _errorHandled = true; - Snackbar.Add(ResolveErrorMessage(HubState.Error), Severity.Error); - await ContinuePkceAsync(); - - if (HubSessionId.TryParse(HubKey, out var hubSessionId)) - { - await ReloadStateAsync(); - } - - await _loginForm.ReloadAsync(); - - StateHasChanged(); - } - } - - // For testing & debugging - private async Task ProgrammaticPkceLogin() - { - var hub = HubState; - - if (hub is null) - return; - - if (!HubSessionId.TryParse(HubKey, out var hubSessionId)) - return; - - var credentials = await HubCredentialResolver.ResolveAsync(hubSessionId); - - var request = new PkceCompleteRequest - { - Identifier = "admin", - Secret = "admin", - AuthorizationCode = credentials?.AuthorizationCode ?? string.Empty, - CodeVerifier = credentials?.CodeVerifier ?? string.Empty, - ReturnUrl = HubState?.ReturnUrl ?? string.Empty, - HubSessionId = HubState?.HubSessionId.Value ?? hubSessionId.Value, - }; - - await UAuthClient.Flows.TryCompletePkceLoginAsync(request, UAuthSubmitMode.TryAndCommit); - } - - private async Task HandleLoginResult(IUAuthTryResult result) - { - if (result is TryPkceLoginResult pkce) - { - if (!result.IsSuccess) - { - if (result.Reason == AuthFailureReason.LockedOut && result.LockoutUntilUtc is { } until) - { - _lockoutUntil = until; - StartCountdown(); - } - - _remainingAttempts = result.RemainingAttempts; - - ShowLoginError(result.Reason, result.RemainingAttempts); - await ContinuePkceAsync(); - } - } - } - - private HubCredentials? _pkce; - - private async Task ContinuePkceAsync() - { - if (string.IsNullOrWhiteSpace(HubKey)) - return; - - var key = new AuthArtifactKey(HubKey); - var artifact = await AuthStore.GetAsync(key) as HubFlowArtifact; - - if (artifact is null) - return; - - _pkce = await PkceService.RefreshAsync(artifact); - await HubFlowService.ContinuePkceAsync(HubKey, _pkce.AuthorizationCode, _pkce.CodeVerifier); - } - - private async Task StartNewPkceAsync() - { - var returnUrl = await ResolveReturnUrlAsync(); - await UAuthClient.Flows.BeginPkceAsync(returnUrl); - } - - private async Task ResolveReturnUrlAsync() - { - var fromContext = HubState?.ReturnUrl; - if (!string.IsNullOrWhiteSpace(fromContext)) - return fromContext; - - var uri = Navigation.ToAbsoluteUri(Navigation.Uri); - var query = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query); - - if (query.TryGetValue(UAuthConstants.Query.ReturnUrl, out var ru) && !string.IsNullOrWhiteSpace(ru)) - return ru!; - - if (query.TryGetValue(UAuthConstants.Query.Hub, out var hubKey) && !string.IsNullOrWhiteSpace(hubKey)) - { - var artifact = await AuthStore.GetAsync(new AuthArtifactKey(hubKey!)); - if (artifact is HubFlowArtifact flow && !string.IsNullOrWhiteSpace(flow.ReturnUrl)) - return flow.ReturnUrl!; - } - - return Navigation.Uri; - } - - private async void StartCountdown() - { - if (_lockoutUntil is null) - return; - - _isLocked = true; - _lockoutStartedAt = DateTimeOffset.UtcNow; - _lockoutDuration = _lockoutUntil.Value - DateTimeOffset.UtcNow; - UpdateRemaining(); - - _lockoutCts?.Cancel(); - _lockoutCts = new CancellationTokenSource(); - - _lockoutTimer?.Dispose(); - _lockoutTimer = new PeriodicTimer(TimeSpan.FromSeconds(1)); - - try - { - while (await _lockoutTimer.WaitForNextTickAsync(_lockoutCts.Token)) - { - UpdateRemaining(); - - if (_remaining <= TimeSpan.Zero) - { - ResetLockoutState(); - await InvokeAsync(StateHasChanged); - break; - } - - await InvokeAsync(StateHasChanged); - } - } - catch (OperationCanceledException) - { - - } - } - - private void ResetLockoutState() - { - _isLocked = false; - _lockoutUntil = null; - _progressPercent = 0; - _remainingAttempts = null; - } - - private void UpdateRemaining() - { - if (_lockoutUntil is null || _lockoutStartedAt is null) - return; - - var now = DateTimeOffset.UtcNow; - - _remaining = _lockoutUntil.Value - now; - - if (_remaining <= TimeSpan.Zero) - { - _remaining = TimeSpan.Zero; - return; - } - - var elapsed = now - _lockoutStartedAt.Value; - - if (_lockoutDuration.TotalSeconds > 0) - { - var percent = 100 - (elapsed.TotalSeconds / _lockoutDuration.TotalSeconds * 100); - _progressPercent = Math.Max(0, percent); - } - } - - private void ShowLoginError(AuthFailureReason? reason, int? remainingAttempts) - { - string message = reason switch - { - AuthFailureReason.InvalidCredentials when remainingAttempts is > 0 - => $"Invalid username or password. {remainingAttempts} attempt(s) remaining.", - - AuthFailureReason.InvalidCredentials - => "Invalid username or password.", - - AuthFailureReason.RequiresMfa - => "Multi-factor authentication required.", - - AuthFailureReason.LockedOut - => "Your account is locked.", - - _ => "Login failed." - }; - - Snackbar.Add(message, Severity.Error); - } - - private string ResolveErrorMessage(HubErrorCode? errorCode) - { - if (errorCode == HubErrorCode.InvalidCredentials) - { - return "Invalid credentials."; - } - - return "Failed attempt."; - } - -} diff --git a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor index 8b565a7f..b43d5517 100644 --- a/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor +++ b/samples/UAuthHub/CodeBeam.UltimateAuth.Sample.UAuthHub/Components/_Imports.razor @@ -16,6 +16,7 @@ @using CodeBeam.UltimateAuth.Sample.Shared.Components @using CodeBeam.UltimateAuth.Sample.Shared.Components.Layout +@using CodeBeam.UltimateAuth.Sample.Shared.Hub.Components.Page @using MudBlazor @using MudExtensions From 41a052eaa2f811ad13e4a481a5c032a59cc9c611 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Fri, 16 Oct 2026 09:32:40 +0300 Subject: [PATCH 8/8] Cleanup --- .../CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs index 415c3f67..272cafb4 100644 --- a/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs +++ b/samples/int-wasm/CodeBeam.UAuth.Sample.IntWasm/CodeBeam.UAuth.Sample.IntWasm.Client/Program.cs @@ -13,7 +13,6 @@ }); builder.Services.AddMudExtensions(); builder.Services.AddScoped(); -builder.Services.AddScoped(); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });