Files
Aaru.Server/Aaru.Server.New/Components/Account/Pages/Login.razor

131 lines
4.9 KiB
Plaintext

@page "/Account/Login"
@using System.ComponentModel.DataAnnotations
@using Microsoft.AspNetCore.Authentication
@using Microsoft.AspNetCore.Identity
@inject SignInManager<IdentityUser> SignInManager
@inject ILogger<Login> Logger
@inject NavigationManager NavigationManager
@inject IdentityRedirectManager RedirectManager
<PageTitle>Log in</PageTitle>
<h1>Log in</h1>
<div class="row">
<div class="col-md-4">
<section>
<StatusMessage Message="@errorMessage"/>
<EditForm FormName="login" method="post" Model="Input" OnValidSubmit="LoginUser">
<DataAnnotationsValidator/>
<h2>Use a local account to log in.</h2>
<hr/>
<ValidationSummary class="text-danger" role="alert"/>
<div class="form-floating mb-3">
<InputText aria-required="true" autocomplete="username" @bind-Value="Input.Email" class="form-control" placeholder="name@example.com"/>
<label class="form-label" for="email">Email</label>
<ValidationMessage class="text-danger" For="() => Input.Email"/>
</div>
<div class="form-floating mb-3">
<InputText aria-required="true" autocomplete="current-password" @bind-Value="Input.Password" class="form-control" placeholder="password" type="password"/>
<label class="form-label" for="password">Password</label>
<ValidationMessage class="text-danger" For="() => Input.Password"/>
</div>
<div class="checkbox mb-3">
<label class="form-label">
<InputCheckbox @bind-Value="Input.RememberMe" class="darker-border-checkbox form-check-input"/>
Remember me
</label>
</div>
<div>
<button class="btn btn-lg btn-primary w-100" type="submit">Log in</button>
</div>
<div>
<p>
<a href="Account/ForgotPassword">Forgot your password?</a>
</p>
<p>
<a href="@(NavigationManager.GetUriWithQueryParameters("Account/Register", new Dictionary<string, object?> { ["ReturnUrl"] = ReturnUrl }))">Register as a new user</a>
</p>
<p>
<a href="Account/ResendEmailConfirmation">Resend email confirmation</a>
</p>
</div>
</EditForm>
</section>
</div>
<div class="col-md-6 col-md-offset-2">
<section>
<h3>Use another service to log in.</h3>
<hr/>
<ExternalLoginPicker/>
</section>
</div>
</div>
@code {
private string? errorMessage;
[CascadingParameter]
private HttpContext HttpContext { get; set; } = default!;
[SupplyParameterFromForm]
private InputModel Input { get; set; } = new();
[SupplyParameterFromQuery]
private string? ReturnUrl { get; set; }
protected override async Task OnInitializedAsync()
{
if(HttpMethods.IsGet(HttpContext.Request.Method))
{
// Clear the existing external cookie to ensure a clean login process
await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme);
}
}
public async Task LoginUser()
{
// This doesn't count login failures towards account lockout
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
SignInResult result = await SignInManager.PasswordSignInAsync(Input.Email, Input.Password, Input.RememberMe, false);
if(result.Succeeded)
{
Logger.LogInformation("User logged in.");
RedirectManager.RedirectTo(ReturnUrl);
}
else if(result.RequiresTwoFactor)
{
RedirectManager.RedirectTo("Account/LoginWith2fa",
new Dictionary<string, object?>
{
["returnUrl"] = ReturnUrl,
["rememberMe"] = Input.RememberMe
});
}
else if(result.IsLockedOut)
{
Logger.LogWarning("User account locked out.");
RedirectManager.RedirectTo("Account/Lockout");
}
else
{
errorMessage = "Error: Invalid login attempt.";
}
}
private sealed class InputModel
{
[Required]
[EmailAddress]
public string Email { get; set; } = "";
[Required]
[DataType(DataType.Password)]
public string Password { get; set; } = "";
[Display(Name = "Remember me?")]
public bool RememberMe { get; set; }
}
}