Files
Aaru.Server/Aaru.Server/Components/Account/Pages/LoginWithRecoveryCode.razor

83 lines
3.0 KiB
Plaintext

@page "/Account/LoginWithRecoveryCode"
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject IdentityRedirectManager RedirectManager
@inject ILogger<LoginWithRecoveryCode> Logger
<PageTitle>Recovery code verification</PageTitle>
<h1>Recovery code verification</h1>
<hr/>
<StatusMessage Message="@message"/>
<p>
You have requested to log in with a recovery code. This login will not be remembered until you provide
an authenticator app code at log in or disable 2FA and log in again.
</p>
<div class="row">
<div class="col-md-4">
<EditForm FormName="login-with-recovery-code" method="post" Model="Input" OnValidSubmit="OnValidSubmitAsync">
<DataAnnotationsValidator/>
<ValidationSummary class="text-danger" role="alert"/>
<div class="form-floating mb-3">
<InputText autocomplete="off" @bind-Value="Input.RecoveryCode" class="form-control" placeholder="RecoveryCode"/>
<label class="form-label" for="recovery-code">Recovery Code</label>
<ValidationMessage class="text-danger" For="() => Input.RecoveryCode"/>
</div>
<button class="btn btn-lg btn-primary w-100" type="submit">Log in</button>
</EditForm>
</div>
</div>
@code {
private string? message;
private IdentityUser user = default!;
[SupplyParameterFromForm]
private InputModel Input { get; set; } = new();
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
protected override async Task OnInitializedAsync()
{
// Ensure the user has gone through the username & password screen first
user = await SignInManager.GetTwoFactorAuthenticationUserAsync() ?? throw new InvalidOperationException("Unable to load two-factor authentication user.");
}
private async Task OnValidSubmitAsync()
{
string recoveryCode = Input.RecoveryCode.Replace(" ", string.Empty);
SignInResult result = await SignInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode);
string userId = await UserManager.GetUserIdAsync(user);
if(result.Succeeded)
{
Logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", userId);
RedirectManager.RedirectTo(ReturnUrl);
}
else if(result.IsLockedOut)
{
Logger.LogWarning("User account locked out.");
RedirectManager.RedirectTo("Account/Lockout");
}
else
{
Logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", userId);
message = "Error: Invalid recovery code entered.";
}
}
private sealed class InputModel
{
[Required]
[DataType(DataType.Text)]
[Display(Name = "Recovery Code")]
public string RecoveryCode { get; set; } = "";
}
}