using Godot; using Microsoft.IdentityModel.Tokens; using System; using System.IdentityModel.Tokens.Jwt; using System.Net.Http; using System.Net.Http.Json; using System.Security.Claims; using System.Security.Cryptography; using System.Threading.Tasks; public partial class MistoxNet : Node{ Options _Options; Reference _Reference; public override void _Ready() { _Options = GetNode( "/root/Options" ); _Reference = GetNode("/root/Reference"); _Reference.MistoxNet = this; } public static string TokenAudience = "mistox-llc-auth-token"; public static string TokenIssuer = "https://auth.mistox.com"; public static string TokenName = "mistox_session"; public async Task<(bool, string)> TryGetSessionToken( string UserName, string Password ) { using( System.Net.Http.HttpClient client = new System.Net.Http.HttpClient() ) { // Get LoginTicket HttpResponseMessage response = await client.PostAsJsonAsync( "https://auth.mistox.com/api/auth/login", new LoginRequest { UserName = UserName, Password = Password, Site = "PolyphiaGame", StayLoggedIn = true } ); string LoginTicket = await response.Content.ReadAsStringAsync(); // Login Via Ticket HttpResponseMessage response2 = await client.PostAsJsonAsync( "https://auth.mistox.com/api/auth/token", new JWTRequest { Ticket = LoginTicket } ); return (response2.IsSuccessStatusCode, await response2.Content.ReadAsStringAsync()); } } public async Task<(bool, string)> TryUpdateSessionToken( string LoginTicket ) { using( System.Net.Http.HttpClient client = new System.Net.Http.HttpClient() ) { HttpResponseMessage response = await client.PostAsJsonAsync( "https://auth.mistox.com/api/auth/renew", new JWTRenewRequest { JWT = LoginTicket } ); return (response.IsSuccessStatusCode, await response.Content.ReadAsStringAsync()); } } public async Task<(bool, Account)> TryValidateSessionToken( string SessionToken ) { using( System.Net.Http.HttpClient client = new System.Net.Http.HttpClient() ) { HttpResponseMessage response = await client.GetAsync( "https://auth.mistox.com/api/auth/publickey" ); string PublicKey = await response.Content.ReadAsStringAsync(); RSA rsa = RSA.Create(); rsa.ImportFromPem(PublicKey); TokenValidationParameters TokenParameters = new TokenValidationParameters { ValidateIssuer = true, ValidateAudience = true, ValidateLifetime = true, ValidateIssuerSigningKey = true, ValidIssuer = TokenIssuer, ValidAudience = TokenAudience, IssuerSigningKey = new RsaSecurityKey(rsa), ClockSkew = TimeSpan.FromMinutes(1) }; try { JwtSecurityTokenHandler tokenHandler = new JwtSecurityTokenHandler(); ClaimsPrincipal principal = tokenHandler.ValidateToken( SessionToken, TokenParameters, out SecurityToken validatedToken ); return (true, new Account { ID = Convert.ToInt32(principal.FindFirst(ClaimTypes.NameIdentifier).Value), UserName = principal.FindFirst(ClaimTypes.Name).Value, Email = principal.FindFirst(ClaimTypes.Email).Value }); } catch (Exception) { return (false, null); } } } } public class LoginRequest { public string UserName { get; set; } = ""; public string Password { get; set; } = ""; public string Site { get; set; } = ""; public bool StayLoggedIn { get; set; } } public class JWTRequest { public string Ticket { get; set; } = ""; } public class JWTRenewRequest { public string JWT { get; set; } = ""; } public class Account { public int ID { get; set; } // PK public string UserName { get; set; } = ""; public string Email { get; set; } = ""; public bool EmailVerified { get; set; } = false; public string PasswordHash { get; set; } = ""; public string Error { get; set; } = ""; } public class ProjectMistData { public int AccountID { get; set; } // PK public int Credits { get; set; } public int OddballTimer { get; set; } public string SessionToken { get; set; } = ""; public int SessionID { get; set; } public int Kills { get; set; } public int Deaths { get; set; } }