Fixed login form, navigation
This commit is contained in:
		
							parent
							
								
									27aaee6293
								
							
						
					
					
						commit
						51766eca42
					
				
					 4 changed files with 175 additions and 182 deletions
				
			
		| 
						 | 
				
			
			@ -4,16 +4,16 @@
 | 
			
		|||
    ViewData["Title"] = "Authenticate";
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
<div class="row" style="display: flex; flex-direction: row;">
 | 
			
		||||
    <div class="col-md-4">
 | 
			
		||||
<div class="row">
 | 
			
		||||
    <div class="col-md-6 offset-md-3">
 | 
			
		||||
        <form method="post">
 | 
			
		||||
            <h4>Login</h4>
 | 
			
		||||
            <h4>Login or Register</h4>
 | 
			
		||||
            <hr />
 | 
			
		||||
            @if (Model.LoginErrorMessages != null && Model.LoginErrorMessages.Any())
 | 
			
		||||
            @if (Model.ErrorMessages != null && Model.ErrorMessages.Any())
 | 
			
		||||
            {
 | 
			
		||||
                <div asp-validation-summary="ModelOnly" class="text-danger" role="alert">
 | 
			
		||||
                <div class="text-danger" role="alert">
 | 
			
		||||
                    <ul>
 | 
			
		||||
                        @foreach (var error in Model.LoginErrorMessages)
 | 
			
		||||
                        @foreach (var error in Model.ErrorMessages)
 | 
			
		||||
                        {
 | 
			
		||||
                            <li>@error</li>
 | 
			
		||||
                        }
 | 
			
		||||
| 
						 | 
				
			
			@ -21,52 +21,23 @@
 | 
			
		|||
                </div>
 | 
			
		||||
            }
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input asp-for="LoginInput.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="username" />
 | 
			
		||||
                <label asp-for="LoginInput.Username">Username</label>
 | 
			
		||||
                <span asp-validation-for="LoginInput.Username" class="text-danger"></span>
 | 
			
		||||
                <input asp-for="Input.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="username" />
 | 
			
		||||
                <label asp-for="Input.Username">Username</label>
 | 
			
		||||
                <span asp-validation-for="Input.Username" class="text-danger"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input asp-for="LoginInput.Password" class="form-control" type="password" autocomplete="current-password" aria-required="true" placeholder="password" />
 | 
			
		||||
                <label asp-for="LoginInput.Password">Password</label>
 | 
			
		||||
                <span asp-validation-for="LoginInput.Password" class="text-danger"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
                <button type="submit" asp-page-handler="Login" class="w-100 btn btn-lg btn-secondary">Login</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col-md-4">
 | 
			
		||||
        <form method="post">
 | 
			
		||||
            <h4>Register</h4>
 | 
			
		||||
            <hr />
 | 
			
		||||
            @if (Model.RegisterErrorMessages != null && Model.RegisterErrorMessages.Any())
 | 
			
		||||
            {
 | 
			
		||||
                <div asp-validation-summary="ModelOnly" class="text-danger" role="alert">
 | 
			
		||||
                    <ul>
 | 
			
		||||
                        @foreach (var error in Model.RegisterErrorMessages)
 | 
			
		||||
                        {
 | 
			
		||||
                            <li>@error</li>
 | 
			
		||||
                        }
 | 
			
		||||
                    </ul>
 | 
			
		||||
                </div>
 | 
			
		||||
            }
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input asp-for="RegisterInput.Username" class="form-control" autocomplete="username" aria-required="true" placeholder="username" />
 | 
			
		||||
                <label asp-for="RegisterInput.Username">Username</label>
 | 
			
		||||
                <span asp-validation-for="RegisterInput.Username" class="text-danger"></span>
 | 
			
		||||
                <input asp-for="Input.Password" class="form-control" type="password" autocomplete="current-password" aria-required="true" placeholder="password" />
 | 
			
		||||
                <label asp-for="Input.Password">Password</label>
 | 
			
		||||
                <span asp-validation-for="Input.Password" class="text-danger"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input asp-for="RegisterInput.Email" class="form-control" autocomplete="email" placeholder="name@example.com" />
 | 
			
		||||
                <label asp-for="RegisterInput.Email">Email</label>
 | 
			
		||||
                <span asp-validation-for="RegisterInput.Email" class="text-danger"></span>
 | 
			
		||||
                <input asp-for="Input.Email" class="form-control" autocomplete="email" placeholder="name@example.com" id="Input_Email" />
 | 
			
		||||
                <label asp-for="Input.Email">Email (Optional for Login)</label>
 | 
			
		||||
                <span asp-validation-for="Input.Email" class="text-danger"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="form-floating mb-3">
 | 
			
		||||
                <input asp-for="RegisterInput.Password" class="form-control" type="password" autocomplete="current-password" aria-required="true" placeholder="password" />
 | 
			
		||||
                <label asp-for="RegisterInput.Password">Password</label>
 | 
			
		||||
                <span asp-validation-for="RegisterInput.Password" class="text-danger"></span>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
                <button type="submit" asp-page-handler="Register" class="w-100 btn btn-lg btn-primary">Login</button>
 | 
			
		||||
            <div class="d-grid gap-2 d-md-flex justify-content-md-between">
 | 
			
		||||
                <button type="submit" asp-page-handler="Login" class="btn btn-lg btn-secondary flex-grow-1 me-2" id="loginButton">Login</button>
 | 
			
		||||
                <button type="submit" asp-page-handler="Register" class="btn btn-lg btn-primary flex-grow-1 ms-2">Register</button>
 | 
			
		||||
            </div>
 | 
			
		||||
        </form>
 | 
			
		||||
    </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -76,14 +47,20 @@
 | 
			
		|||
    <partial name="_ValidationScriptsPartial" />
 | 
			
		||||
    <script>
 | 
			
		||||
        $(document).ready(function() {
 | 
			
		||||
            // when login button is clicked, remove validation from email field
 | 
			
		||||
            $("button[asp-page-handler='Login']").click(function() {
 | 
			
		||||
                $("#Input_Email").removeAttr("data-val");
 | 
			
		||||
                $("#Input_Email").removeAttr("data-val-required");
 | 
			
		||||
                // revalidate the form to clear error
 | 
			
		||||
                $("form").validate().element("#Input_Email");
 | 
			
		||||
                return true;
 | 
			
		||||
            // When the login button is clicked
 | 
			
		||||
            $("#loginButton").click(function() {
 | 
			
		||||
                var emailInput = $("#Input_Email");
 | 
			
		||||
                var form = $("#authForm");
 | 
			
		||||
 | 
			
		||||
                // Remove the data-val-required attribute for client-side validation
 | 
			
		||||
                emailInput.removeAttr("data-val-required");
 | 
			
		||||
 | 
			
		||||
                // If jQuery Validate has already initialized the form,
 | 
			
		||||
                // re-parse the validation for the email field to reflect the change.
 | 
			
		||||
                if (form.data('validator')) {
 | 
			
		||||
                    form.validate().element(emailInput);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        });
 | 
			
		||||
    </script>
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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<string> ErrorMessages { get; set; } = [];
 | 
			
		||||
 | 
			
		||||
    public List<string> LoginErrorMessages { get; set; } = [];
 | 
			
		||||
    public List<string> 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<IActionResult> 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<IActionResult> OnPostLogoutAsync()
 | 
			
		||||
  {
 | 
			
		||||
    await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
 | 
			
		||||
    return RedirectToPage("/Index"); // Redirect to home page after logout
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<Claim>
 | 
			
		||||
      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<Claim>
 | 
			
		||||
        {
 | 
			
		||||
            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");
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    return user.Role.Name switch
 | 
			
		||||
    {
 | 
			
		||||
      "Admin" => RedirectToPage("/Admin"),
 | 
			
		||||
      "User" => RedirectToPage("/User"),
 | 
			
		||||
      _ => RedirectToPage("/Index"),
 | 
			
		||||
    };
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,9 +19,32 @@
 | 
			
		|||
                </button>
 | 
			
		||||
                <div class="navbar-collapse collapse d-sm-inline-flex justify-content-between">
 | 
			
		||||
                    <ul class="navbar-nav flex-grow-1">
 | 
			
		||||
                        <li class="nav-item">
 | 
			
		||||
                            <a class="nav-link text-dark" asp-area="" asp-page="/Auth">Login/Register</a>
 | 
			
		||||
                        </li>
 | 
			
		||||
                        @if (User.Identity.IsAuthenticated)
 | 
			
		||||
                        {
 | 
			
		||||
                            if (User.IsInRole("Admin"))
 | 
			
		||||
                            {
 | 
			
		||||
                                <li class="nav-item">
 | 
			
		||||
                                    <a class="nav-link text-dark" asp-area="" asp-page="/Admin">[Admin Page]</a>
 | 
			
		||||
                                </li>
 | 
			
		||||
                            }
 | 
			
		||||
                            if (User.IsInRole("User") || User.IsInRole("Admin"))
 | 
			
		||||
                            {
 | 
			
		||||
                                <li class="nav-item">
 | 
			
		||||
                                    <a class="nav-link text-dark" asp-area="" asp-page="/User">[User Profile]</a>
 | 
			
		||||
                                </li>
 | 
			
		||||
                            }
 | 
			
		||||
                            <li class="nav-item">
 | 
			
		||||
                                <form class="form-inline" asp-page="/Auth" asp-page-handler="Logout" method="post">
 | 
			
		||||
                                    <button type="submit" class="nav-link btn btn-link text-dark">[Logout]</button>
 | 
			
		||||
                                </form>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        }
 | 
			
		||||
                        else
 | 
			
		||||
                        {
 | 
			
		||||
                            <li class="nav-item">
 | 
			
		||||
                                <a class="nav-link text-dark" asp-area="" asp-page="/Auth">[Login or Register]</a>
 | 
			
		||||
                            </li>
 | 
			
		||||
                        }
 | 
			
		||||
                    </ul>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -45,4 +68,4 @@
 | 
			
		|||
 | 
			
		||||
    @await RenderSectionAsync("Scripts", required: false)
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
</html>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue