Refactor. Add data layer
This commit is contained in:
1 parent
3b7e4e6ec5
commit
b6b794f0b4
82 files changed
+2930
-2811
No files matched your search
@@ -1,5 +1,6 @@
|
||||
@page "/login"
|
||||
@layout AuthLayout
|
||||
@using BudgetApp.Data.Entities
|
||||
@using Microsoft.AspNetCore.Authentication
|
||||
@using Microsoft.AspNetCore.Identity
|
||||
@inject SignInManager<ApplicationUser> SignInManager
|
||||
@@ -17,9 +18,9 @@
|
||||
<EditForm Model="Model" OnValidSubmit="HandleLogin" FormName="login">
|
||||
<DataAnnotationsValidator />
|
||||
|
||||
@if (!string.IsNullOrEmpty(errorMessage))
|
||||
@if (!string.IsNullOrEmpty(_errorMessage))
|
||||
{
|
||||
<div class="alert alert-danger">@errorMessage</div>
|
||||
<div class="alert alert-danger">@_errorMessage</div>
|
||||
}
|
||||
|
||||
<div class="mb-3">
|
||||
@@ -37,17 +38,17 @@
|
||||
<button type="submit" class="btn btn-primary w-100">Sign In</button>
|
||||
</EditForm>
|
||||
|
||||
@if (externalProviders.Count > 0)
|
||||
@if (_externalProviders.Count > 0)
|
||||
{
|
||||
<hr class="my-4" />
|
||||
<p class="text-center text-muted mb-3">Or sign in with</p>
|
||||
<div class="d-flex flex-column gap-2">
|
||||
@foreach (var provider in externalProviders)
|
||||
@foreach (var provider in _externalProviders)
|
||||
{
|
||||
<form method="post" action="/api/auth/external-login">
|
||||
<input type="hidden" name="provider" value="@provider.Name" />
|
||||
<input type="hidden" name="returnUrl" value="/" />
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@antiforgeryToken" />
|
||||
<input type="hidden" name="__RequestVerificationToken" value="@_antiforgeryToken" />
|
||||
<button type="submit" class="btn btn-outline-secondary w-100 d-flex align-items-center justify-content-center gap-2">
|
||||
@GetProviderIcon(provider.DisplayName ?? provider.Name)
|
||||
<span>@(provider.DisplayName ?? provider.Name)</span>
|
||||
@@ -59,71 +60,4 @@
|
||||
|
||||
<p class="text-center mt-3">
|
||||
Don't have an account? <a href="/register">Register</a>
|
||||
</p>
|
||||
|
||||
@code {
|
||||
[SupplyParameterFromForm]
|
||||
private LoginModel Model { get; set; } = new();
|
||||
|
||||
private string? errorMessage;
|
||||
private List<AuthenticationScheme> externalProviders = [];
|
||||
private string antiforgeryToken = string.Empty;
|
||||
|
||||
[CascadingParameter]
|
||||
private HttpContext? HttpContext { get; set; }
|
||||
|
||||
protected override async Task OnInitializedAsync()
|
||||
{
|
||||
var schemes = await SchemeProvider.GetAllSchemesAsync();
|
||||
externalProviders = schemes
|
||||
.Where(s => !string.IsNullOrEmpty(s.DisplayName)
|
||||
&& s.Name != IdentityConstants.ApplicationScheme
|
||||
&& s.Name != IdentityConstants.ExternalScheme
|
||||
&& s.Name != IdentityConstants.TwoFactorUserIdScheme
|
||||
&& s.Name != IdentityConstants.TwoFactorRememberMeScheme)
|
||||
.ToList();
|
||||
|
||||
if (HttpContext is not null)
|
||||
{
|
||||
var tokens = HttpContext.RequestServices
|
||||
.GetRequiredService<Microsoft.AspNetCore.Antiforgery.IAntiforgery>()
|
||||
.GetAndStoreTokens(HttpContext);
|
||||
antiforgeryToken = tokens.RequestToken ?? string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleLogin()
|
||||
{
|
||||
errorMessage = null;
|
||||
|
||||
var result = await SignInManager.PasswordSignInAsync(
|
||||
Model.Email, Model.Password, isPersistent: false, lockoutOnFailure: false);
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
Navigation.NavigateTo("/", forceLoad: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
errorMessage = "Invalid email or password.";
|
||||
}
|
||||
}
|
||||
|
||||
private static MarkupString GetProviderIcon(string provider) => provider switch
|
||||
{
|
||||
"Google" => new MarkupString("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\"><path fill=\"#4285F4\" d=\"M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.27-4.74 3.27-8.1z\"/><path fill=\"#34A853\" d=\"M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z\"/><path fill=\"#FBBC05\" d=\"M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z\"/><path fill=\"#EA4335\" d=\"M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z\"/></svg>"),
|
||||
"Microsoft" => new MarkupString("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 23 23\"><rect fill=\"#f25022\" x=\"1\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#00a4ef\" x=\"1\" y=\"12\" width=\"10\" height=\"10\"/><rect fill=\"#7fba00\" x=\"12\" y=\"1\" width=\"10\" height=\"10\"/><rect fill=\"#ffb900\" x=\"12\" y=\"12\" width=\"10\" height=\"10\"/></svg>"),
|
||||
"Facebook" => new MarkupString("<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"18\" height=\"18\" viewBox=\"0 0 24 24\"><path fill=\"#1877F2\" d=\"M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047V9.413c0-3.007 1.792-4.669 4.533-4.669 1.312 0 2.686.235 2.686.235v2.953H15.83c-1.491 0-1.956.925-1.956 1.874v2.25h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z\"/></svg>"),
|
||||
_ => new MarkupString("")
|
||||
};
|
||||
|
||||
private sealed class LoginModel
|
||||
{
|
||||
[System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Email is required")]
|
||||
[System.ComponentModel.DataAnnotations.EmailAddress]
|
||||
public string Email { get; set; } = string.Empty;
|
||||
|
||||
[System.ComponentModel.DataAnnotations.Required(ErrorMessage = "Password is required")]
|
||||
public string Password { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
</p>
|
||||
Reference in new issue
Block a user