From a3afa02a2d38308b47a3fbafba55a78b3ddec908 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Sat, 7 Nov 2026 20:31:08 +0300 Subject: [PATCH 1/2] Improve Identity Lab Login UX and Sidebar Footer --- README.md | 3 +- .../Components/Layout/DashboardLayout.razor | 145 +++++++------ .../Layout/DashboardLayout.razor.css | 116 ++++++++++- .../Components/Pages/LoginPage.razor | 22 +- docs/content/migration/index.md | 82 +++++++- docs/content/migration/v0.1.4.md | 194 ++++++++++++++++++ docs/content/migration/v0.2.0.md | 161 +++++++++++++++ .../wwwroot/docs/docs-index.json | 14 ++ .../wwwroot/docs/migration/index.json | 38 +++- .../wwwroot/docs/migration/v0.1.4.json | 54 +++++ .../wwwroot/docs/migration/v0.2.0.json | 39 ++++ .../Components/UAuthLoginForm.razor.cs | 30 ++- 12 files changed, 810 insertions(+), 88 deletions(-) create mode 100644 docs/content/migration/v0.1.4.md create mode 100644 docs/content/migration/v0.2.0.md create mode 100644 docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.1.4.json create mode 100644 docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json diff --git a/README.md b/README.md index a157e2c6..37dd42fc 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ --- -UltimateAuth is an open-source auth framework with platform-level capabilities that unifies secure session, cookie and token based Auth, modern PKCE flows, Blazor/Maui-ready client experiences - eliminating the complexity of traditional Auth systems while providing a clean, lightweight, extensible and developer-first architecture. +UltimateAuth is an open-source auth framework with platform-level capabilities that unifies secure session, cookie and token based Auth, modern PKCE flows, Blazor/MAUI-ready client experiences - eliminating the complexity of traditional Auth systems while providing a clean, lightweight, extensible and developer-first architecture. --- ## Roadmap @@ -70,6 +70,7 @@ UltimateAuth is designed to deliver a simple, consistent developer experience fr --- + ### 💜 Join the UltimateAuth Community UltimateAuth is more than a framework — it's a growing open-source community. diff --git a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor index fbb8cedb..54c68294 100644 --- a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor +++ b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor @@ -118,85 +118,110 @@ - -
WORKSPACE
+
+ +
WORKSPACE
+ + + + Platform Administration + + - - - Platform Administration + + Overview - - - Overview - +
PERSONAL
-
PERSONAL
+ + My Identity + - - My Identity - + + My Sessions + - - My Sessions - + + Session Diagnostics + - - Session Diagnostics - + + My Access + - - My Access - + + Authorization Lab + - - Authorization Lab - + @if (ShowManagement) + { +
SANDBOX MANAGEMENT
- @if (ShowManagement) - { -
SANDBOX MANAGEMENT
+ + Users + - - Users - + + Authorization + - - Authorization - + + Activity + - - Activity - + + Settings + + } - - Settings - - } + + + Sign Out + + - - - Sign Out +
PLAYGROUND
+ + + Demo Store
+
-
PLAYGROUND
- - - Demo Store - -
- - - -
- - Powered by UltimateAuth + - - v @UltimateAuthVersion - .NET @LabVersionInfo.DotNetVersion -
diff --git a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor.css b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor.css index 00097497..efe385e9 100644 --- a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor.css +++ b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Layout/DashboardLayout.razor.css @@ -54,8 +54,9 @@ .lab-sidebar-content { display: flex; flex-direction: column; - min-height: 100%; - padding: 20px 12px; + height: 100%; + min-height: 0; + padding: 20px 12px 12px; } .lab-sidebar-sandbox { @@ -117,15 +118,118 @@ font-weight: 650; } -.lab-sidebar-bottom { + +/* Scrollable navigation */ + +.lab-sidebar-navigation { + flex: 1 1 auto; + min-height: 0; + overflow-y: auto; + overflow-x: hidden; + scrollbar-width: thin; + scrollbar-color: var(--mud-palette-lines-default) transparent; +} + +/* Product footer */ + +.lab-sidebar-footer { + flex-shrink: 0; + padding-top: 12px; + margin-top: 12px; + border-top: 1px solid var(--mud-palette-lines-default); +} + +.lab-sidebar-product { + padding: 12px; + border: 1px solid var(--mud-palette-lines-default); + border-radius: 12px; + background: var(--mud-palette-surface); +} + +.lab-sidebar-product-brand { + display: flex; + align-items: center; + gap: 9px; + color: var(--mud-palette-text-primary); + text-decoration: none; + min-width: 0; +} + +.lab-sidebar-product-icon { + width: 36px; + height: 36px; + flex-shrink: 0; display: flex; align-items: center; - gap: 8px; - padding: 18px 12px 4px; + justify-content: center; + border-radius: 9px; + background: var(--mud-palette-primary-hover); +} + +.lab-sidebar-product-info { + display: flex; + flex: 1; + flex-direction: column; + gap: 3px; + min-width: 0; +} + + .lab-sidebar-product-info strong { + font-size: 0.75rem; + font-weight: 700; + line-height: 1.3; + white-space: nowrap; + } + + .lab-sidebar-product-info small { + font-size: 0.66rem; + color: var(--mud-palette-text-secondary); + } + +.lab-sidebar-product-external { + flex-shrink: 0; color: var(--mud-palette-text-secondary); - font-size: .72rem; + opacity: 0.65; +} + +.lab-sidebar-product-brand:hover .lab-sidebar-product-external { + color: var(--mud-palette-primary); + opacity: 1; } +/* Version information */ + +.lab-sidebar-product-meta { + display: flex; + align-items: center; + justify-content: space-between; + gap: 6px; + margin-top: 12px; + padding-top: 10px; + border-top: 1px solid var(--mud-palette-lines-default); +} + + .lab-sidebar-product-meta a, + .lab-sidebar-product-runtime { + display: inline-flex; + align-items: center; + gap: 4px; + min-width: 0; + color: var(--mud-palette-text-secondary); + font-size: 0.65rem; + white-space: nowrap; + text-decoration: none; + } + + .lab-sidebar-product-meta .mud-icon-root { + font-size: 14px; + } + + .lab-sidebar-product-meta a:hover { + color: var(--mud-palette-primary); + } + + .lab-dashboard-main { min-height: calc(100vh - var(--mud-appbar-height)); } diff --git a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor index fc4a05b5..aeb2ed2e 100644 --- a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor +++ b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor @@ -107,7 +107,7 @@ - + @if (IsLockedOut) { @@ -127,10 +127,7 @@ @LockoutCountdown - + Try again after @@ -187,7 +184,7 @@ MaxLength="256" Required="true" RequiredError="Email or username is required." - Disabled="IsLockedOut" + Disabled="@_loginBusy" Immediate="true" /> - AuthState.Identity?.PrimaryUserName; + private string? CurrentUserName => AuthState.Identity?.PrimaryUserName; + + private bool _loginBusy; + + private async Task HandleSubmittingChanged(bool submitting) + { + _loginBusy = submitting; + await InvokeAsync(StateHasChanged); + } private void ContinueToDashboard() { diff --git a/docs/content/migration/index.md b/docs/content/migration/index.md index 0cd8f9d0..f890b36a 100644 --- a/docs/content/migration/index.md +++ b/docs/content/migration/index.md @@ -6,10 +6,84 @@ group: migration # Migration Guides -Version-specific instructions for upgrading UltimateAuth applications. +Keep your UltimateAuth applications up to date with clear, version-specific upgrade guidance. -Migration guides focus on breaking changes, behavior changes, and required application updates. +This page provides an overview of stable UltimateAuth releases, their migration impact, and any actions required when upgrading. -## Available Guides +**Most updates require little or no application code changes.** When an update requires attention, a dedicated migration guide explains what changed and how to adapt your application. -- [Migrating to v0.1.1](/docs/migration/v0.1.1) — Blazor route authorization and component lifecycle changes. +## Version Migration Overview + +The table below lists stable releases in descending order, with the newest version first. + +Preview and release candidate versions are excluded. + +| Version | Migration Impact | What's Changed | Migration Guide | +|---|---|---|---| +| **v0.2.0 (In Progress)** | **Medium (Provisional)** | Async authorization APIs, authorization checks, and integration changes | [View Guide](/docs/migration/v0.2.0) | +| **v0.1.4** | **Low** | CSRF protection, antiforgery integration, and interface changes | [View Guide](/docs/migration/v0.1.4) | +| **v0.1.3** | **None** | Session deletion, revocation, and refresh consistency fixes | Not required | +| **v0.1.2** | **None** | Password change transaction and session revocation fixes | Not required | +| **v0.1.1** | **Low** | Blazor route authorization and component lifecycle changes | [View Guide](/docs/migration/v0.1.1) | +| **v0.1.0** | **N/A** | Initial stable release | Not applicable | + +**Migration impact describes the expected developer effort and affected integration surface, not the size of the code change or the significance of the release.** A small change to a widely used authentication API may have a higher migration impact than a large internal refactor. + +> Individual preview and release candidate versions are not listed separately. Migration guidance for an in-progress release may change before its stable release. + +Security and reliability fixes may have an impact of **None** while still being strongly recommended. + +## Understanding Migration Impact + +| Impact | Meaning | Expected Action | +|---|---|---| +| **None** | No application code or configuration changes are required for standard integrations. | Update packages and run existing tests. | +| **Low** | Small, localized changes may be required, typically for specific integrations or customizations. | Review the migration guide and update affected code. | +| **Medium** | Changes affect commonly used APIs, core integration points, or multiple application areas. Even a small code change is classified as Medium when developers must update functionality they use directly and extensively. | Review the migration guide, update affected integrations, and perform targeted regression testing. | +| **High** | Significant architectural, API, persistence, or behavioral changes require a planned migration. | Review all migration steps, test thoroughly, and plan deployment carefully. | + +Migration impact is evaluated using both **the effort required and how directly the changes affect application developers**. + +A change does not qualify as Low simply because it requires only a few lines of code. Breaking changes to frequently used authentication, authorization, session management, or client integration APIs may be classified as Medium even when the implementation changes are relatively small. + +Applications using only unaffected functionality may require fewer changes than the stated impact level suggests. + +## How to Upgrade + +1. **Identify your current version.** Check the installed `CodeBeam.UltimateAuth.*` NuGet packages. +2. **Review every version between your current and target versions.** Migration requirements are cumulative when skipping releases. +3. **Follow the linked migration guides.** Apply any required API, configuration, or behavioral changes in version order. +4. **Update your UltimateAuth packages together.** Keep related packages on compatible versions. +5. **Build and test your application.** Verify login, logout, refresh, authorization, and session management flows relevant to your integration. + +For releases marked **None**, no dedicated migration guide is necessary. You should still review the release notes and run your application tests. + +## Available Migration Guides + +### [Migrating to v0.1.4](/docs/migration/v0.1.4) + +**Impact: Low** + +Introduces antiforgery protection for cookie-based authentication flows, updates browser client integration, and changes selected session resolution and browser bridge interfaces. + +Applications using the standard UltimateAuth browser client generally receive antiforgery handling automatically. + +Custom HTTP clients, manually implemented browser bridges, and custom session resolvers should review the guide. + +### [Migrating to v0.1.1](/docs/migration/v0.1.1) + +**Impact: Low** + +Introduces routing-level enforcement for `[UAuthAuthorize]` and updates the `UAuthComponentBase` lifecycle. + +Most applications using the built-in `UAuthApp` router require no changes. Applications with custom routers, component lifecycle overrides, or specialized session requirements should review the guide. + +## Release History + +For complete release notes, bug fixes, and security updates, visit the [UltimateAuth GitHub Releases](https://github.com/CodeBeamOrg/UltimateAuth/releases) page. + +Migration guides focus on changes developers must make to their applications. Release notes provide the complete history of changes in each version. + +--- + +**Upgrading across multiple versions?** Start with the earliest version after your currently installed release and review each migration entry through your target version. \ No newline at end of file diff --git a/docs/content/migration/v0.1.4.md b/docs/content/migration/v0.1.4.md new file mode 100644 index 00000000..c197caea --- /dev/null +++ b/docs/content/migration/v0.1.4.md @@ -0,0 +1,194 @@ +--- +title: Migrating to v0.1.4 +order: 3 +group: migration +--- + +# Migrating to v0.1.4 + +**Migration Impact: Low** + +UltimateAuth v0.1.4 introduces antiforgery protection for cookie-based authentication flows and updates several client and server integration interfaces. + +The release strengthens protection against Cross-Site Request Forgery (CSRF) while preserving the standard UltimateAuth developer experience. + +**Most applications using the built-in UltimateAuth browser client require no application code changes.** Antiforgery token handling is integrated into the client. + +Applications using custom HTTP requests, custom browser bridges, or custom session resolvers should review the changes below. + +## 1. Antiforgery Protection for Cookie-Based Authentication + +UltimateAuth now validates antiforgery tokens for protected operations when cookie-based authentication is applicable. + +This includes relevant authentication operations and authenticated state-changing endpoints. + +Requests that fail antiforgery validation are rejected with HTTP `400 Bad Request` and the following error: + +```json +{ + "error": "invalid_antiforgery_token" +} +``` + +### Using the built-in browser client + +The UltimateAuth browser client now supports retrieving and submitting antiforgery tokens automatically. + +If your application uses the standard UltimateAuth client integration, no additional antiforgery implementation is normally required. + +Make sure the server and client packages are updated together. + +### Using custom HTTP requests + +If your application calls protected UltimateAuth endpoints directly from a browser, you must obtain an antiforgery token and submit it with the request. + +The default token endpoint is: + +```http +GET /auth/antiforgery/token +``` + +The response contains: + +```json +{ + "requestToken": "...", + "headerName": "X-UAuth-CSRF", + "formFieldName": "__RequestVerificationToken" +} +``` + +The endpoint also issues an antiforgery cookie. + +For subsequent protected requests: + +1. Obtain a token from the configured antiforgery endpoint. +2. Preserve the associated antiforgery cookie. +3. Send the request token using the returned `headerName`. +4. Include the appropriate authentication credentials for the request. + +For example: + +```http +POST /auth/logout +X-UAuth-CSRF: +Cookie: +``` + +The request token and antiforgery cookie must belong to the same antiforgery context. + +**Do not hardcode or fabricate antiforgery tokens.** Always obtain them from the server. + +The default endpoint path assumes the standard `/auth` base path. Applications using custom routing or multi-tenancy must use their configured endpoint URL. + +### Custom server-side integrations + +Applications using custom HTTP clients or server-to-server integrations should review whether their requests use cookie-based authentication. + +Antiforgery requirements depend on the authentication transport and operation. They are not automatically equivalent for every bearer-token or header-based request. + +Do not disable antiforgery validation to resolve an integration failure. Update the affected request flow instead. + +## 2. ISessionIdResolver Is Now Asynchronous + +The `ISessionIdResolver` interface has changed to support asynchronous session resolution. + +If you implement this interface yourself, update the implementation. + +**Before (v0.1.3):** + +```csharp +public AuthSessionId? Resolve(HttpContext context) +{ + // Resolve the session identifier. +} +``` + +**After (v0.1.4):** + +```csharp +public ValueTask ResolveAsync(HttpContext context, CancellationToken ct = default) +{ + ct.ThrowIfCancellationRequested(); + + // Resolve the session identifier. + return ValueTask.FromResult(null); +} +``` + +Replace the placeholder return with your existing resolution logic. + +If your resolver performs asynchronous operations, use an `async ValueTask` implementation and await those operations. + +Update any direct calls from `Resolve(...)` to `ResolveAsync(...)` and await the result. + +Applications using the built-in session resolver do not need to make this change. + +## 3. Custom Browser Bridges + +The `IBrowserUAuthBridge` interface now includes: + +```csharp +ValueTask ConfigureAntiforgeryAsync(string tokenUrl, string? trustedOrigin = null); +``` + +This allows the UltimateAuth client bootstrapper to configure antiforgery handling for browser requests. + +If you provide a custom implementation of `IBrowserUAuthBridge`, implement this new method. + +Your implementation must configure the browser-side antiforgery integration using the supplied token endpoint and optional trusted origin. + +The exact implementation depends on your browser integration. + +**Do not add an empty implementation unless antiforgery handling is already provided by your custom bridge.** Doing so may leave protected browser requests without the required token. + +Applications using the built-in UltimateAuth browser bridge do not need to make this change. + +## 4. Antiforgery Endpoint Configuration + +v0.1.4 introduces a server-side antiforgery configuration section: + +```csharp +options.Antiforgery.TokenEndpoint = "/antiforgery/token"; +``` + +The client also exposes the corresponding endpoint setting: + +```csharp +options.Endpoints.AntiforgeryToken = "/antiforgery/token"; +``` + +The default endpoint path is `/antiforgery/token`, resolved under the configured UltimateAuth base path. + +No configuration change is required when using the defaults. + +If you customize the endpoint, ensure the server and client configurations match. + +## 5. Verify Your Application + +After upgrading to v0.1.4, verify the following flows where applicable: + +- Login and logout using the built-in browser client. +- Session refresh and validation. +- Authenticated account and session management operations. +- Custom requests to UltimateAuth endpoints. +- Custom session resolver implementations. +- Custom browser bridge implementations. +- External Hub and multi-tenant configurations. + +For applications using custom browser requests, verify that valid antiforgery tokens allow protected operations and missing or invalid tokens are rejected. + +## Migration Checklist + +- [ ] Update UltimateAuth packages to compatible v0.1.4 versions. +- [ ] Update custom `ISessionIdResolver` implementations, if any. +- [ ] Update custom `IBrowserUAuthBridge` implementations, if any. +- [ ] Add antiforgery token handling to custom browser HTTP requests, if applicable. +- [ ] Verify custom antiforgery endpoint configuration, if applicable. +- [ ] Run authentication, authorization, and session regression tests. + +--- + +**Using the standard UltimateAuth client and built-in session resolution?** No application code changes are normally required. Update your packages and verify your existing authentication flows. + +For the complete list of changes, see [UltimateAuth v0.1.4 Release](https://github.com/CodeBeamOrg/UltimateAuth/releases/tag/v0.1.4). diff --git a/docs/content/migration/v0.2.0.md b/docs/content/migration/v0.2.0.md new file mode 100644 index 00000000..cdc4ab5b --- /dev/null +++ b/docs/content/migration/v0.2.0.md @@ -0,0 +1,161 @@ +--- +title: Migrating to v0.2.0 +order: 4 +group: migration +--- + +# Migrating to v0.2.0 + +**Migration Impact: Medium — In Progress** + +**Latest published prerelease reviewed: v0.2.0-preview.2** + +This guide covers migration requirements for the upcoming UltimateAuth v0.2.0 release. + +The guide is provisional and will be updated as new preview and release candidate versions become available. The final migration requirements may change before the stable v0.2.0 release. + +## 1. Asynchronous Authorization Policies + +**Available since preview.1** + +Custom implementations of `IAccessPolicy`, `IAccessInvariant`, and `IAccessAuthority` should migrate to `DecideAsync`. + +**Before:** + +```csharp +public AccessDecision Decide(AccessContext context) +{ + return AccessDecision.Allow(); +} +``` + +**After:** + +```csharp +public ValueTask DecideAsync(AccessContext context, CancellationToken ct = default) +{ + return ValueTask.FromResult(AccessDecision.Allow()); +} +``` + +For `IAccessAuthority`, preserve the existing `runtimePolicies` parameter and add the cancellation token. + +Synchronous `Decide` methods are obsolete. Existing synchronous implementations retain compatibility through the interface defaults, but new implementations should use `DecideAsync`. + +If your application invokes an authority directly, switch to `DecideAsync` and await the result. + +## 2. Authorization Check Results + +**Available since preview.1** + +`CheckAsync` now returns an explicit authorization decision in the response body. + +If your application previously interpreted HTTP `403` as the result of a successful authorization evaluation that denied access, update that handling. + +```csharp +var result = await UAuthClient.Authorization.CheckAsync(request); + +if (result.IsSuccess && result.Value is { IsAllowed: true }) +{ + // Authorized +} +``` + +An HTTP-successful authorization check does not necessarily mean that access was granted. + +Inspect the returned authorization decision rather than relying solely on the HTTP status. + +## 3. Custom User Lifecycle Integrations + +**Available since preview.2** + +The `IUserLifecycleIntegration.OnUserCreatedAsync` signature now includes `UAuthClientProfile`. + +**Before:** + +```csharp +Task OnUserCreatedAsync( + TenantKey tenant, + UserKey userKey, + object request, + CancellationToken ct = default); +``` + +**After:** + +```csharp +Task OnUserCreatedAsync( + TenantKey tenant, + UserKey userKey, + object request, + UAuthClientProfile clientProfile, + CancellationToken ct = default); +``` + +Update custom implementations to accept the additional client profile parameter. + +Applications using built-in lifecycle integrations do not need to make this change. + +## 4. Identifier and Profile Limits + +**Available since preview.2** + +The reference Users domain now enforces additional identifier and profile safety limits. + +The default maximum is 10 active identifiers per user. Applications requiring a different capacity should configure `Identifiers.Behavior.MaxIdentifiersPerUser`. + +Existing profile creation and update operations must also respect the new field-length and metadata limits. + +If you use EF Core persistence: + +1. Review existing profile data for values exceeding the new limits. +2. Add or apply the appropriate EF Core database migration for your application's DbContext. +3. Verify that applications handling profile validation errors use the returned error codes. + +See [Profile Validation & Limits](/docs/plugin-domains/profile-validation-limits) for the supported limits. + +## 5. Password Policies and History + +**Available since preview.2** + +The reference password credential implementation now applies configurable password policies, with Standard as the default level. + +Review custom registration, password-change, and password-reset flows to ensure that they handle server-side password validation errors. + +Applications using persistent password-history storage must apply the required database migration before enabling password history. + +Password history is disabled by default (`RememberLast = 0`). + +See [Password Policy & History](/docs/security/password-policy) for configuration and persistence requirements. + +## 6. Rate Limiting + +**Available since preview.2** + +Built-in endpoint rate limiting is enabled by default when using: + +```csharp +app.UseUltimateAuthWithAspNetCore(); +``` + +If your application already registers its own rate limiting middleware, avoid installing a duplicate limiter. + +To retain application-owned rate limiting: + +```csharp +app.UseUltimateAuthWithAspNetCore(useRateLimiting: false); +``` + +Then configure your existing `UseRateLimiter()` middleware in the appropriate pipeline position. + +Applications using `UseUltimateAuth()` without the integrated ASP.NET Core helper do not enable UltimateAuth rate limiting by default. + +Review custom HTTP clients and authentication flows for HTTP `429 Too Many Requests` handling. + +See [Rate Limiting](/docs/security/rate-limiting) for middleware integration and defaults. + +--- + +**Before upgrading:** Review the migration steps applicable to your installed prerelease version. Sections marked **Current dev** describe upcoming changes and may be revised before their first published prerelease. + +This page will continue to evolve through the v0.2.0 preview and RC series and will become the stable migration guide when v0.2.0 is released. diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/docs-index.json b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/docs-index.json index 0a8a077b..e1c3c2ec 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/docs-index.json +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/docs-index.json @@ -320,5 +320,19 @@ "Order": 2, "Group": "migration", "GroupOrder": 10 + }, + { + "Title": "Migrating to v0.1.4", + "Slug": "migration/v0.1.4", + "Order": 3, + "Group": "migration", + "GroupOrder": 10 + }, + { + "Title": "Migrating to v0.2.0", + "Slug": "migration/v0.2.0", + "Order": 4, + "Group": "migration", + "GroupOrder": 10 } ] \ No newline at end of file diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/index.json b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/index.json index c595f397..8f6b4d5a 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/index.json +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/index.json @@ -1,14 +1,44 @@ { "Slug": "migration/index", "Title": "Migration Guides", - "Html": "\n\u003Cp\u003EVersion-specific instructions for upgrading UltimateAuth applications.\u003C/p\u003E\n\u003Cp\u003EMigration guides focus on breaking changes, behavior changes, and required application updates.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022available-guides\u0022\u003EAvailable Guides\u003C/h2\u003E\n\u003Cul\u003E\n\u003Cli\u003E\u003Ca href=\u0022/docs/migration/v0.1.1\u0022\u003EMigrating to v0.1.1\u003C/a\u003E \u2014 Blazor route authorization and component lifecycle changes.\u003C/li\u003E\n\u003C/ul\u003E\n", + "Html": "\n\u003Cp\u003EKeep your UltimateAuth applications up to date with clear, version-specific upgrade guidance.\u003C/p\u003E\n\u003Cp\u003EThis page provides an overview of stable UltimateAuth releases, their migration impact, and any actions required when upgrading.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EMost updates require little or no application code changes.\u003C/strong\u003E When an update requires attention, a dedicated migration guide explains what changed and how to adapt your application.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022version-migration-overview\u0022\u003EVersion Migration Overview\u003C/h2\u003E\n\u003Cp\u003EThe table below lists stable releases in descending order, with the newest version first.\u003C/p\u003E\n\u003Cp\u003EPreview and release candidate versions are excluded.\u003C/p\u003E\n\u003Cdiv class=\u0022docs-table-wrapper\u0022\u003E\u003Ctable\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n\u003Cth\u003EVersion\u003C/th\u003E\n\u003Cth\u003EMigration Impact\u003C/th\u003E\n\u003Cth\u003EWhat\u0027s Changed\u003C/th\u003E\n\u003Cth\u003EMigration Guide\u003C/th\u003E\n\u003C/tr\u003E\n\u003C/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.2.0 (In Progress)\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003EMedium (Provisional)\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003EAsync authorization APIs, authorization checks, and integration changes\u003C/td\u003E\n\u003Ctd\u003E\u003Ca href=\u0022/docs/migration/v0.2.0\u0022\u003EView Guide\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.1.4\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003ELow\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003ECSRF protection, antiforgery integration, and interface changes\u003C/td\u003E\n\u003Ctd\u003E\u003Ca href=\u0022/docs/migration/v0.1.4\u0022\u003EView Guide\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.1.3\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003ENone\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003ESession deletion, revocation, and refresh consistency fixes\u003C/td\u003E\n\u003Ctd\u003ENot required\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.1.2\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003ENone\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003EPassword change transaction and session revocation fixes\u003C/td\u003E\n\u003Ctd\u003ENot required\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.1.1\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003ELow\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003EBlazor route authorization and component lifecycle changes\u003C/td\u003E\n\u003Ctd\u003E\u003Ca href=\u0022/docs/migration/v0.1.1\u0022\u003EView Guide\u003C/a\u003E\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003Ev0.1.0\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003E\u003Cstrong\u003EN/A\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003EInitial stable release\u003C/td\u003E\n\u003Ctd\u003ENot applicable\u003C/td\u003E\n\u003C/tr\u003E\n\u003C/tbody\u003E\n\u003C/table\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EMigration impact describes the expected developer effort and affected integration surface, not the size of the code change or the significance of the release.\u003C/strong\u003E A small change to a widely used authentication API may have a higher migration impact than a large internal refactor.\u003C/p\u003E\n\u003Cblockquote\u003E\n\u003Cp\u003EIndividual preview and release candidate versions are not listed separately. Migration guidance for an in-progress release may change before its stable release.\u003C/p\u003E\n\u003C/blockquote\u003E\n\u003Cp\u003ESecurity and reliability fixes may have an impact of \u003Cstrong\u003ENone\u003C/strong\u003E while still being strongly recommended.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022understanding-migration-impact\u0022\u003EUnderstanding Migration Impact\u003C/h2\u003E\n\u003Cdiv class=\u0022docs-table-wrapper\u0022\u003E\u003Ctable\u003E\n\u003Cthead\u003E\n\u003Ctr\u003E\n\u003Cth\u003EImpact\u003C/th\u003E\n\u003Cth\u003EMeaning\u003C/th\u003E\n\u003Cth\u003EExpected Action\u003C/th\u003E\n\u003C/tr\u003E\n\u003C/thead\u003E\n\u003Ctbody\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003ENone\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003ENo application code or configuration changes are required for standard integrations.\u003C/td\u003E\n\u003Ctd\u003EUpdate packages and run existing tests.\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003ELow\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003ESmall, localized changes may be required, typically for specific integrations or customizations.\u003C/td\u003E\n\u003Ctd\u003EReview the migration guide and update affected code.\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003EMedium\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003EChanges affect commonly used APIs, core integration points, or multiple application areas. Even a small code change is classified as Medium when developers must update functionality they use directly and extensively.\u003C/td\u003E\n\u003Ctd\u003EReview the migration guide, update affected integrations, and perform targeted regression testing.\u003C/td\u003E\n\u003C/tr\u003E\n\u003Ctr\u003E\n\u003Ctd\u003E\u003Cstrong\u003EHigh\u003C/strong\u003E\u003C/td\u003E\n\u003Ctd\u003ESignificant architectural, API, persistence, or behavioral changes require a planned migration.\u003C/td\u003E\n\u003Ctd\u003EReview all migration steps, test thoroughly, and plan deployment carefully.\u003C/td\u003E\n\u003C/tr\u003E\n\u003C/tbody\u003E\n\u003C/table\u003E\u003C/div\u003E\n\u003Cp\u003EMigration impact is evaluated using both \u003Cstrong\u003Ethe effort required and how directly the changes affect application developers\u003C/strong\u003E.\u003C/p\u003E\n\u003Cp\u003EA change does not qualify as Low simply because it requires only a few lines of code. Breaking changes to frequently used authentication, authorization, session management, or client integration APIs may be classified as Medium even when the implementation changes are relatively small.\u003C/p\u003E\n\u003Cp\u003EApplications using only unaffected functionality may require fewer changes than the stated impact level suggests.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022how-to-upgrade\u0022\u003EHow to Upgrade\u003C/h2\u003E\n\u003Col\u003E\n\u003Cli\u003E\u003Cstrong\u003EIdentify your current version.\u003C/strong\u003E Check the installed \u003Ccode\u003ECodeBeam.UltimateAuth.*\u003C/code\u003E NuGet packages.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EReview every version between your current and target versions.\u003C/strong\u003E Migration requirements are cumulative when skipping releases.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EFollow the linked migration guides.\u003C/strong\u003E Apply any required API, configuration, or behavioral changes in version order.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EUpdate your UltimateAuth packages together.\u003C/strong\u003E Keep related packages on compatible versions.\u003C/li\u003E\n\u003Cli\u003E\u003Cstrong\u003EBuild and test your application.\u003C/strong\u003E Verify login, logout, refresh, authorization, and session management flows relevant to your integration.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003EFor releases marked \u003Cstrong\u003ENone\u003C/strong\u003E, no dedicated migration guide is necessary. You should still review the release notes and run your application tests.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022available-migration-guides\u0022\u003EAvailable Migration Guides\u003C/h2\u003E\n\u003Ch3 class=\u0022mud-scrollspy-section\u0022 id=\u0022migrating-to-v0.1.4\u0022\u003E\u003Ca href=\u0022/docs/migration/v0.1.4\u0022\u003EMigrating to v0.1.4\u003C/a\u003E\u003C/h3\u003E\n\u003Cp\u003E\u003Cstrong\u003EImpact: Low\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EIntroduces antiforgery protection for cookie-based authentication flows, updates browser client integration, and changes selected session resolution and browser bridge interfaces.\u003C/p\u003E\n\u003Cp\u003EApplications using the standard UltimateAuth browser client generally receive antiforgery handling automatically.\u003C/p\u003E\n\u003Cp\u003ECustom HTTP clients, manually implemented browser bridges, and custom session resolvers should review the guide.\u003C/p\u003E\n\u003Ch3 class=\u0022mud-scrollspy-section\u0022 id=\u0022migrating-to-v0.1.1\u0022\u003E\u003Ca href=\u0022/docs/migration/v0.1.1\u0022\u003EMigrating to v0.1.1\u003C/a\u003E\u003C/h3\u003E\n\u003Cp\u003E\u003Cstrong\u003EImpact: Low\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EIntroduces routing-level enforcement for \u003Ccode\u003E[UAuthAuthorize]\u003C/code\u003E and updates the \u003Ccode\u003EUAuthComponentBase\u003C/code\u003E lifecycle.\u003C/p\u003E\n\u003Cp\u003EMost applications using the built-in \u003Ccode\u003EUAuthApp\u003C/code\u003E router require no changes. Applications with custom routers, component lifecycle overrides, or specialized session requirements should review the guide.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022release-history\u0022\u003ERelease History\u003C/h2\u003E\n\u003Cp\u003EFor complete release notes, bug fixes, and security updates, visit the \u003Ca href=\u0022https://github.com/CodeBeamOrg/UltimateAuth/releases\u0022\u003EUltimateAuth GitHub Releases\u003C/a\u003E page.\u003C/p\u003E\n\u003Cp\u003EMigration guides focus on changes developers must make to their applications. Release notes provide the complete history of changes in each version.\u003C/p\u003E\n\u003Chr\u003E\n\u003Cp\u003E\u003Cstrong\u003EUpgrading across multiple versions?\u003C/strong\u003E Start with the earliest version after your currently installed release and review each migration entry through your target version.\u003C/p\u003E\n", "Headings": [ { - "Id": "available-guides", - "Text": "Available Guides", + "Id": "version-migration-overview", + "Text": "Version Migration Overview", + "Level": 0 + }, + { + "Id": "understanding-migration-impact", + "Text": "Understanding Migration Impact", + "Level": 0 + }, + { + "Id": "how-to-upgrade", + "Text": "How to Upgrade", + "Level": 0 + }, + { + "Id": "available-migration-guides", + "Text": "Available Migration Guides", + "Level": 0 + }, + { + "Id": "migrating-to-v0.1.4", + "Text": "Migrating to v0.1.4", + "Level": 1 + }, + { + "Id": "migrating-to-v0.1.1", + "Text": "Migrating to v0.1.1", + "Level": 1 + }, + { + "Id": "release-history", + "Text": "Release History", "Level": 0 } ], - "SourceHash": "FA6FAFE02BA9EF2656EBA1C8531CEC3F43A2666D05A61B6E2979BD96B3593D8B", + "SourceHash": "DD4CBD449E209E19EED5EE80BEE6DEA683168AF0485EA7C6CF76F5D80A8A3B76", "BuilderVersion": "1" } \ No newline at end of file diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.1.4.json b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.1.4.json new file mode 100644 index 00000000..fefe0679 --- /dev/null +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.1.4.json @@ -0,0 +1,54 @@ +{ + "Slug": "migration/v0.1.4", + "Title": "Migrating to v0.1.4", + "Html": "\n\u003Cp\u003E\u003Cstrong\u003EMigration Impact: Low\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EUltimateAuth v0.1.4 introduces antiforgery protection for cookie-based authentication flows and updates several client and server integration interfaces.\u003C/p\u003E\n\u003Cp\u003EThe release strengthens protection against Cross-Site Request Forgery (CSRF) while preserving the standard UltimateAuth developer experience.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EMost applications using the built-in UltimateAuth browser client require no application code changes.\u003C/strong\u003E Antiforgery token handling is integrated into the client.\u003C/p\u003E\n\u003Cp\u003EApplications using custom HTTP requests, custom browser bridges, or custom session resolvers should review the changes below.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022antiforgery-protection-for-cookie-based-authentication\u0022\u003E1. Antiforgery Protection for Cookie-Based Authentication\u003C/h2\u003E\n\u003Cp\u003EUltimateAuth now validates antiforgery tokens for protected operations when cookie-based authentication is applicable.\u003C/p\u003E\n\u003Cp\u003EThis includes relevant authentication operations and authenticated state-changing endpoints.\u003C/p\u003E\n\u003Cp\u003ERequests that fail antiforgery validation are rejected with HTTP \u003Ccode\u003E400 Bad Request\u003C/code\u003E and the following error:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EJSON\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-json\u0022\u003E{\n \u0026quot;error\u0026quot;: \u0026quot;invalid_antiforgery_token\u0026quot;\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Ch3 class=\u0022mud-scrollspy-section\u0022 id=\u0022using-the-built-in-browser-client\u0022\u003EUsing the built-in browser client\u003C/h3\u003E\n\u003Cp\u003EThe UltimateAuth browser client now supports retrieving and submitting antiforgery tokens automatically.\u003C/p\u003E\n\u003Cp\u003EIf your application uses the standard UltimateAuth client integration, no additional antiforgery implementation is normally required.\u003C/p\u003E\n\u003Cp\u003EMake sure the server and client packages are updated together.\u003C/p\u003E\n\u003Ch3 class=\u0022mud-scrollspy-section\u0022 id=\u0022using-custom-http-requests\u0022\u003EUsing custom HTTP requests\u003C/h3\u003E\n\u003Cp\u003EIf your application calls protected UltimateAuth endpoints directly from a browser, you must obtain an antiforgery token and submit it with the request.\u003C/p\u003E\n\u003Cp\u003EThe default token endpoint is:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EHTTP\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-http\u0022\u003EGET /auth/antiforgery/token\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThe response contains:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EJSON\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-json\u0022\u003E{\n \u0026quot;requestToken\u0026quot;: \u0026quot;...\u0026quot;,\n \u0026quot;headerName\u0026quot;: \u0026quot;X-UAuth-CSRF\u0026quot;,\n \u0026quot;formFieldName\u0026quot;: \u0026quot;__RequestVerificationToken\u0026quot;\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThe endpoint also issues an antiforgery cookie.\u003C/p\u003E\n\u003Cp\u003EFor subsequent protected requests:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003EObtain a token from the configured antiforgery endpoint.\u003C/li\u003E\n\u003Cli\u003EPreserve the associated antiforgery cookie.\u003C/li\u003E\n\u003Cli\u003ESend the request token using the returned \u003Ccode\u003EheaderName\u003C/code\u003E.\u003C/li\u003E\n\u003Cli\u003EInclude the appropriate authentication credentials for the request.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003EFor example:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EHTTP\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-http\u0022\u003EPOST /auth/logout\nX-UAuth-CSRF: \u0026lt;request-token\u0026gt;\nCookie: \u0026lt;authentication-and-antiforgery-cookies\u0026gt;\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThe request token and antiforgery cookie must belong to the same antiforgery context.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EDo not hardcode or fabricate antiforgery tokens.\u003C/strong\u003E Always obtain them from the server.\u003C/p\u003E\n\u003Cp\u003EThe default endpoint path assumes the standard \u003Ccode\u003E/auth\u003C/code\u003E base path. Applications using custom routing or multi-tenancy must use their configured endpoint URL.\u003C/p\u003E\n\u003Ch3 class=\u0022mud-scrollspy-section\u0022 id=\u0022custom-server-side-integrations\u0022\u003ECustom server-side integrations\u003C/h3\u003E\n\u003Cp\u003EApplications using custom HTTP clients or server-to-server integrations should review whether their requests use cookie-based authentication.\u003C/p\u003E\n\u003Cp\u003EAntiforgery requirements depend on the authentication transport and operation. They are not automatically equivalent for every bearer-token or header-based request.\u003C/p\u003E\n\u003Cp\u003EDo not disable antiforgery validation to resolve an integration failure. Update the affected request flow instead.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022isessionidresolver-is-now-asynchronous\u0022\u003E2. ISessionIdResolver Is Now Asynchronous\u003C/h2\u003E\n\u003Cp\u003EThe \u003Ccode\u003EISessionIdResolver\u003C/code\u003E interface has changed to support asynchronous session resolution.\u003C/p\u003E\n\u003Cp\u003EIf you implement this interface yourself, update the implementation.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore (v0.1.3):\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic AuthSessionId? Resolve(HttpContext context)\n{\n // Resolve the session identifier.\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter (v0.1.4):\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic ValueTask\u0026lt;AuthSessionId?\u0026gt; ResolveAsync(HttpContext context, CancellationToken ct = default)\n{\n ct.ThrowIfCancellationRequested();\n\n // Resolve the session identifier.\n return ValueTask.FromResult\u0026lt;AuthSessionId?\u0026gt;(null);\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EReplace the placeholder return with your existing resolution logic.\u003C/p\u003E\n\u003Cp\u003EIf your resolver performs asynchronous operations, use an \u003Ccode\u003Easync ValueTask\u0026lt;AuthSessionId?\u0026gt;\u003C/code\u003E implementation and await those operations.\u003C/p\u003E\n\u003Cp\u003EUpdate any direct calls from \u003Ccode\u003EResolve(...)\u003C/code\u003E to \u003Ccode\u003EResolveAsync(...)\u003C/code\u003E and await the result.\u003C/p\u003E\n\u003Cp\u003EApplications using the built-in session resolver do not need to make this change.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022custom-browser-bridges\u0022\u003E3. Custom Browser Bridges\u003C/h2\u003E\n\u003Cp\u003EThe \u003Ccode\u003EIBrowserUAuthBridge\u003C/code\u003E interface now includes:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003EValueTask ConfigureAntiforgeryAsync(string tokenUrl, string? trustedOrigin = null);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThis allows the UltimateAuth client bootstrapper to configure antiforgery handling for browser requests.\u003C/p\u003E\n\u003Cp\u003EIf you provide a custom implementation of \u003Ccode\u003EIBrowserUAuthBridge\u003C/code\u003E, implement this new method.\u003C/p\u003E\n\u003Cp\u003EYour implementation must configure the browser-side antiforgery integration using the supplied token endpoint and optional trusted origin.\u003C/p\u003E\n\u003Cp\u003EThe exact implementation depends on your browser integration.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EDo not add an empty implementation unless antiforgery handling is already provided by your custom bridge.\u003C/strong\u003E Doing so may leave protected browser requests without the required token.\u003C/p\u003E\n\u003Cp\u003EApplications using the built-in UltimateAuth browser bridge do not need to make this change.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022antiforgery-endpoint-configuration\u0022\u003E4. Antiforgery Endpoint Configuration\u003C/h2\u003E\n\u003Cp\u003Ev0.1.4 introduces a server-side antiforgery configuration section:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eoptions.Antiforgery.TokenEndpoint = \u0026quot;/antiforgery/token\u0026quot;;\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThe client also exposes the corresponding endpoint setting:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eoptions.Endpoints.AntiforgeryToken = \u0026quot;/antiforgery/token\u0026quot;;\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThe default endpoint path is \u003Ccode\u003E/antiforgery/token\u003C/code\u003E, resolved under the configured UltimateAuth base path.\u003C/p\u003E\n\u003Cp\u003ENo configuration change is required when using the defaults.\u003C/p\u003E\n\u003Cp\u003EIf you customize the endpoint, ensure the server and client configurations match.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022verify-your-application\u0022\u003E5. Verify Your Application\u003C/h2\u003E\n\u003Cp\u003EAfter upgrading to v0.1.4, verify the following flows where applicable:\u003C/p\u003E\n\u003Cul\u003E\n\u003Cli\u003ELogin and logout using the built-in browser client.\u003C/li\u003E\n\u003Cli\u003ESession refresh and validation.\u003C/li\u003E\n\u003Cli\u003EAuthenticated account and session management operations.\u003C/li\u003E\n\u003Cli\u003ECustom requests to UltimateAuth endpoints.\u003C/li\u003E\n\u003Cli\u003ECustom session resolver implementations.\u003C/li\u003E\n\u003Cli\u003ECustom browser bridge implementations.\u003C/li\u003E\n\u003Cli\u003EExternal Hub and multi-tenant configurations.\u003C/li\u003E\n\u003C/ul\u003E\n\u003Cp\u003EFor applications using custom browser requests, verify that valid antiforgery tokens allow protected operations and missing or invalid tokens are rejected.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022migration-checklist\u0022\u003EMigration Checklist\u003C/h2\u003E\n\u003Cul class=\u0022contains-task-list\u0022\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Update UltimateAuth packages to compatible v0.1.4 versions.\u003C/li\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Update custom \u003Ccode\u003EISessionIdResolver\u003C/code\u003E implementations, if any.\u003C/li\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Update custom \u003Ccode\u003EIBrowserUAuthBridge\u003C/code\u003E implementations, if any.\u003C/li\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Add antiforgery token handling to custom browser HTTP requests, if applicable.\u003C/li\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Verify custom antiforgery endpoint configuration, if applicable.\u003C/li\u003E\n\u003Cli class=\u0022task-list-item\u0022\u003E\u003Cinput disabled=\u0022disabled\u0022 type=\u0022checkbox\u0022\u003E Run authentication, authorization, and session regression tests.\u003C/li\u003E\n\u003C/ul\u003E\n\u003Chr\u003E\n\u003Cp\u003E\u003Cstrong\u003EUsing the standard UltimateAuth client and built-in session resolution?\u003C/strong\u003E No application code changes are normally required. Update your packages and verify your existing authentication flows.\u003C/p\u003E\n\u003Cp\u003EFor the complete list of changes, see \u003Ca href=\u0022https://github.com/CodeBeamOrg/UltimateAuth/releases/tag/v0.1.4\u0022\u003EUltimateAuth v0.1.4 Release\u003C/a\u003E.\u003C/p\u003E\n", + "Headings": [ + { + "Id": "antiforgery-protection-for-cookie-based-authentication", + "Text": "1. Antiforgery Protection for Cookie-Based Authentication", + "Level": 0 + }, + { + "Id": "using-the-built-in-browser-client", + "Text": "Using the built-in browser client", + "Level": 1 + }, + { + "Id": "using-custom-http-requests", + "Text": "Using custom HTTP requests", + "Level": 1 + }, + { + "Id": "custom-server-side-integrations", + "Text": "Custom server-side integrations", + "Level": 1 + }, + { + "Id": "isessionidresolver-is-now-asynchronous", + "Text": "2. ISessionIdResolver Is Now Asynchronous", + "Level": 0 + }, + { + "Id": "custom-browser-bridges", + "Text": "3. Custom Browser Bridges", + "Level": 0 + }, + { + "Id": "antiforgery-endpoint-configuration", + "Text": "4. Antiforgery Endpoint Configuration", + "Level": 0 + }, + { + "Id": "verify-your-application", + "Text": "5. Verify Your Application", + "Level": 0 + }, + { + "Id": "migration-checklist", + "Text": "Migration Checklist", + "Level": 0 + } + ], + "SourceHash": "F8FA4FDA0E64B56BADDBA75519538C1ACBFDF88567EF487D30011FAB944B67CC", + "BuilderVersion": "1" +} \ No newline at end of file diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json new file mode 100644 index 00000000..0a2cd895 --- /dev/null +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json @@ -0,0 +1,39 @@ +{ + "Slug": "migration/v0.2.0", + "Title": "Migrating to v0.2.0", + "Html": "\n\u003Cp\u003E\u003Cstrong\u003EMigration Impact: Medium \u2014 In Progress\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003ELatest published prerelease reviewed: v0.2.0-preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThis guide covers migration requirements for the upcoming UltimateAuth v0.2.0 release.\u003C/p\u003E\n\u003Cp\u003EThe guide is provisional and will be updated as new preview and release candidate versions become available. The final migration requirements may change before the stable v0.2.0 release.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022asynchronous-authorization-policies\u0022\u003E1. Asynchronous Authorization Policies\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003ECustom implementations of \u003Ccode\u003EIAccessPolicy\u003C/code\u003E, \u003Ccode\u003EIAccessInvariant\u003C/code\u003E, and \u003Ccode\u003EIAccessAuthority\u003C/code\u003E should migrate to \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic AccessDecision Decide(AccessContext context)\n{\n return AccessDecision.Allow();\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic ValueTask\u0026lt;AccessDecision\u0026gt; DecideAsync(AccessContext context, CancellationToken ct = default)\n{\n return ValueTask.FromResult(AccessDecision.Allow());\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EFor \u003Ccode\u003EIAccessAuthority\u003C/code\u003E, preserve the existing \u003Ccode\u003EruntimePolicies\u003C/code\u003E parameter and add the cancellation token.\u003C/p\u003E\n\u003Cp\u003ESynchronous \u003Ccode\u003EDecide\u003C/code\u003E methods are obsolete. Existing synchronous implementations retain compatibility through the interface defaults, but new implementations should use \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EIf your application invokes an authority directly, switch to \u003Ccode\u003EDecideAsync\u003C/code\u003E and await the result.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022authorization-check-results\u0022\u003E2. Authorization Check Results\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Ccode\u003ECheckAsync\u003C/code\u003E now returns an explicit authorization decision in the response body.\u003C/p\u003E\n\u003Cp\u003EIf your application previously interpreted HTTP \u003Ccode\u003E403\u003C/code\u003E as the result of a successful authorization evaluation that denied access, update that handling.\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Evar result = await UAuthClient.Authorization.CheckAsync(request);\n\nif (result.IsSuccess \u0026amp;\u0026amp; result.Value is { IsAllowed: true })\n{\n // Authorized\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EAn HTTP-successful authorization check does not necessarily mean that access was granted.\u003C/p\u003E\n\u003Cp\u003EInspect the returned authorization decision rather than relying solely on the HTTP status.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022custom-user-lifecycle-integrations\u0022\u003E3. Custom User Lifecycle Integrations\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe \u003Ccode\u003EIUserLifecycleIntegration.OnUserCreatedAsync\u003C/code\u003E signature now includes \u003Ccode\u003EUAuthClientProfile\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n UAuthClientProfile clientProfile,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EUpdate custom implementations to accept the additional client profile parameter.\u003C/p\u003E\n\u003Cp\u003EApplications using built-in lifecycle integrations do not need to make this change.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022identifier-and-profile-limits\u0022\u003E4. Identifier and Profile Limits\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference Users domain now enforces additional identifier and profile safety limits.\u003C/p\u003E\n\u003Cp\u003EThe default maximum is 10 active identifiers per user. Applications requiring a different capacity should configure \u003Ccode\u003EIdentifiers.Behavior.MaxIdentifiersPerUser\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EExisting profile creation and update operations must also respect the new field-length and metadata limits.\u003C/p\u003E\n\u003Cp\u003EIf you use EF Core persistence:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003EReview existing profile data for values exceeding the new limits.\u003C/li\u003E\n\u003Cli\u003EAdd or apply the appropriate EF Core database migration for your application\u0027s DbContext.\u003C/li\u003E\n\u003Cli\u003EVerify that applications handling profile validation errors use the returned error codes.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/plugin-domains/profile-validation-limits\u0022\u003EProfile Validation \u0026amp; Limits\u003C/a\u003E for the supported limits.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022password-policies-and-history\u0022\u003E5. Password Policies and History\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference password credential implementation now applies configurable password policies, with Standard as the default level.\u003C/p\u003E\n\u003Cp\u003EReview custom registration, password-change, and password-reset flows to ensure that they handle server-side password validation errors.\u003C/p\u003E\n\u003Cp\u003EApplications using persistent password-history storage must apply the required database migration before enabling password history.\u003C/p\u003E\n\u003Cp\u003EPassword history is disabled by default (\u003Ccode\u003ERememberLast = 0\u003C/code\u003E).\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/password-policy\u0022\u003EPassword Policy \u0026amp; History\u003C/a\u003E for configuration and persistence requirements.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022rate-limiting\u0022\u003E6. Rate Limiting\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EBuilt-in endpoint rate limiting is enabled by default when using:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore();\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EIf your application already registers its own rate limiting middleware, avoid installing a duplicate limiter.\u003C/p\u003E\n\u003Cp\u003ETo retain application-owned rate limiting:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore(useRateLimiting: false);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThen configure your existing \u003Ccode\u003EUseRateLimiter()\u003C/code\u003E middleware in the appropriate pipeline position.\u003C/p\u003E\n\u003Cp\u003EApplications using \u003Ccode\u003EUseUltimateAuth()\u003C/code\u003E without the integrated ASP.NET Core helper do not enable UltimateAuth rate limiting by default.\u003C/p\u003E\n\u003Cp\u003EReview custom HTTP clients and authentication flows for HTTP \u003Ccode\u003E429 Too Many Requests\u003C/code\u003E handling.\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/rate-limiting\u0022\u003ERate Limiting\u003C/a\u003E for middleware integration and defaults.\u003C/p\u003E\n\u003Chr\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore upgrading:\u003C/strong\u003E Review the migration steps applicable to your installed prerelease version. Sections marked \u003Cstrong\u003ECurrent dev\u003C/strong\u003E describe upcoming changes and may be revised before their first published prerelease.\u003C/p\u003E\n\u003Cp\u003EThis page will continue to evolve through the v0.2.0 preview and RC series and will become the stable migration guide when v0.2.0 is released.\u003C/p\u003E\n", + "Headings": [ + { + "Id": "asynchronous-authorization-policies", + "Text": "1. Asynchronous Authorization Policies", + "Level": 0 + }, + { + "Id": "authorization-check-results", + "Text": "2. Authorization Check Results", + "Level": 0 + }, + { + "Id": "custom-user-lifecycle-integrations", + "Text": "3. Custom User Lifecycle Integrations", + "Level": 0 + }, + { + "Id": "identifier-and-profile-limits", + "Text": "4. Identifier and Profile Limits", + "Level": 0 + }, + { + "Id": "password-policies-and-history", + "Text": "5. Password Policies and History", + "Level": 0 + }, + { + "Id": "rate-limiting", + "Text": "6. Rate Limiting", + "Level": 0 + } + ], + "SourceHash": "B45903FF622268C6416F9DA0201D80F549E297ECF30E27449EE09A6864688E45", + "BuilderVersion": "1" +} \ No newline at end of file diff --git a/src/client/CodeBeam.UltimateAuth.Client.Blazor/Components/UAuthLoginForm.razor.cs b/src/client/CodeBeam.UltimateAuth.Client.Blazor/Components/UAuthLoginForm.razor.cs index 7ff71a56..d9c54663 100644 --- a/src/client/CodeBeam.UltimateAuth.Client.Blazor/Components/UAuthLoginForm.razor.cs +++ b/src/client/CodeBeam.UltimateAuth.Client.Blazor/Components/UAuthLoginForm.razor.cs @@ -95,6 +95,13 @@ public partial class UAuthLoginForm [Parameter] public EventCallback OnTryResult { get; set; } + private bool _isSubmitting; + + [Parameter] + public EventCallback OnSubmittingChanged { get; set; } + + public bool IsSubmitting => _isSubmitting; + private ElementReference _form; private HubCredentials? _credentials; @@ -174,16 +181,31 @@ public async Task ReloadAsync() /// Thrown if the form has not been rendered. Call this method only after the OnAfterRender lifecycle event. public async Task SubmitAsync() { + if (_isSubmitting) + return; + if (_form.Context is null) throw new InvalidOperationException("Form is not yet rendered. Call SubmitAsync after OnAfterRender."); - if (LoginType == UAuthLoginType.Pkce) + _isSubmitting = true; + + try { - await SubmitPkceAsync(); + await OnSubmittingChanged.InvokeAsync(true); + + if (LoginType == UAuthLoginType.Pkce) + { + await SubmitPkceAsync(); + } + else + { + await SubmitPasswordAsync(); + } } - else + finally { - await SubmitPasswordAsync(); + _isSubmitting = false; + await OnSubmittingChanged.InvokeAsync(false); } } From 158836008bba36f284b1f26ef5b721bedbc9d52c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mehmet=20Can=20Karag=C3=B6z?= Date: Sat, 7 Nov 2026 20:51:34 +0300 Subject: [PATCH 2/2] Completed Implementations --- .../Components/Pages/LoginPage.razor | 6 ++++-- docs/content/migration/v0.2.0.md | 2 -- .../wwwroot/docs/migration/v0.2.0.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor index aeb2ed2e..d512cd87 100644 --- a/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor +++ b/apps/identity-lab/CodeBeam.UltimateAuth.IdentityLab/Components/Pages/LoginPage.razor @@ -198,14 +198,16 @@ Disabled="@_loginBusy" Immediate="true" /> - @(IsLockedOut ? "Temporarily locked" : "Sign In") - + diff --git a/docs/content/migration/v0.2.0.md b/docs/content/migration/v0.2.0.md index cdc4ab5b..08c132d9 100644 --- a/docs/content/migration/v0.2.0.md +++ b/docs/content/migration/v0.2.0.md @@ -156,6 +156,4 @@ See [Rate Limiting](/docs/security/rate-limiting) for middleware integration and --- -**Before upgrading:** Review the migration steps applicable to your installed prerelease version. Sections marked **Current dev** describe upcoming changes and may be revised before their first published prerelease. - This page will continue to evolve through the v0.2.0 preview and RC series and will become the stable migration guide when v0.2.0 is released. diff --git a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json index 0a2cd895..a0206e85 100644 --- a/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json +++ b/docs/website/CodeBeam.UltimateAuth.Docs.Wasm/CodeBeam.UltimateAuth.Docs.Wasm.Client/wwwroot/docs/migration/v0.2.0.json @@ -1,7 +1,7 @@ { "Slug": "migration/v0.2.0", "Title": "Migrating to v0.2.0", - "Html": "\n\u003Cp\u003E\u003Cstrong\u003EMigration Impact: Medium \u2014 In Progress\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003ELatest published prerelease reviewed: v0.2.0-preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThis guide covers migration requirements for the upcoming UltimateAuth v0.2.0 release.\u003C/p\u003E\n\u003Cp\u003EThe guide is provisional and will be updated as new preview and release candidate versions become available. The final migration requirements may change before the stable v0.2.0 release.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022asynchronous-authorization-policies\u0022\u003E1. Asynchronous Authorization Policies\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003ECustom implementations of \u003Ccode\u003EIAccessPolicy\u003C/code\u003E, \u003Ccode\u003EIAccessInvariant\u003C/code\u003E, and \u003Ccode\u003EIAccessAuthority\u003C/code\u003E should migrate to \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic AccessDecision Decide(AccessContext context)\n{\n return AccessDecision.Allow();\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic ValueTask\u0026lt;AccessDecision\u0026gt; DecideAsync(AccessContext context, CancellationToken ct = default)\n{\n return ValueTask.FromResult(AccessDecision.Allow());\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EFor \u003Ccode\u003EIAccessAuthority\u003C/code\u003E, preserve the existing \u003Ccode\u003EruntimePolicies\u003C/code\u003E parameter and add the cancellation token.\u003C/p\u003E\n\u003Cp\u003ESynchronous \u003Ccode\u003EDecide\u003C/code\u003E methods are obsolete. Existing synchronous implementations retain compatibility through the interface defaults, but new implementations should use \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EIf your application invokes an authority directly, switch to \u003Ccode\u003EDecideAsync\u003C/code\u003E and await the result.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022authorization-check-results\u0022\u003E2. Authorization Check Results\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Ccode\u003ECheckAsync\u003C/code\u003E now returns an explicit authorization decision in the response body.\u003C/p\u003E\n\u003Cp\u003EIf your application previously interpreted HTTP \u003Ccode\u003E403\u003C/code\u003E as the result of a successful authorization evaluation that denied access, update that handling.\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Evar result = await UAuthClient.Authorization.CheckAsync(request);\n\nif (result.IsSuccess \u0026amp;\u0026amp; result.Value is { IsAllowed: true })\n{\n // Authorized\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EAn HTTP-successful authorization check does not necessarily mean that access was granted.\u003C/p\u003E\n\u003Cp\u003EInspect the returned authorization decision rather than relying solely on the HTTP status.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022custom-user-lifecycle-integrations\u0022\u003E3. Custom User Lifecycle Integrations\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe \u003Ccode\u003EIUserLifecycleIntegration.OnUserCreatedAsync\u003C/code\u003E signature now includes \u003Ccode\u003EUAuthClientProfile\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n UAuthClientProfile clientProfile,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EUpdate custom implementations to accept the additional client profile parameter.\u003C/p\u003E\n\u003Cp\u003EApplications using built-in lifecycle integrations do not need to make this change.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022identifier-and-profile-limits\u0022\u003E4. Identifier and Profile Limits\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference Users domain now enforces additional identifier and profile safety limits.\u003C/p\u003E\n\u003Cp\u003EThe default maximum is 10 active identifiers per user. Applications requiring a different capacity should configure \u003Ccode\u003EIdentifiers.Behavior.MaxIdentifiersPerUser\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EExisting profile creation and update operations must also respect the new field-length and metadata limits.\u003C/p\u003E\n\u003Cp\u003EIf you use EF Core persistence:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003EReview existing profile data for values exceeding the new limits.\u003C/li\u003E\n\u003Cli\u003EAdd or apply the appropriate EF Core database migration for your application\u0027s DbContext.\u003C/li\u003E\n\u003Cli\u003EVerify that applications handling profile validation errors use the returned error codes.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/plugin-domains/profile-validation-limits\u0022\u003EProfile Validation \u0026amp; Limits\u003C/a\u003E for the supported limits.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022password-policies-and-history\u0022\u003E5. Password Policies and History\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference password credential implementation now applies configurable password policies, with Standard as the default level.\u003C/p\u003E\n\u003Cp\u003EReview custom registration, password-change, and password-reset flows to ensure that they handle server-side password validation errors.\u003C/p\u003E\n\u003Cp\u003EApplications using persistent password-history storage must apply the required database migration before enabling password history.\u003C/p\u003E\n\u003Cp\u003EPassword history is disabled by default (\u003Ccode\u003ERememberLast = 0\u003C/code\u003E).\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/password-policy\u0022\u003EPassword Policy \u0026amp; History\u003C/a\u003E for configuration and persistence requirements.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022rate-limiting\u0022\u003E6. Rate Limiting\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EBuilt-in endpoint rate limiting is enabled by default when using:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore();\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EIf your application already registers its own rate limiting middleware, avoid installing a duplicate limiter.\u003C/p\u003E\n\u003Cp\u003ETo retain application-owned rate limiting:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore(useRateLimiting: false);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThen configure your existing \u003Ccode\u003EUseRateLimiter()\u003C/code\u003E middleware in the appropriate pipeline position.\u003C/p\u003E\n\u003Cp\u003EApplications using \u003Ccode\u003EUseUltimateAuth()\u003C/code\u003E without the integrated ASP.NET Core helper do not enable UltimateAuth rate limiting by default.\u003C/p\u003E\n\u003Cp\u003EReview custom HTTP clients and authentication flows for HTTP \u003Ccode\u003E429 Too Many Requests\u003C/code\u003E handling.\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/rate-limiting\u0022\u003ERate Limiting\u003C/a\u003E for middleware integration and defaults.\u003C/p\u003E\n\u003Chr\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore upgrading:\u003C/strong\u003E Review the migration steps applicable to your installed prerelease version. Sections marked \u003Cstrong\u003ECurrent dev\u003C/strong\u003E describe upcoming changes and may be revised before their first published prerelease.\u003C/p\u003E\n\u003Cp\u003EThis page will continue to evolve through the v0.2.0 preview and RC series and will become the stable migration guide when v0.2.0 is released.\u003C/p\u003E\n", + "Html": "\n\u003Cp\u003E\u003Cstrong\u003EMigration Impact: Medium \u2014 In Progress\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003ELatest published prerelease reviewed: v0.2.0-preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThis guide covers migration requirements for the upcoming UltimateAuth v0.2.0 release.\u003C/p\u003E\n\u003Cp\u003EThe guide is provisional and will be updated as new preview and release candidate versions become available. The final migration requirements may change before the stable v0.2.0 release.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022asynchronous-authorization-policies\u0022\u003E1. Asynchronous Authorization Policies\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003ECustom implementations of \u003Ccode\u003EIAccessPolicy\u003C/code\u003E, \u003Ccode\u003EIAccessInvariant\u003C/code\u003E, and \u003Ccode\u003EIAccessAuthority\u003C/code\u003E should migrate to \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic AccessDecision Decide(AccessContext context)\n{\n return AccessDecision.Allow();\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Epublic ValueTask\u0026lt;AccessDecision\u0026gt; DecideAsync(AccessContext context, CancellationToken ct = default)\n{\n return ValueTask.FromResult(AccessDecision.Allow());\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EFor \u003Ccode\u003EIAccessAuthority\u003C/code\u003E, preserve the existing \u003Ccode\u003EruntimePolicies\u003C/code\u003E parameter and add the cancellation token.\u003C/p\u003E\n\u003Cp\u003ESynchronous \u003Ccode\u003EDecide\u003C/code\u003E methods are obsolete. Existing synchronous implementations retain compatibility through the interface defaults, but new implementations should use \u003Ccode\u003EDecideAsync\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EIf your application invokes an authority directly, switch to \u003Ccode\u003EDecideAsync\u003C/code\u003E and await the result.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022authorization-check-results\u0022\u003E2. Authorization Check Results\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.1\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003E\u003Ccode\u003ECheckAsync\u003C/code\u003E now returns an explicit authorization decision in the response body.\u003C/p\u003E\n\u003Cp\u003EIf your application previously interpreted HTTP \u003Ccode\u003E403\u003C/code\u003E as the result of a successful authorization evaluation that denied access, update that handling.\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Evar result = await UAuthClient.Authorization.CheckAsync(request);\n\nif (result.IsSuccess \u0026amp;\u0026amp; result.Value is { IsAllowed: true })\n{\n // Authorized\n}\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EAn HTTP-successful authorization check does not necessarily mean that access was granted.\u003C/p\u003E\n\u003Cp\u003EInspect the returned authorization decision rather than relying solely on the HTTP status.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022custom-user-lifecycle-integrations\u0022\u003E3. Custom User Lifecycle Integrations\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe \u003Ccode\u003EIUserLifecycleIntegration.OnUserCreatedAsync\u003C/code\u003E signature now includes \u003Ccode\u003EUAuthClientProfile\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003E\u003Cstrong\u003EBefore:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003E\u003Cstrong\u003EAfter:\u003C/strong\u003E\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003ETask OnUserCreatedAsync(\n TenantKey tenant,\n UserKey userKey,\n object request,\n UAuthClientProfile clientProfile,\n CancellationToken ct = default);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EUpdate custom implementations to accept the additional client profile parameter.\u003C/p\u003E\n\u003Cp\u003EApplications using built-in lifecycle integrations do not need to make this change.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022identifier-and-profile-limits\u0022\u003E4. Identifier and Profile Limits\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference Users domain now enforces additional identifier and profile safety limits.\u003C/p\u003E\n\u003Cp\u003EThe default maximum is 10 active identifiers per user. Applications requiring a different capacity should configure \u003Ccode\u003EIdentifiers.Behavior.MaxIdentifiersPerUser\u003C/code\u003E.\u003C/p\u003E\n\u003Cp\u003EExisting profile creation and update operations must also respect the new field-length and metadata limits.\u003C/p\u003E\n\u003Cp\u003EIf you use EF Core persistence:\u003C/p\u003E\n\u003Col\u003E\n\u003Cli\u003EReview existing profile data for values exceeding the new limits.\u003C/li\u003E\n\u003Cli\u003EAdd or apply the appropriate EF Core database migration for your application\u0027s DbContext.\u003C/li\u003E\n\u003Cli\u003EVerify that applications handling profile validation errors use the returned error codes.\u003C/li\u003E\n\u003C/ol\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/plugin-domains/profile-validation-limits\u0022\u003EProfile Validation \u0026amp; Limits\u003C/a\u003E for the supported limits.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022password-policies-and-history\u0022\u003E5. Password Policies and History\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EThe reference password credential implementation now applies configurable password policies, with Standard as the default level.\u003C/p\u003E\n\u003Cp\u003EReview custom registration, password-change, and password-reset flows to ensure that they handle server-side password validation errors.\u003C/p\u003E\n\u003Cp\u003EApplications using persistent password-history storage must apply the required database migration before enabling password history.\u003C/p\u003E\n\u003Cp\u003EPassword history is disabled by default (\u003Ccode\u003ERememberLast = 0\u003C/code\u003E).\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/password-policy\u0022\u003EPassword Policy \u0026amp; History\u003C/a\u003E for configuration and persistence requirements.\u003C/p\u003E\n\u003Ch2 class=\u0022mud-scrollspy-section\u0022 id=\u0022rate-limiting\u0022\u003E6. Rate Limiting\u003C/h2\u003E\n\u003Cp\u003E\u003Cstrong\u003EAvailable since preview.2\u003C/strong\u003E\u003C/p\u003E\n\u003Cp\u003EBuilt-in endpoint rate limiting is enabled by default when using:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore();\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EIf your application already registers its own rate limiting middleware, avoid installing a duplicate limiter.\u003C/p\u003E\n\u003Cp\u003ETo retain application-owned rate limiting:\u003C/p\u003E\n\u003Cdiv class=\u0022docs-code-wrapper\u0022\u003E\u003Cdiv class=\u0022docs-code-header\u0022\u003E\u003Cspan class=\u0022docs-code-language\u0022\u003EC#\u003C/span\u003E\u003Cbutton type=\u0022button\u0022 class=\u0022docs-code-copy\u0022 aria-label=\u0022Copy code\u0022\u003ECopy\u003C/button\u003E\u003C/div\u003E\u003Cpre\u003E\u003Ccode class=\u0022language-csharp\u0022\u003Eapp.UseUltimateAuthWithAspNetCore(useRateLimiting: false);\n\u003C/code\u003E\u003C/pre\u003E\u003C/div\u003E\n\u003Cp\u003EThen configure your existing \u003Ccode\u003EUseRateLimiter()\u003C/code\u003E middleware in the appropriate pipeline position.\u003C/p\u003E\n\u003Cp\u003EApplications using \u003Ccode\u003EUseUltimateAuth()\u003C/code\u003E without the integrated ASP.NET Core helper do not enable UltimateAuth rate limiting by default.\u003C/p\u003E\n\u003Cp\u003EReview custom HTTP clients and authentication flows for HTTP \u003Ccode\u003E429 Too Many Requests\u003C/code\u003E handling.\u003C/p\u003E\n\u003Cp\u003ESee \u003Ca href=\u0022/docs/security/rate-limiting\u0022\u003ERate Limiting\u003C/a\u003E for middleware integration and defaults.\u003C/p\u003E\n\u003Chr\u003E\n\u003Cp\u003EThis page will continue to evolve through the v0.2.0 preview and RC series and will become the stable migration guide when v0.2.0 is released.\u003C/p\u003E\n", "Headings": [ { "Id": "asynchronous-authorization-policies", @@ -34,6 +34,6 @@ "Level": 0 } ], - "SourceHash": "B45903FF622268C6416F9DA0201D80F549E297ECF30E27449EE09A6864688E45", + "SourceHash": "99DF0B4E30A8578E3B2E809B38606FC0041D6A54F05EECDC98D95E8FD78DCBBA", "BuilderVersion": "1" } \ No newline at end of file