Update route for proper routing
Docker Build and Release Upload / build (push) Has been cancelled

This commit is contained in:
2025-07-14 21:59:18 +00:00
parent b8634dbc87
commit 3b169f18d9
@@ -1,285 +1,285 @@
using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using System.Security.Claims; using System.Security.Claims;
using MistoxWebsite.Server.Services; using MistoxWebsite.Server.Services;
using MistoxWebsite.Server.Services.DatabaseService; using MistoxWebsite.Server.Services.DatabaseService;
using MistoxWebsite.Server.Entities; using MistoxWebsite.Server.Entities;
namespace MistoxWebsite.Server.Controllers { namespace MistoxWebsite.Server.Controllers {
[ApiController] [ApiController]
[Route("api/account/[controller]")] [Route("api/account/")]
public class AuthenticationController : MistoxControllerBase { public class AuthenticationController : MistoxControllerBase {
EmailService _emailContext; EmailService _emailContext;
public AuthenticationController(DatabaseService db, EmailService emailContext) : base(db) { public AuthenticationController(DatabaseService db, EmailService emailContext) : base(db) {
_emailContext = emailContext; _emailContext = emailContext;
} }
[Route("login")] [Route("login")]
[HttpPost] [HttpPost]
public async Task<ActionResult<Account>> Login([FromForm] string UserName, [FromForm] string PasswordHash, [FromForm] bool StayLoggedIn) { public async Task<ActionResult<Account>> Login([FromForm] string UserName, [FromForm] string PasswordHash, [FromForm] bool StayLoggedIn) {
try { try {
Account? test = await _databaseService.GetAccount(UserName.ToLower()); Account? test = await _databaseService.GetAccount(UserName.ToLower());
if (test != null) { if (test != null) {
if (test.EmailVerified == true) { if (test.EmailVerified == true) {
if (test.FailedPasswordLock) { if (test.FailedPasswordLock) {
if (test.CurrentPasswordAttempts >= test.PasswordAttempts) { if (test.CurrentPasswordAttempts >= test.PasswordAttempts) {
return new Account() { Error = "Too many failed password attempts. Please reset your password" }; return new Account() { Error = "Too many failed password attempts. Please reset your password" };
} }
} }
if (BCrypt.Net.BCrypt.Verify(PasswordHash, test.PasswordHash)) { if (BCrypt.Net.BCrypt.Verify(PasswordHash, test.PasswordHash)) {
test.CurrentPasswordAttempts = 0; test.CurrentPasswordAttempts = 0;
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
List<Claim> claims = new List<Claim>() { List<Claim> claims = new List<Claim>() {
new Claim("ID", test.ID.ToString()) new Claim("ID", test.ID.ToString())
}; };
await HttpContext.SignInAsync( await HttpContext.SignInAsync(
CookieAuthenticationDefaults.AuthenticationScheme, CookieAuthenticationDefaults.AuthenticationScheme,
new ClaimsPrincipal(new ClaimsIdentity(claims, "Auth")), new ClaimsPrincipal(new ClaimsIdentity(claims, "Auth")),
new AuthenticationProperties { new AuthenticationProperties {
ExpiresUtc = DateTime.UtcNow.AddYears(30), // Add 30 years with sliding on ExpiresUtc = DateTime.UtcNow.AddYears(30), // Add 30 years with sliding on
IsPersistent = StayLoggedIn, // Is set from the StayLoggedIn IsPersistent = StayLoggedIn, // Is set from the StayLoggedIn
} }
); );
return test; return test;
} }
else { else {
test.CurrentPasswordAttempts += 1; test.CurrentPasswordAttempts += 1;
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
return new Account() { Error = "Wrong password" }; return new Account() { Error = "Wrong password" };
} }
} }
else { else {
await SendVerify(test.UserName); await SendVerify(test.UserName);
return new Account() { Error = "A new verify email has been sent. \n Note only 1 email send every 5 mintes" }; return new Account() { Error = "A new verify email has been sent. \n Note only 1 email send every 5 mintes" };
} }
} }
return new Account() { Error = "User doesn't exist" }; return new Account() { Error = "User doesn't exist" };
} catch (Exception ex) { } catch (Exception ex) {
return new Account() { Error = ex.Message }; return new Account() { Error = ex.Message };
} }
} }
[Route("register")] [Route("register")]
[HttpPost] [HttpPost]
public async Task<ActionResult<Account>> Register([FromForm] string Email, [FromForm] string UserName, [FromForm] string PasswordHash) { public async Task<ActionResult<Account>> Register([FromForm] string Email, [FromForm] string UserName, [FromForm] string PasswordHash) {
try { try {
if (await _databaseService.GetAccount(UserName.ToLower()) == null) { if (await _databaseService.GetAccount(UserName.ToLower()) == null) {
if (await _databaseService.GetAccount(Email.ToLower()) == null) { if (await _databaseService.GetAccount(Email.ToLower()) == null) {
Account? created = new Account() { Account? created = new Account() {
UserName = UserName.ToLower(), UserName = UserName.ToLower(),
Email = Email.ToLower(), Email = Email.ToLower(),
EmailVerified = false, EmailVerified = false,
PasswordHash = BCrypt.Net.BCrypt.HashPassword(PasswordHash), PasswordHash = BCrypt.Net.BCrypt.HashPassword(PasswordHash),
}; };
await _databaseService.SetAccount(created); await _databaseService.SetAccount(created);
created = await _databaseService.GetAccount(Email.ToLower()); created = await _databaseService.GetAccount(Email.ToLower());
if (created != null) { if (created != null) {
await SendVerify(created.UserName); await SendVerify(created.UserName);
return created; return created;
} }
return new Account() { Error = "Unknown Error" }; return new Account() { Error = "Unknown Error" };
} }
else { else {
return new Account() { Error = "Email is already in use" }; return new Account() { Error = "Email is already in use" };
} }
} }
else { else {
return new Account() { Error = "UserName is taken" }; return new Account() { Error = "UserName is taken" };
} }
} catch (Exception ex) { } catch (Exception ex) {
Console.WriteLine("Error: " + ex.Message); Console.WriteLine("Error: " + ex.Message);
return new Account() { Error = ex.Message }; return new Account() { Error = ex.Message };
} }
} }
[Route("changepassword")] [Route("changepassword")]
[HttpPost] [HttpPost]
public async Task<ActionResult<bool>> ChangePassword([FromForm] string OldPassword, [FromForm] string NewPassword) { public async Task<ActionResult<bool>> ChangePassword([FromForm] string OldPassword, [FromForm] string NewPassword) {
try { try {
if (isLoggedIn()) { if (isLoggedIn()) {
Account user = await getLoggedInUser(); Account user = await getLoggedInUser();
if (BCrypt.Net.BCrypt.Verify(OldPassword, user.PasswordHash)) { if (BCrypt.Net.BCrypt.Verify(OldPassword, user.PasswordHash)) {
user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword); user.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
user.CurrentPasswordAttempts = 0; user.CurrentPasswordAttempts = 0;
await _databaseService.SetAccount(user); await _databaseService.SetAccount(user);
return true; return true;
} }
} }
return false; return false;
} catch { } catch {
return false; return false;
} }
} }
[Route("toggleaccountlock")] [Route("toggleaccountlock")]
[HttpPost] [HttpPost]
public async Task<ActionResult<string>> ToggleAccountLock([FromForm] bool AccountLock) { public async Task<ActionResult<string>> ToggleAccountLock([FromForm] bool AccountLock) {
try { try {
if (isLoggedIn()) { if (isLoggedIn()) {
Account user = await getLoggedInUser(); Account user = await getLoggedInUser();
user.FailedPasswordLock = AccountLock; user.FailedPasswordLock = AccountLock;
user.CurrentPasswordAttempts = 0; user.CurrentPasswordAttempts = 0;
await _databaseService.SetAccount(user); await _databaseService.SetAccount(user);
return "Account Lock Status Updated"; return "Account Lock Status Updated";
} }
return "Unknown Error Occurred"; return "Unknown Error Occurred";
} catch (Exception ex) { } catch (Exception ex) {
return ex.Message; return ex.Message;
} }
} }
[Route("get")] [Route("get")]
[HttpPost] [HttpPost]
public async Task<ActionResult<Account?>> Get() { public async Task<ActionResult<Account?>> Get() {
try { try {
if (isLoggedIn()) { if (isLoggedIn()) {
return await getLoggedInUser(); return await getLoggedInUser();
} }
return Ok(); return Ok();
} catch { } catch {
return Ok(); return Ok();
} }
} }
[Route("logout")] [Route("logout")]
[HttpPost] [HttpPost]
public async Task Logout() { public async Task Logout() {
await HttpContext.SignOutAsync(); await HttpContext.SignOutAsync();
} }
[Route("sendverifyemail")] [Route("sendverifyemail")]
[HttpPost] [HttpPost]
public async Task<ActionResult<string>> SendVerify([FromForm] string UserName) { public async Task<ActionResult<string>> SendVerify([FromForm] string UserName) {
try { try {
string key = "v" + UserName; string key = "v" + UserName;
// Stop from sending multiple emails quickly // Stop from sending multiple emails quickly
if (_emailContext._SentEmails.ContainsKey(key)) { if (_emailContext._SentEmails.ContainsKey(key)) {
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key); DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) { if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
return "Cannot sent another verify email until 5 minutes has elapsed "; return "Cannot sent another verify email until 5 minutes has elapsed ";
} }
else { else {
_emailContext._SentEmails.Remove(key); _emailContext._SentEmails.Remove(key);
} }
} }
Account? test = await _databaseService.GetAccount(UserName.ToLower()); Account? test = await _databaseService.GetAccount(UserName.ToLower());
if (test != null) { if (test != null) {
test.EmailToken = Guid.NewGuid().ToString(); test.EmailToken = Guid.NewGuid().ToString();
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
string EmailContents = EmailService.VerifyEmailEmail; string EmailContents = EmailService.VerifyEmailEmail;
EmailContents = Substitue(EmailContents, "@UserName", UserName); EmailContents = Substitue(EmailContents, "@UserName", UserName);
EmailContents = Substitue(EmailContents, "@UserName", UserName); EmailContents = Substitue(EmailContents, "@UserName", UserName);
EmailContents = Substitue(EmailContents, "@VerifyPassword", test.EmailToken); EmailContents = Substitue(EmailContents, "@VerifyPassword", test.EmailToken);
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents); string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
_emailContext._SentEmails.Add(key, DateTime.Now); _emailContext._SentEmails.Add(key, DateTime.Now);
return result; return result;
} }
return "Account not found"; return "Account not found";
} catch (Exception) { } catch (Exception) {
return "The connection couldn't be established to the email server"; return "The connection couldn't be established to the email server";
} }
} }
[Route("verifyemail")] [Route("verifyemail")]
[HttpPost] [HttpPost]
public async Task<ActionResult<bool>> VerifyEmail([FromForm] string UserName, [FromForm] string EmailToken) { public async Task<ActionResult<bool>> VerifyEmail([FromForm] string UserName, [FromForm] string EmailToken) {
try { try {
Account? test = await _databaseService.GetAccount(UserName.ToLower()); Account? test = await _databaseService.GetAccount(UserName.ToLower());
if (test != null) { if (test != null) {
if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == EmailToken) { if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == EmailToken) {
test.EmailToken = ""; test.EmailToken = "";
test.EmailVerified = true; test.EmailVerified = true;
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
return true; return true;
} }
} }
return false; return false;
} catch { } catch {
return false; return false;
} }
} }
[Route("sendresetpassword")] [Route("sendresetpassword")]
[HttpPost] [HttpPost]
public async Task<ActionResult<string>> ResetPassword([FromForm] string Email) { public async Task<ActionResult<string>> ResetPassword([FromForm] string Email) {
try { try {
string key = "p" + Email.ToLower(); string key = "p" + Email.ToLower();
// Stop from sending multiple emails quickly // Stop from sending multiple emails quickly
if (_emailContext._SentEmails.ContainsKey(key)) { if (_emailContext._SentEmails.ContainsKey(key)) {
DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key); DateTime PreviousSentTime = _emailContext._SentEmails.GetValueOrDefault(key);
if (PreviousSentTime.AddMinutes(5) > DateTime.Now) { if (PreviousSentTime.AddMinutes(5) > DateTime.Now) {
return "Cannot sent another reset requests until 5 minutes has elapsed"; return "Cannot sent another reset requests until 5 minutes has elapsed";
} }
else { else {
_emailContext._SentEmails.Remove(key); _emailContext._SentEmails.Remove(key);
} }
} }
Account? test = await _databaseService.GetAccount(Email.ToLower()); Account? test = await _databaseService.GetAccount(Email.ToLower());
if (test != null) { if (test != null) {
test.EmailToken = Guid.NewGuid().ToString(); test.EmailToken = Guid.NewGuid().ToString();
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
string EmailContents = EmailService.ResetPasswordEmail; string EmailContents = EmailService.ResetPasswordEmail;
EmailContents = Substitue(EmailContents, "@UserName", test.UserName); EmailContents = Substitue(EmailContents, "@UserName", test.UserName);
EmailContents = Substitue(EmailContents, "@UserName", test.UserName); EmailContents = Substitue(EmailContents, "@UserName", test.UserName);
EmailContents = Substitue(EmailContents, "@ResetPassWord", test.EmailToken); EmailContents = Substitue(EmailContents, "@ResetPassWord", test.EmailToken);
string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents); string result = _emailContext.Send(test.Email, EmailService.VerifyEmailSubject, EmailContents);
_emailContext._SentEmails.Add(key, DateTime.Now); _emailContext._SentEmails.Add(key, DateTime.Now);
return result; return result;
} }
return "Account Not Found"; return "Account Not Found";
} catch (Exception e) { } catch (Exception e) {
Console.WriteLine("EmailService Error: " + e.ToString()); Console.WriteLine("EmailService Error: " + e.ToString());
return "The connection couldn't be established to the email server"; return "The connection couldn't be established to the email server";
} }
} }
[Route("resetpassword")] [Route("resetpassword")]
[HttpPost] [HttpPost]
public async Task<ActionResult<bool>> ResetPwdVerify([FromForm] string UserName, [FromForm] string NewPassword, [FromForm] string ResetToken) { public async Task<ActionResult<bool>> ResetPwdVerify([FromForm] string UserName, [FromForm] string NewPassword, [FromForm] string ResetToken) {
try { try {
Account? test = await _databaseService.GetAccount(UserName.ToLower()); Account? test = await _databaseService.GetAccount(UserName.ToLower());
if (test != null && !string.IsNullOrEmpty(test.EmailToken)) { if (test != null && !string.IsNullOrEmpty(test.EmailToken)) {
if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == ResetToken) { if (!string.IsNullOrEmpty(test.EmailToken) && test.EmailToken == ResetToken) {
test.CurrentPasswordAttempts = 0; test.CurrentPasswordAttempts = 0;
test.EmailToken = ""; test.EmailToken = "";
test.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword); test.PasswordHash = BCrypt.Net.BCrypt.HashPassword(NewPassword);
await _databaseService.SetAccount(test); await _databaseService.SetAccount(test);
return true; return true;
} }
} }
return false; return false;
} catch { } catch {
return false; return false;
} }
} }
[Route("delete")] [Route("delete")]
[HttpPost] [HttpPost]
public async Task<ActionResult<bool>> delete([FromForm] string Password) { public async Task<ActionResult<bool>> delete([FromForm] string Password) {
try { try {
if (isLoggedIn()) { if (isLoggedIn()) {
Account user = await getLoggedInUser(); Account user = await getLoggedInUser();
if (BCrypt.Net.BCrypt.Verify(Password, user.PasswordHash)) { if (BCrypt.Net.BCrypt.Verify(Password, user.PasswordHash)) {
await _databaseService.DeleteAccount(user.ID); await _databaseService.DeleteAccount(user.ID);
return true; return true;
} }
} }
return false; return false;
} catch { } catch {
return false; return false;
} }
} }
} }
} }