diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs index 9d7e30adae19..5f0d9418d9c5 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/IdentityRedirectManager.cs @@ -1,20 +1,10 @@ using Microsoft.AspNetCore.Components; -using Microsoft.AspNetCore.Identity; -using BlazorWebCSharp._1.Data; namespace BlazorWebCSharp._1.Components.Account; internal sealed class IdentityRedirectManager(NavigationManager navigationManager) { - public const string StatusCookieName = "Identity.StatusMessage"; - - private static readonly CookieBuilder StatusCookieBuilder = new() - { - SameSite = SameSiteMode.Strict, - HttpOnly = true, - IsEssential = true, - MaxAge = TimeSpan.FromSeconds(5), - }; + public const string StatusMessageKey = "Identity.StatusMessage"; public void RedirectTo(string? uri) { @@ -36,19 +26,7 @@ public void RedirectTo(string uri, Dictionary queryParameters) RedirectTo(newUri); } - public void RedirectToWithStatus(string uri, string message, HttpContext context) - { - context.Response.Cookies.Append(StatusCookieName, message, StatusCookieBuilder.Build(context)); - RedirectTo(uri); - } - private string CurrentPath => navigationManager.ToAbsoluteUri(navigationManager.Uri).GetLeftPart(UriPartial.Path); public void RedirectToCurrentPage() => RedirectTo(CurrentPath); - - public void RedirectToCurrentPageWithStatus(string message, HttpContext context) - => RedirectToWithStatus(CurrentPath, message, context); - - public void RedirectToInvalidUser(UserManager userManager, HttpContext context) - => RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context); } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor index 3a76b7261564..6b9052849d68 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ConfirmEmailChange.razor @@ -21,6 +21,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromQuery] private string? UserId { get; set; } @@ -32,17 +35,20 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + if (UserId is null || Email is null || Code is null) { - RedirectManager.RedirectToWithStatus( - "Account/Login", "Error: Invalid email change confirmation link.", HttpContext); + IdentityStatusMessage = "Error: Invalid email change confirmation link."; + RedirectManager.RedirectTo("Account/Login"); return; } var user = await UserManager.FindByIdAsync(UserId); if (user is null) { - message = "Unable to find user with Id '{userId}'"; + message = $"Error: Unable to find user with Id '{UserId}'"; return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor index 0c30821599fa..a8a386f32a4a 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/ExternalLogin.razor @@ -23,7 +23,7 @@

Associate your @ProviderDisplayName account.


-
+
You've successfully authenticated with @ProviderDisplayName. Please enter an email address for this site below and click the Register button to finish logging in. @@ -53,6 +53,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -69,18 +72,22 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); if (RemoteError is not null) { - RedirectManager.RedirectToWithStatus("Account/Login", $"Error from external provider: {RemoteError}", HttpContext); + IdentityStatusMessage = $"Error from external provider: {RemoteError}"; + RedirectManager.RedirectTo("Account/Login"); return; } var info = await SignInManager.GetExternalLoginInfoAsync(); if (info is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); + IdentityStatusMessage = "Error loading external login information."; + RedirectManager.RedirectTo("Account/Login"); return; } @@ -104,7 +111,8 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); + IdentityStatusMessage = "Error loading external login information."; + RedirectManager.RedirectTo("Account/Login"); return; } @@ -141,7 +149,8 @@ { if (externalLoginInfo is null) { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", HttpContext); + IdentityStatusMessage = "Error loading external login information during confirmation."; + RedirectManager.RedirectTo("Account/Login"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor index e61fe5def569..f67f733baba2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/InvalidUser.razor @@ -1,7 +1,23 @@ @page "/Account/InvalidUser" +@using Microsoft.AspNetCore.Identity +@using BlazorWebCSharp._1.Data +@inject UserManager UserManager + Invalid user

Invalid user

- + + +@code { + private string? message; + + [CascadingParameter] + private HttpContext HttpContext { get; set; } = default!; + + protected override void OnInitialized() + { + message = $"Error: Unable to load user with ID '{UserManager.GetUserId(HttpContext.User)}'."; + } +} diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor index 65157408b009..286969a93179 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Login.razor @@ -82,6 +82,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; @@ -90,6 +93,8 @@ protected override async Task OnInitializedAsync() { + errorMessage = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); editContext = new EditContext(Input); diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor index 0a47876de2ba..4197acb78ff2 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ChangePassword.razor @@ -52,17 +52,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -77,7 +82,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -91,7 +96,8 @@ await SignInManager.RefreshSignInAsync(user); Logger.LogInformation("User changed their password successfully."); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", HttpContext); + IdentityStatusMessage = "Your password has been changed"; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor index f9c247897223..bbece664423e 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/DeletePersonalData.razor @@ -45,17 +45,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } requirePassword = await UserManager.HasPasswordAsync(user); @@ -65,7 +70,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor index 8a6921b2ae5b..3a6d501b7d70 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Disable2fa.razor @@ -9,7 +9,7 @@ Disable two-factor authentication (2FA) - +

Disable two-factor authentication (2FA)

@code { + private string? message; private ApplicationUser? user; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -54,7 +61,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -66,9 +73,7 @@ var userId = await UserManager.GetUserIdAsync(user); Logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", userId); - RedirectManager.RedirectToWithStatus( - "Account/Manage/TwoFactorAuthentication", - "2fa has been disabled. You can reenable 2fa when you setup an authenticator app", - HttpContext); + IdentityStatusMessage = "2fa has been disabled. You can reenable 2fa when you setup an authenticator app"; + RedirectManager.RedirectTo("Account/Manage/TwoFactorAuthentication"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor index a2ca61841b0b..3e46514e0c3f 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Email.razor @@ -64,17 +64,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm(FormName = "change-email")] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -94,7 +99,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -119,7 +124,7 @@ if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor index 588134b5fa5a..002202c690f8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/EnableAuthenticator.razor @@ -77,17 +77,22 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -98,7 +103,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -126,7 +131,8 @@ else } else { - RedirectManager.RedirectToWithStatus("Account/Manage/TwoFactorAuthentication", message, HttpContext); + IdentityStatusMessage = message; + RedirectManager.RedirectTo("Account/Manage/TwoFactorAuthentication"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor index 4c2582dcae89..1e14a8d3b604 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ExternalLogins.razor @@ -11,7 +11,7 @@ Manage your external logins - + @if (currentLogins?.Count > 0) {

Registered Logins

@@ -65,6 +65,7 @@ @code { public const string LinkLoginCallbackAction = "LinkLoginCallback"; + private string? message; private ApplicationUser? user; private IList? currentLogins; private IList? otherLogins; @@ -73,6 +74,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private string? LoginProvider { get; set; } @@ -84,10 +88,13 @@ protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -114,19 +121,21 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", HttpContext); + IdentityStatusMessage = "Error: The external login was not removed."; + RedirectManager.RedirectToCurrentPage(); } else { await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", HttpContext); + IdentityStatusMessage = "The external login was removed."; + RedirectManager.RedirectToCurrentPage(); } } @@ -134,7 +143,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -142,7 +151,8 @@ var info = await SignInManager.GetExternalLoginInfoAsync(userId); if (info is null) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext); + IdentityStatusMessage = "Error: Could not load external login info."; + RedirectManager.RedirectToCurrentPage(); return; } @@ -152,11 +162,13 @@ // Clear the existing external cookie to ensure a clean login process await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", HttpContext); + IdentityStatusMessage = "The external login was added."; + RedirectManager.RedirectToCurrentPage(); } else { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", HttpContext); + IdentityStatusMessage = "Error: The external login was not added. External logins can only be associated with one account."; + RedirectManager.RedirectToCurrentPage(); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor index 7ef969efb286..6caf5d210e61 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor @@ -45,12 +45,18 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -65,7 +71,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor index 13faf41804f2..f0f2b9ce26e3 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Index.razor @@ -11,7 +11,7 @@ Profile

