102 lines
4.4 KiB
C#
102 lines
4.4 KiB
C#
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<string, JWTMemCache> LoginSessions = new Dictionary<string, JWTMemCache>();
|
|
|
|
// Login and return a ticket to retreive your JWT
|
|
[HttpPost("login")]
|
|
public async Task<ActionResult> 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);
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|