using Microsoft.AspNetCore.Mvc; using Auth.Services.DatabaseService; using System.Web.Http; using Auth.Entities; using Microsoft.IdentityModel.Tokens; using System.IdentityModel.Tokens.Jwt; using System.Security.Claims; using Auth.Services; using Auth.DTO; namespace Auth.Controllers { [ApiController] [Route("api/v1/mauth/")] public class MAuthController : MistoxControllerBase { public MAuthController(DatabaseService db) : base(db) { } static Dictionary LoginSessions = new Dictionary(); // Login and return a ticket to retreive your JWT [HttpPost("login")] public async Task Authenticate([FromBody] LoginRequest request) { try { Account? test = await _databaseService.GetAccount(request.UserName.ToLower()); if (test != null) { if (test.EmailVerified == true) { if (test.FailedPasswordLock) { if (test.CurrentPasswordAttempts >= test.PasswordAttempts) { return BadRequest("Too many failed password attempts. Please reset your password"); } } if (BCrypt.Net.BCrypt.Verify(request.Password, test.PasswordHash)) { test.CurrentPasswordAttempts = 0; await _databaseService.SetAccount(test); string Ticket = Guid.NewGuid().ToString().Replace("-", ""); LoginSessions[Ticket] = new JWTMemCache { JWT = AuthJWT.GenereateJWTToken(test, request.StayLoggedIn), ExpiresAt = DateTime.UtcNow.AddMinutes(2) }; return Ok(Ticket); } else { test.CurrentPasswordAttempts += 1; await _databaseService.SetAccount(test); return BadRequest("Wrong Password"); } } else { return BadRequest("You need to verify your email before you can sign in"); } } return BadRequest("Account Not Found"); } catch (Exception ex) { Console.WriteLine("Login Error: " + ex.Message); return BadRequest("An internal server error has occured: " + ex.Message); } } [HttpPost("token")] public ActionResult Token([FromForm] JWTRequest request) { try { if (LoginSessions.ContainsKey(request.Ticket)) { JWTMemCache JWTObj = LoginSessions[request.Ticket]; if (JWTObj.ExpiresAt < DateTime.UtcNow) { string JWT = JWTObj.JWT; LoginSessions.Remove(request.Ticket); return Ok(JWT); } else { LoginSessions.Remove(request.Ticket); return BadRequest("The session ticket has already expired"); } } return BadRequest("The session ticket cannot be found"); } catch (Exception ex) { Console.WriteLine("Delete Error: " + ex.Message); return BadRequest("An internal server error has occured"); } } // Renews an old JWT before it expires [HttpPost("renew")] public IActionResult Session([FromBody] JWTRenewRequest request) { try { JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler(); ClaimsPrincipal claimsPrincipal = handler.ValidateToken(request.JWT, AuthJWT.TokenParameters, out var validatedToken); JwtSecurityToken jwt = (JwtSecurityToken)validatedToken; if (jwt != null) { if (jwt.ValidTo - DateTime.UtcNow < TimeSpan.FromDays(1)) { var newJwt = AuthJWT.RenewJWTToken(claimsPrincipal); return Ok(newJwt); } return BadRequest("Not ready to renew"); } return BadRequest("Malformed Token"); } catch (SecurityTokenException ex) { return BadRequest("Token invalid: " + ex.Message); } } } }