From 51766eca42ccc54f1a7242607fc58967e378df38 Mon Sep 17 00:00:00 2001 From: danial23 Date: Tue, 20 May 2025 11:26:05 -0400 Subject: [PATCH] Fixed login form, navigation --- CSR.WebUI/Pages/Auth.cshtml | 87 ++++----- CSR.WebUI/Pages/Auth.cshtml.cs | 237 ++++++++++++------------- CSR.WebUI/Pages/Shared/_Layout.cshtml | 31 +++- CSR.WebUI/appsettings.Development.json | 2 +- 4 files changed, 175 insertions(+), 182 deletions(-) diff --git a/CSR.WebUI/Pages/Auth.cshtml b/CSR.WebUI/Pages/Auth.cshtml index a15fc3d..4f22a88 100644 --- a/CSR.WebUI/Pages/Auth.cshtml +++ b/CSR.WebUI/Pages/Auth.cshtml @@ -4,16 +4,16 @@ ViewData["Title"] = "Authenticate"; } -
-
+
+
-

Login

+

Login or Register


- @if (Model.LoginErrorMessages != null && Model.LoginErrorMessages.Any()) + @if (Model.ErrorMessages != null && Model.ErrorMessages.Any()) { -
-
-
-

Register

-
- @if (Model.RegisterErrorMessages != null && Model.RegisterErrorMessages.Any()) - { - - } -
- - - + + +
- - - + + +
-
- - - -
-
- +
+ +
@@ -76,14 +47,20 @@ -} \ No newline at end of file +} diff --git a/CSR.WebUI/Pages/Auth.cshtml.cs b/CSR.WebUI/Pages/Auth.cshtml.cs index 4010308..a00d32e 100644 --- a/CSR.WebUI/Pages/Auth.cshtml.cs +++ b/CSR.WebUI/Pages/Auth.cshtml.cs @@ -7,160 +7,153 @@ using System.Threading.Tasks; using CSR.Application.Interfaces; using CSR.Domain.Entities; using System.Collections.Generic; -using System.Linq; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using System.Security.Claims; -using System.Runtime.InteropServices; - -// If you are using ASP.NET Core Identity for sign-in management, you might need: -// using Microsoft.AspNetCore.Identity; -// using System.Security.Claims; public class AuthModel(IUserService userService) : PageModel { - private readonly IUserService _userService = userService; + private readonly IUserService _userService = userService; - [BindProperty] - public LoginModel LoginInput { get; set; } = new(); + [BindProperty] + public InputModel Input { get; set; } = new(); - [BindProperty] - public RegisterModel RegisterInput { get; set; } = new(); + public List ErrorMessages { get; set; } = []; - public List LoginErrorMessages { get; set; } = []; - public List RegisterErrorMessages { get; set; } = []; + public class InputModel + { + [Required(ErrorMessage = "Username is required.")] + [Display(Name = "Username")] + [StringLength(32, ErrorMessage = "Username cannot be longer than 32 characters.")] + [RegularExpression(@"^[a-zA-Z0-9_]+$", ErrorMessage = "Username can only contain letters, numbers and underscore.")] + public string Username { get; set; } = string.Empty; - public class LoginModel + [EmailAddress] + [Display(Name = "Email")] + public string? Email { get; set; } = string.Empty; + + [Required(ErrorMessage = "Password is required.")] + [DataType(DataType.Password)] + [Display(Name = "Password")] + public string Password { get; set; } = string.Empty; + } + + public void OnGet() + { + ErrorMessages.Clear(); + } + + public async Task OnPostLoginAsync() + { + // Clear any previous registration errors + ModelState.Remove("Input.Email"); + + if (!ModelState.IsValid) { - [Required(ErrorMessage = "Username is required.")] - [Display(Name = "Username")] - public string Username { get; set; } = string.Empty; - - [Required] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } = string.Empty; + foreach (var modelState in ModelState.Values) + { + foreach (var e in modelState.Errors) + { + ErrorMessages.Add(e.ErrorMessage); + } + } + return Page(); } - public class RegisterModel + var (user, error) = await _userService.Login(Input.Username, Input.Password); + + if (user == null) { - [Required(ErrorMessage = "Username is required.")] - [Display(Name = "Username")] - [StringLength(32, ErrorMessage = "Username cannot be longer than 32 characters.")] - [RegularExpression(@"^[a-zA-Z0-9_]+$", ErrorMessage = "Username can only contain letters, numbers and underscore.")] - [DataType(DataType.Text)] - public string Username { get; set; } = string.Empty; - - [Required(ErrorMessage = "Email is required for registration.")] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } = string.Empty; - - [Required] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } = string.Empty; + ErrorMessages.Add(error ?? "Login failed."); + Console.WriteLine(error); + return Page(); } - public void OnGet() + await SendCookies(user.Username, user.Role.Name); + + return RedirectToPageBasedOnRole(user); + } + + public async Task OnPostLogoutAsync() + { + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + return RedirectToPage("/Index"); // Redirect to home page after logout + } + + public async Task OnPostRegisterAsync() + { + // Email is required for registration, so add a validation error if it's missing + if (string.IsNullOrWhiteSpace(Input.Email)) { + ModelState.AddModelError("Input.Email", "Email is required for registration."); } - public async Task OnPostRegisterAsync() + if (!ModelState.IsValid) { - if (!ModelState.IsValid) + foreach (var modelState in ModelState.Values) + { + foreach (var error in modelState.Errors) { - RegisterErrorMessages.Add("Please correct the form errors."); - return Page(); - } - - // Email is required for registration - if (string.IsNullOrWhiteSpace(RegisterInput.Email)) - { - RegisterErrorMessages.Add("Email is required for registration."); - return Page(); - } - - - var result = await _userService.RegisterNewUser(RegisterInput.Username, RegisterInput.Email, RegisterInput.Password); - - if (result.User != null) - { - // Registration successful - await _userService.Login(RegisterInput.Username, RegisterInput.Password); - - await SendCookies(result.User.Username, result.User.Role.Name); - - return RedirectToPageBasedOnRole(result.User); - } - else - { - if (result.Errors != null) - { - RegisterErrorMessages.AddRange(result.Errors); - } - else - { - RegisterErrorMessages.Add("An unknown error occurred during registration."); - } - return Page(); + ErrorMessages.Add(error.ErrorMessage); } + } + return Page(); } - public async Task OnPostLoginAsync() - { - if (string.IsNullOrWhiteSpace(LoginInput.Username) || string.IsNullOrWhiteSpace(LoginInput.Password)) - { - LoginErrorMessages.Add("Username and Password are required."); - return Page(); - } - - var (user, error) = await _userService.Login(LoginInput.Username, LoginInput.Password); - - if (user == null) - { - LoginErrorMessages.Add(error ?? "Login failed."); - return Page(); - } - - await SendCookies(user.Username, user.Role.Name); + var result = await _userService.RegisterNewUser(Input.Username, Input.Email!, Input.Password); - return RedirectToPageBasedOnRole(user); - } - - private async Task SendCookies(string username, string role) + if (result.User != null) { - var claims = new List + await _userService.Login(Input.Username, Input.Password); + await SendCookies(result.User.Username, result.User.Role.Name); + return RedirectToPageBasedOnRole(result.User); + } + else + { + if (result.Errors != null) + { + ErrorMessages.AddRange(result.Errors); + } + else + { + ErrorMessages.Add("An unknown error occurred during registration."); + } + return Page(); + } + } + + private async Task SendCookies(string username, string role) + { + var claims = new List { new(ClaimTypes.Name, username), new(ClaimTypes.Role, role) }; - var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); - var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); + var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); + var claimsPrincipal = new ClaimsPrincipal(claimsIdentity); - var authProperties = new AuthenticationProperties - { - IsPersistent = true, - ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(5) - }; - - await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal, authProperties); - } - - private RedirectToPageResult RedirectToPageBasedOnRole(User user) + var authProperties = new AuthenticationProperties { - if (user == null || string.IsNullOrWhiteSpace(user.Role.Name)) - { - // Default redirect if role is not defined or user is null - return RedirectToPage("/Index"); - } + IsPersistent = true, + ExpiresUtc = DateTimeOffset.UtcNow.AddMinutes(5) + }; - return user.Role.Name switch - { - "Admin" => RedirectToPage("/Admin"), - "User" => RedirectToPage("/User"), - _ => RedirectToPage("/Index"), - }; + await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, claimsPrincipal, authProperties); + } + + private RedirectToPageResult RedirectToPageBasedOnRole(User user) + { + if (user == null || string.IsNullOrWhiteSpace(user.Role.Name)) + { + return RedirectToPage("/Index"); } -} \ No newline at end of file + + return user.Role.Name switch + { + "Admin" => RedirectToPage("/Admin"), + "User" => RedirectToPage("/User"), + _ => RedirectToPage("/Index"), + }; + } +} diff --git a/CSR.WebUI/Pages/Shared/_Layout.cshtml b/CSR.WebUI/Pages/Shared/_Layout.cshtml index 1ed7a9a..62fa35f 100644 --- a/CSR.WebUI/Pages/Shared/_Layout.cshtml +++ b/CSR.WebUI/Pages/Shared/_Layout.cshtml @@ -19,9 +19,32 @@
@@ -45,4 +68,4 @@ @await RenderSectionAsync("Scripts", required: false) - \ No newline at end of file + diff --git a/CSR.WebUI/appsettings.Development.json b/CSR.WebUI/appsettings.Development.json index 76fc403..def7c8d 100644 --- a/CSR.WebUI/appsettings.Development.json +++ b/CSR.WebUI/appsettings.Development.json @@ -7,6 +7,6 @@ } }, "Database": { - "Path": "/home/danial23/Desktop/csr.db" + "Path": "/home/danial23/dl/csr.db" } }