Add authentication and authorization (#21)

Reviewed-on: #21
This commit was merged in pull request #21.
This commit is contained in:
2025-04-21 01:53:58 +02:00
parent 51dab81121
commit 033747899b
55 changed files with 2186 additions and 317 deletions

View File

@@ -1,49 +0,0 @@
@using GameIdeas.Resources
@using Blazored.FluentValidation;
<div class="account-setting-container" tabindex="1000">
<div class="account-setting-content @(ContentVisile ? string.Empty : "invisible")">
@if (!IsLogin)
{
<EditForm EditContext="EditContext" OnSubmit="HandleLoginSubmit">
<FluentValidationValidator />
<div class="login-form">
<div class="login-field">
<div class="input-title">@ResourcesKey.EnterUsername</div>
<InputText class="input-text"
@bind-Value="LoginDto.Username" />
</div>
<div class="login-field">
<div class="input-title">@ResourcesKey.EnterPassword</div>
<InputText class="input-text"
@bind-Value="LoginDto.Password" />
</div>
<div class="login-field">
<button class="login-button" type="submit" disabled="@IsLoading">
@if (IsLoading)
{
<div class="loading"></div>
}
else
{
@ResourcesKey.Login
}
</button>
</div>
</div>
</EditForm>
}
else
{
<div class="settings-list">
<div class="settings-element">
@ResourcesKey.UserManager
</div>
<span class="line"></span>
<div class="settings-element" @onclick="HandleLogoutClicked">
@ResourcesKey.Logout
</div>
</div>
}
</div>
</div>

View File

@@ -1,47 +0,0 @@
using GameIdeas.Shared.Dto;
using Microsoft.AspNetCore.Components.Forms;
namespace GameIdeas.BlazorApp.Shared.Components.Account;
public partial class AccountSettings
{
private bool ContentVisile = false;
private EditContext? EditContext;
private LoginDto LoginDto = new();
private bool IsLoading = false;
private bool IsLogin = true;
protected override void OnInitialized()
{
EditContext = new EditContext(LoginDto);
}
public void Close()
{
ContentVisile = false;
StateHasChanged();
}
public void Toggle()
{
ContentVisile = !ContentVisile;
StateHasChanged();
}
private async Task HandleLoginSubmit()
{
if (EditContext?.Validate() == false)
{
return;
}
IsLoading = true;
await Task.Delay(TimeSpan.FromSeconds(5));
Close();
IsLoading = false;
}
private void HandleLogoutClicked()
{
Close();
}
}

View File

@@ -1,95 +0,0 @@
.account-setting-content {
overflow: hidden;
border-radius: var(--big-radius);
position: fixed;
animation-name: fade-in;
animation-duration: 0.4s;
border: 2px solid var(--input-selected);
background: var(--dropdown-content);
right: 10px;
margin-top: 4px;
z-index: var(--index-floating);
}
.invisible {
display: none;
}
.login-form {
display: flex;
flex-direction: column;
padding: 20px 8px;
gap: 20px;
max-width: 400px;
}
.login-field {
display: flex;
flex-direction: column;
width: 100%;
height: fit-content;
}
::deep .input-text {
background: var(--input-selected);
border: 2px solid var(--input-selected);
border-radius: var(--small-radius);
padding: 6px;
color: var(--white);
}
::deep .input-text:focus-visible {
border: 2px solid var(--violet) !important;
}
.login-button {
background: var(--violet);
border: none;
border-radius: 100px;
height: 32px;
color: var(--white);
font-weight: bold;
}
.login-button:hover {
background: var(--violet-selected);
cursor:pointer;
}
.login-button:disabled {
background: var(--violet-selected);
cursor: wait;
}
.loading {
width: 18px;
height: 18px;
border-radius: 50%;
border: 3px solid rgba(0, 0, 0, 0.2);
border-top-color: var(--white);
animation: loading 1s linear infinite;
justify-self: center;
}
.settings-list {
display: flex;
flex-direction: column;
}
.line {
margin: 0 6px;
border-bottom: 2px solid var(--line);
}
.settings-element {
max-width: 140px;
height: 40px;
padding: 0 26px;
align-content: center;
}
.settings-element:hover {
background: var(--line)
}

View File

@@ -1,18 +0,0 @@
using FluentValidation;
using GameIdeas.Shared.Dto;
namespace GameIdeas.BlazorApp.Shared.Components.Account;
public class LoginValidator : AbstractValidator<LoginDto>
{
public LoginValidator()
{
RuleFor(dto => dto.Username)
.NotNull()
.NotEmpty();
RuleFor(dto => dto.Password)
.NotNull()
.NotEmpty();
}
}

View File

@@ -15,4 +15,9 @@ public static class Endpoints
{
public static readonly string AllCategories = "api/Category/All";
}
public static class Auth
{
public static readonly string Login = "api/User/Login";
}
}

View File

@@ -23,4 +23,8 @@ public static class Icons
public readonly static MarkupString Game = new(OpenBraket +
"<path d=\"M6,7H18A5,5 0 0,1 23,12A5,5 0 0,1 18,17C16.36,17 14.91,16.21 14,15H10C9.09,16.21 7.64,17 6,17A5,5 0 0,1 1,12A5,5 0 0,1 6,7M19.75,9.5A1.25,1.25 0 0,0 18.5,10.75A1.25,1.25 0 0,0 19.75,12A1.25,1.25 0 0,0 21,10.75A1.25,1.25 0 0,0 19.75,9.5M17.25,12A1.25,1.25 0 0,0 16,13.25A1.25,1.25 0 0,0 17.25,14.5A1.25,1.25 0 0,0 18.5,13.25A1.25,1.25 0 0,0 17.25,12M5,9V11H3V13H5V15H7V13H9V11H7V9H5Z\">" +
CloseBraket);
public readonly static MarkupString Account = new(OpenBraket +
"<path d=\"M12,19.2C9.5,19.2 7.29,17.92 6,16C6.03,14 10,12.9 12,12.9C14,12.9 17.97,14 18,16C16.71,17.92 14.5,19.2 12,19.2M12,5A3,3 0 0,1 15,8A3,3 0 0,1 12,11A3,3 0 0,1 9,8A3,3 0 0,1 12,5M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12C22,6.47 17.5,2 12,2Z\" />" +
CloseBraket);
}

View File

@@ -0,0 +1,3 @@
namespace GameIdeas.BlazorApp.Shared.Exceptions;
public class AuthenticationUserException(string message) : Exception(message);