using System.Globalization; using System.Security.Cryptography; using System.Text.RegularExpressions; using System.Collections.Generic; using System; namespace Tesses.Chatr.Server { public class Account { public Account() { Name=""; Username=""; HashedPassword=""; Salt=""; Email=""; ShowUserNameToAnyBody=false; ShowBots=true; HiddenBots=new List(); HiddenUsers=new List(); IsAnonymous=false; IsAdmin=false; } public bool IsHidden(long user,long bot) { if(bot != -1 && !ShowBots) return true; if(HiddenUsers.Contains(user)) return true; if(bot == -1) return false; if(HiddenBots.Contains(bot)) return true; return false; } public bool IsAnonymous {get;set;} public long Id {get;set;} public string Name {get;set;} public string Username {get;set;} public string Email {get;set;} public string HashedPassword {get;set;} public string Salt {get;set;} public bool Verified {get;set;} public bool ShowUserNameToAnyBody {get;set;} public bool ShowBots {get;set;} public List HiddenUsers {get;set;} public List HiddenBots {get;set;} public bool IsAdmin { get; internal set; } public bool IsValid() { if(!IsValidEmail(Email)) return false; if(!IsValidUserName(Username)) return false; if(!IsValidName(Name)) return false; return true; } public static bool IsValidName(string name) { foreach(var c in name) { if(c == ' ') continue; if(char.IsLetterOrDigit(c)) continue; if(c=='_') continue; return false; } return true; } public static bool IsValidUserName(string username) { if(string.IsNullOrWhiteSpace(username)) return false; if(username.Contains(" ")) return false; return IsValidName(username); } private static bool IsValidEmail(string email) { if (string.IsNullOrWhiteSpace(email)) return false; try { // Normalize the domain email = Regex.Replace(email, @"(@)(.+)$", DomainMapper, RegexOptions.None, TimeSpan.FromMilliseconds(200)); // Examines the domain part of the email and normalizes it. string DomainMapper(Match match) { // Use IdnMapping class to convert Unicode domain names. var idn = new IdnMapping(); // Pull out and process domain name (throws ArgumentException on invalid) string domainName = idn.GetAscii(match.Groups[2].Value); return match.Groups[1].Value + domainName; } } catch (RegexMatchTimeoutException e) { _=e; return false; } catch (ArgumentException e) { _=e; return false; } try { return Regex.IsMatch(email, @"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(250)); } catch (RegexMatchTimeoutException) { return false; } } public bool IsCorrectPassword(string password) { string pass = $"{password}{Salt}"; using(SHA256 mySHA256 = SHA256.Create()) { string check= Convert.ToBase64String(mySHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pass))); return check.Equals(HashedPassword); } } public void SetPassword(string password,bool resetSalt=true) { if(resetSalt) Salt=GetNewSalt(); string pass = $"{password}{Salt}"; using(SHA256 mySHA256 = SHA256.Create()) { string check= Convert.ToBase64String(mySHA256.ComputeHash(System.Text.Encoding.UTF8.GetBytes(pass))); HashedPassword=check; } } public static string GetNewSalt() { return Session.GetNewId(); } } }