Skip to content
Original file line number Diff line number Diff line change
@@ -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)
{
Expand All @@ -36,19 +26,7 @@ public void RedirectTo(string uri, Dictionary<string, object?> 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<ApplicationUser> userManager, HttpContext context)
=> RedirectToWithStatus("Account/InvalidUser", $"Error: Unable to load user with ID '{userManager.GetUserId(context.User)}'.", context);
}
Comment thread
dariatiurina marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -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; }

Expand All @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<h2>Associate your @ProviderDisplayName account.</h2>
<hr />

<div class="alert alert-info">
<div class="alert alert-info">
You've successfully authenticated with <strong>@ProviderDisplayName</strong>.
Please enter an email address for this site below and click the Register button to finish
logging in.
Expand Down Expand Up @@ -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!;

Expand All @@ -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;
}

Expand All @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
@page "/Account/InvalidUser"

@using Microsoft.AspNetCore.Identity
Comment thread
dariatiurina marked this conversation as resolved.
@using BlazorWebCSharp._1.Data
@inject UserManager<ApplicationUser> UserManager

<PageTitle>Invalid user</PageTitle>

<h3>Invalid user</h3>

<StatusMessage />
<StatusMessage Message="@message" />

@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)}'.";
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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!;

Expand All @@ -90,6 +93,8 @@

protected override async Task OnInitializedAsync()
{
errorMessage = IdentityStatusMessage;
IdentityStatusMessage = null;
Input ??= new();

editContext = new EditContext(Input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -77,7 +82,7 @@
{
if (user is null)
{
RedirectManager.RedirectToInvalidUser(UserManager, HttpContext);
RedirectManager.RedirectTo("Account/InvalidUser");
return;
}

Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -65,7 +70,7 @@
{
if (user is null)
{
RedirectManager.RedirectToInvalidUser(UserManager, HttpContext);
RedirectManager.RedirectTo("Account/InvalidUser");
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

<PageTitle>Disable two-factor authentication (2FA)</PageTitle>

<StatusMessage />
<StatusMessage Message="@message" />
<h3>Disable two-factor authentication (2FA)</h3>

<div class="alert alert-warning" role="alert">
Expand All @@ -30,17 +30,24 @@
</div>

@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;
}

Expand All @@ -54,7 +61,7 @@
{
if (user is null)
{
RedirectManager.RedirectToInvalidUser(UserManager, HttpContext);
RedirectManager.RedirectTo("Account/InvalidUser");
return;
}

Expand All @@ -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");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -94,7 +99,7 @@

if (user is null)
{
RedirectManager.RedirectToInvalidUser(UserManager, HttpContext);
RedirectManager.RedirectTo("Account/InvalidUser");
return;
}

Expand All @@ -119,7 +124,7 @@

if (user is null)
{
RedirectManager.RedirectToInvalidUser(UserManager, HttpContext);
RedirectManager.RedirectTo("Account/InvalidUser");
return;
}

Expand Down
Loading
Loading