Profile

- +
@@ -33,6 +33,7 @@
@code { + private string? message; private ApplicationUser? user; private string? username; private string? phoneNumber; @@ -40,17 +41,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -64,7 +70,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -73,13 +79,15 @@ var setPhoneResult = await UserManager.SetPhoneNumberAsync(user, Input.PhoneNumber); if (!setPhoneResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Failed to set phone number.", HttpContext); + IdentityStatusMessage = "Error: Failed to set phone number."; + RedirectManager.RedirectToCurrentPage(); return; } } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your profile has been updated", HttpContext); + IdentityStatusMessage = "Your profile has been updated"; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor index 1536f17305be..35198ee58d52 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/Passkeys.razor @@ -13,7 +13,7 @@

Manage your passkeys

- + @if (currentPasskeys is { Count: > 0 }) { @@ -65,12 +65,16 @@ else @code { private const int MaxPasskeyCount = 100; + private string? message; private ApplicationUser? user; private IList? currentPasskeys; [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private string? Action { get; set; } @@ -82,12 +86,14 @@ else protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } currentPasskeys = await UserManager.GetPasskeysAsync(user); @@ -97,32 +103,36 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } if (!string.IsNullOrEmpty(Input.Error)) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: {Input.Error}", HttpContext); + IdentityStatusMessage = $"Error: {Input.Error}"; + RedirectManager.RedirectToCurrentPage(); return; } if (string.IsNullOrEmpty(Input.CredentialJson)) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The browser did not provide a passkey.", HttpContext); + IdentityStatusMessage = "Error: The browser did not provide a passkey."; + RedirectManager.RedirectToCurrentPage(); return; } if (currentPasskeys!.Count >= MaxPasskeyCount) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: You have reached the maximum number of allowed passkeys.", HttpContext); + IdentityStatusMessage = "Error: You have reached the maximum number of allowed passkeys."; + RedirectManager.RedirectToCurrentPage(); return; } var attestationResult = await SignInManager.PerformPasskeyAttestationAsync(Input.CredentialJson); if (!attestationResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Could not add the passkey: {attestationResult.Failure.Message}", HttpContext); + IdentityStatusMessage = $"Error: Could not add the passkey: {attestationResult.Failure.Message}"; + RedirectManager.RedirectToCurrentPage(); return; } @@ -135,14 +145,16 @@ else var addPasskeyResult = await UserManager.AddOrUpdatePasskeyAsync(user, attestationResult.Passkey); if (!addPasskeyResult.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be added to your account.", HttpContext); + IdentityStatusMessage = "Error: The passkey could not be added to your account."; + RedirectManager.RedirectToCurrentPage(); return; } // If a name was inferred, go back to the passkeys list if (!string.IsNullOrEmpty(attestationResult.Passkey.Name)) { - RedirectManager.RedirectToCurrentPageWithStatus("Your passkey was added successfully.", HttpContext); + IdentityStatusMessage = "Your passkey was added successfully."; + RedirectManager.RedirectToCurrentPage(); return; } @@ -162,7 +174,8 @@ else await DeletePasskey(); break; default: - RedirectManager.RedirectToCurrentPageWithStatus($"Error: Unknown action '{Action}'.", HttpContext); + IdentityStatusMessage = $"Error: Unknown action '{Action}'."; + RedirectManager.RedirectToCurrentPage(); break; } } @@ -171,7 +184,7 @@ else { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -182,17 +195,20 @@ else } catch (FormatException) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The specified passkey ID had an invalid format.", HttpContext); + IdentityStatusMessage = "Error: The specified passkey ID had an invalid format."; + RedirectManager.RedirectToCurrentPage(); return; } var result = await UserManager.RemovePasskeyAsync(user, credentialId); if (!result.Succeeded) { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The passkey could not be deleted.", HttpContext); + IdentityStatusMessage = "Error: The passkey could not be deleted."; + RedirectManager.RedirectToCurrentPage(); return; } - RedirectManager.RedirectToCurrentPageWithStatus("Passkey deleted successfully.", HttpContext); + IdentityStatusMessage = "Passkey deleted successfully."; + RedirectManager.RedirectToCurrentPage(); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor index 214902bdbdec..65708ecd703c 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/PersonalData.razor @@ -8,7 +8,7 @@ Personal Data - +

Personal Data

@@ -28,15 +28,23 @@
@code { + private string? message; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + protected override async Task OnInitializedAsync() { - var user = await UserManager.GetUserAsync(HttpContext.User); + message = IdentityStatusMessage; + IdentityStatusMessage = null; + + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); } } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor index a28d1bb85a50..4b76ce786d29 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/RenamePasskey.razor @@ -37,6 +37,9 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [Parameter] public string? Id { get; set; } @@ -45,12 +48,13 @@ protected override async Task OnInitializedAsync() { + IdentityStatusMessage = null; Input ??= new(); user = (await UserManager.GetUserAsync(HttpContext.User))!; if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -61,14 +65,16 @@ } catch (FormatException) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey ID had an invalid format.", HttpContext); + IdentityStatusMessage = "Error: The specified passkey ID had an invalid format."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } passkey = await UserManager.GetPasskeyAsync(user, credentialId); if (passkey is null) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The specified passkey could not be found.", HttpContext); + IdentityStatusMessage = "Error: The specified passkey could not be found."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } } @@ -79,11 +85,13 @@ var result = await UserManager.AddOrUpdatePasskeyAsync(user!, passkey); if (!result.Succeeded) { - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Error: The passkey could not be updated.", HttpContext); + IdentityStatusMessage = "Error: The passkey could not be updated."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); return; } - RedirectManager.RedirectToWithStatus("Account/Manage/Passkeys", "Passkey updated successfully.", HttpContext); + IdentityStatusMessage = "Passkey updated successfully."; + RedirectManager.RedirectTo("Account/Manage/Passkeys"); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor index beb54b93a5f8..74542ddb37f8 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/ResetAuthenticator.razor @@ -10,7 +10,7 @@ Reset authenticator key - +

Reset authenticator key

@code { + private string? message; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + + protected override void OnInitialized() + { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + } + private async Task OnSubmitAsync() { var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -49,9 +60,7 @@ await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToWithStatus( - "Account/Manage/EnableAuthenticator", - "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.", - HttpContext); + IdentityStatusMessage = "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key."; + RedirectManager.RedirectTo("Account/Manage/EnableAuthenticator"); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor index 180b4d77a4cc..c5662be69af0 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/SetPassword.razor @@ -43,17 +43,22 @@ [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + [SupplyParameterFromForm] private InputModel Input { get; set; } = default!; protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; Input ??= new(); user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -68,7 +73,7 @@ { if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -80,7 +85,8 @@ } await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.", HttpContext); + IdentityStatusMessage = "Your password has been set."; + RedirectManager.RedirectToCurrentPage(); } private sealed class InputModel diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor index 6774ba789335..795d01d386cb 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Pages/Manage/TwoFactorAuthentication.razor @@ -10,7 +10,7 @@ Two-factor authentication (2FA) - +

Two-factor authentication (2FA)

@if (canTrack) { @@ -70,6 +70,7 @@ else } @code { + private string? message; private bool canTrack; private bool hasAuthenticator; private int recoveryCodesLeft; @@ -79,12 +80,18 @@ else [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; + [SupplyParameterFromTempData(Name = IdentityRedirectManager.StatusMessageKey)] + private string? IdentityStatusMessage { get; set; } + protected override async Task OnInitializedAsync() { + message = IdentityStatusMessage; + IdentityStatusMessage = null; + var user = await UserManager.GetUserAsync(HttpContext.User); if (user is null) { - RedirectManager.RedirectToInvalidUser(UserManager, HttpContext); + RedirectManager.RedirectTo("Account/InvalidUser"); return; } @@ -99,8 +106,7 @@ else { await SignInManager.ForgetTwoFactorClientAsync(); - RedirectManager.RedirectToCurrentPageWithStatus( - "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.", - HttpContext); + IdentityStatusMessage = "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code."; + RedirectManager.RedirectToCurrentPage(); } } diff --git a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor index 12cd544cfe77..8f2724a45f24 100644 --- a/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor +++ b/src/ProjectTemplates/Web.ProjectTemplates/content/BlazorWeb-CSharp/BlazorWebCSharp.1/Components/Account/Shared/StatusMessage.razor @@ -1,29 +1,12 @@ -@if (!string.IsNullOrEmpty(DisplayMessage)) +@if (!string.IsNullOrEmpty(Message)) { - var statusMessageClass = DisplayMessage.StartsWith("Error") ? "danger" : "success"; + var statusMessageClass = Message.StartsWith("Error") ? "danger" : "success"; } @code { - private string? messageFromCookie; - [Parameter] public string? Message { get; set; } - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - private string? DisplayMessage => Message ?? messageFromCookie; - - protected override void OnInitialized() - { - messageFromCookie = HttpContext.Request.Cookies[IdentityRedirectManager.StatusCookieName]; - - if (messageFromCookie is not null) - { - HttpContext.Response.Cookies.Delete(IdentityRedirectManager.StatusCookieName); - } - } }