From 143d1b304df2a6918b8203b6612fbcfd9a2728ea Mon Sep 17 00:00:00 2001 From: WeylonSantana <63019821+WeylonSantana@users.noreply.github.com> Date: Thu, 1 Aug 2024 13:36:59 -0300 Subject: [PATCH] chore: refactor register window (#2353) --- Intersect (Core)/Security/PasswordUtils.cs | 12 + .../Interface/Menu/LoginWindow.cs | 10 +- Intersect.Client/Interface/Menu/MainMenu.cs | 6 +- .../Interface/Menu/MainMenuWindow.cs | 4 +- .../Interface/Menu/RegisterWindow.cs | 277 ------------------ .../Interface/Menu/RegistrationWindow.cs | 144 +++++++++ 6 files changed, 164 insertions(+), 289 deletions(-) create mode 100644 Intersect (Core)/Security/PasswordUtils.cs delete mode 100644 Intersect.Client/Interface/Menu/RegisterWindow.cs create mode 100644 Intersect.Client/Interface/Menu/RegistrationWindow.cs diff --git a/Intersect (Core)/Security/PasswordUtils.cs b/Intersect (Core)/Security/PasswordUtils.cs new file mode 100644 index 000000000..75df90c74 --- /dev/null +++ b/Intersect (Core)/Security/PasswordUtils.cs @@ -0,0 +1,12 @@ +using System.Security.Cryptography; +using System.Text; + +namespace Intersect.Security; + +public partial class PasswordUtils +{ + public static string ComputePasswordHash(string password) + { + return BitConverter.ToString(SHA256.HashData(Encoding.UTF8.GetBytes(password ?? string.Empty))).Replace("-", string.Empty); + } +} diff --git a/Intersect.Client/Interface/Menu/LoginWindow.cs b/Intersect.Client/Interface/Menu/LoginWindow.cs index 238c0f404..a0dd702ca 100644 --- a/Intersect.Client/Interface/Menu/LoginWindow.cs +++ b/Intersect.Client/Interface/Menu/LoginWindow.cs @@ -1,5 +1,3 @@ -using System.Security.Cryptography; -using System.Text; using Intersect.Client.Core; using Intersect.Client.Framework.File_Management; using Intersect.Client.Framework.Gwen.Control; @@ -9,6 +7,7 @@ using Intersect.Client.Interface.Game.Chat; using Intersect.Client.Localization; using Intersect.Client.Networking; +using Intersect.Security; using Intersect.Utilities; namespace Intersect.Client.Interface.Menu; @@ -177,7 +176,7 @@ private void TryLogin() var password = _savedPass; if (!_useSavedPass) { - password = ComputePasswordHash(_txtPassword.Text.Trim()); + password = PasswordUtils.ComputePasswordHash(_txtPassword.Text.Trim()); } Globals.WaitingOnServer = true; @@ -209,9 +208,6 @@ private void LoadCredentials() _chkSavePass.IsChecked = true; } - private static string ComputePasswordHash(string password) => - BitConverter.ToString(SHA256.HashData(Encoding.UTF8.GetBytes(password ?? string.Empty))).Replace("-", string.Empty); - private void SaveCredentials() { string username = string.Empty, password = string.Empty; @@ -219,7 +215,7 @@ private void SaveCredentials() if (_chkSavePass.IsChecked) { username = _txtUsername.Text.Trim(); - password = _useSavedPass ? _savedPass : ComputePasswordHash(_txtPassword.Text.Trim()); + password = _useSavedPass ? _savedPass : PasswordUtils.ComputePasswordHash(_txtPassword.Text.Trim()); } Globals.Database.SavePreference("Username", username); diff --git a/Intersect.Client/Interface/Menu/MainMenu.cs b/Intersect.Client/Interface/Menu/MainMenu.cs index 86c05dde5..d74137e5b 100644 --- a/Intersect.Client/Interface/Menu/MainMenu.cs +++ b/Intersect.Client/Interface/Menu/MainMenu.cs @@ -39,7 +39,7 @@ public static void HandleReceivedConfiguration() private readonly SettingsWindow mSettingsWindow; - private readonly RegisterWindow mRegisterWindow; + private readonly RegistrationWindow mRegisterWindow; private readonly ResetPasswordWindow mResetPasswordWindow; @@ -73,7 +73,7 @@ public MainMenu(Canvas menuCanvas) : base(menuCanvas) mLoginWindow = new LoginWindow(menuCanvas, this); //Register Controls - mRegisterWindow = new RegisterWindow(menuCanvas, this); + mRegisterWindow = new RegistrationWindow(menuCanvas, this); //Forgot Password Controls mForgotPasswordWindow = new ForgotPasswordWindow(menuCanvas, this); @@ -228,7 +228,7 @@ internal void SwitchToWindow() where TMainMenuWindow : IMainMen { mLoginWindow.Show(); } - else if (typeof(TMainMenuWindow) == typeof(RegisterWindow)) + else if (typeof(TMainMenuWindow) == typeof(RegistrationWindow)) { mRegisterWindow.Show(); } diff --git a/Intersect.Client/Interface/Menu/MainMenuWindow.cs b/Intersect.Client/Interface/Menu/MainMenuWindow.cs index da6c0ab9b..0d80d9e32 100644 --- a/Intersect.Client/Interface/Menu/MainMenuWindow.cs +++ b/Intersect.Client/Interface/Menu/MainMenuWindow.cs @@ -134,7 +134,7 @@ private void ButtonRegisterOnClicked(Base sender, ClickedEventArgs arguments) { if (Networking.Network.InterruptDisconnectsIfConnected()) { - _mainMenu.SwitchToWindow(); + _mainMenu.SwitchToWindow(); } else { @@ -163,7 +163,7 @@ private void RemoveRegisterEvents() private void RegisterConnected(object? sender, EventArgs eventArgs) { RemoveRegisterEvents(); - _mainMenu.SwitchToWindow(); + _mainMenu.SwitchToWindow(); } #endregion Register diff --git a/Intersect.Client/Interface/Menu/RegisterWindow.cs b/Intersect.Client/Interface/Menu/RegisterWindow.cs deleted file mode 100644 index 3cf7c848c..000000000 --- a/Intersect.Client/Interface/Menu/RegisterWindow.cs +++ /dev/null @@ -1,277 +0,0 @@ -using System.Security.Cryptography; -using System.Text; - -using Intersect.Client.Core; -using Intersect.Client.Framework.File_Management; -using Intersect.Client.Framework.Gwen.Control; -using Intersect.Client.Framework.Gwen.Control.EventArguments; -using Intersect.Client.General; -using Intersect.Client.Interface.Game.Chat; -using Intersect.Client.Localization; -using Intersect.Client.Networking; -using Intersect.Utilities; - -namespace Intersect.Client.Interface.Menu; - - -public partial class RegisterWindow : IMainMenuWindow -{ - - private Button mBackBtn; - - private ImagePanel mEmailBackground; - - private Label mEmailLabel; - - private TextBox mEmailTextbox; - - //Parent - private MainMenu mMainMenu; - - private ImagePanel mPasswordBackground; - - private ImagePanel mPasswordBackground2; - - private Label mPasswordLabel; - - private Label mPasswordLabel2; - - private TextBoxPassword mPasswordTextbox; - - private TextBoxPassword mPasswordTextbox2; - - private Button mRegisterBtn; - - private Label mRegistrationHeader; - - //Controls - private ImagePanel mRegistrationPanel; - - private ImagePanel mUsernameBackground; - - private Label mUsernameLabel; - - private TextBox mUsernameTextbox; - - //Init - public RegisterWindow(Canvas parent, MainMenu mainMenu) - { - //Assign References - mMainMenu = mainMenu; - - //Main Menu Window - mRegistrationPanel = new ImagePanel(parent, "RegistrationWindow"); - - //Menu Header - mRegistrationHeader = new Label(mRegistrationPanel, "RegistrationLabel"); - mRegistrationHeader.SetText(Strings.Registration.Title); - - //Register Username Background - mUsernameBackground = new ImagePanel(mRegistrationPanel, "UsernamePanel"); - - //Register Username Label - mUsernameLabel = new Label(mUsernameBackground, "UsernameLabel"); - mUsernameLabel.SetText(Strings.Registration.Username); - - //Register Username Textbox - mUsernameTextbox = new TextBox(mUsernameBackground, "UsernameField") - { - IsTabable = true, - }; - mUsernameTextbox.SubmitPressed += UsernameTextbox_SubmitPressed; - - //Register Email Background - mEmailBackground = new ImagePanel(mRegistrationPanel, "EmailPanel"); - - //Register Email Label - mEmailLabel = new Label(mEmailBackground, "EmailLabel"); - mEmailLabel.SetText(Strings.Registration.Email); - - //Register Email Textbox - mEmailTextbox = new TextBox(mEmailBackground, "EmailField") - { - IsTabable = true, - }; - mEmailTextbox.SubmitPressed += EmailTextbox_SubmitPressed; - - //Register Password Background - mPasswordBackground = new ImagePanel(mRegistrationPanel, "Password1Panel"); - - //Register Password Label - mPasswordLabel = new Label(mPasswordBackground, "Password1Label"); - mPasswordLabel.SetText(Strings.Registration.Password); - - //Register Password Textbox - mPasswordTextbox = new TextBoxPassword(mPasswordBackground, "Password1Field") - { - IsTabable = true, - }; - mPasswordTextbox.SubmitPressed += PasswordTextbox_SubmitPressed; - - //Register Password Background - mPasswordBackground2 = new ImagePanel(mRegistrationPanel, "Password2Panel"); - - //Register Password Label2 - mPasswordLabel2 = new Label(mPasswordBackground2, "Password2Label"); - mPasswordLabel2.SetText(Strings.Registration.ConfirmPassword); - - //Register Password Textbox2 - mPasswordTextbox2 = new TextBoxPassword(mPasswordBackground2, "Password2Field") - { - IsTabable = true, - }; - mPasswordTextbox2.SubmitPressed += PasswordTextbox2_SubmitPressed; - - //Register - Send Registration Button - mRegisterBtn = new Button(mRegistrationPanel, "RegisterButton") - { - // IsTabable = true, - Text = Strings.Registration.Register, - }; - mRegisterBtn.Clicked += RegisterBtn_Clicked; - - //Register - Back Button - mBackBtn = new Button(mRegistrationPanel, "BackButton") - { - // IsTabable = true, - Text = Strings.Registration.Back, - }; - mBackBtn.Clicked += BackBtn_Clicked; - - mRegistrationPanel.LoadJsonUi(GameContentManager.UI.Menu, Graphics.Renderer.GetResolutionString()); - } - - public bool IsHidden => mRegistrationPanel.IsHidden; - - //Methods - public void Update() - { - if (!Networking.Network.IsConnected) - { - Hide(); - mMainMenu.Show(); - } - - // Re-Enable our buttons if we're not waiting for the server anymore with it disabled. - if (!Globals.WaitingOnServer && mRegisterBtn.IsDisabled) - { - mRegisterBtn.Enable(); - } - } - - public void Show() - { - mRegistrationPanel.Show(); - mUsernameTextbox.Focus(); - } - - public void Hide() - { - mRegistrationPanel.Hide(); - } - - private static string ComputePasswordHash(string password) - { - using (var sha = new SHA256Managed()) - { - return BitConverter.ToString(sha.ComputeHash(Encoding.UTF8.GetBytes(password ?? ""))).Replace("-", ""); - } - } - - void TryRegister() - { - if (Globals.WaitingOnServer) - { - return; - } - - if (Networking.Network.IsConnected) - { - if (FieldChecking.IsValidUsername(mUsernameTextbox.Text, Strings.Regex.Username)) - { - if (mPasswordTextbox.Text == mPasswordTextbox2.Text) - { - if (FieldChecking.IsValidPassword(mPasswordTextbox.Text, Strings.Regex.Password)) - { - if (FieldChecking.IsWellformedEmailAddress(mEmailTextbox.Text, Strings.Regex.Email)) - { - Hide(); - - //Hash Password - using (var sha = new SHA256Managed()) - { - var hashedPass = BitConverter.ToString( - sha.ComputeHash(Encoding.UTF8.GetBytes(mPasswordTextbox.Text.Trim())) - ) - .Replace("-", ""); - - PacketSender.SendCreateAccount( - mUsernameTextbox.Text, hashedPass, mEmailTextbox.Text - ); - } - - Globals.WaitingOnServer = true; - mRegisterBtn.Disable(); - ChatboxMsg.ClearMessages(); - } - else - { - Interface.ShowError(Strings.Registration.EmailInvalid); - } - } - else - { - Interface.ShowError(Strings.Errors.PasswordInvalid); - } - } - else - { - Interface.ShowError(Strings.Registration.PasswordMismatch); - } - } - else - { - Interface.ShowError(Strings.Errors.UsernameInvalid); - } - } - else - { - Interface.ShowError(Strings.Errors.NotConnected); - } - } - - //Input Handlers - void UsernameTextbox_SubmitPressed(Base sender, EventArgs arguments) - { - TryRegister(); - } - - void EmailTextbox_SubmitPressed(Base sender, EventArgs arguments) - { - TryRegister(); - } - - void PasswordTextbox_SubmitPressed(Base sender, EventArgs arguments) - { - TryRegister(); - } - - void PasswordTextbox2_SubmitPressed(Base sender, EventArgs arguments) - { - TryRegister(); - } - - void RegisterBtn_Clicked(Base sender, ClickedEventArgs arguments) - { - TryRegister(); - } - - void BackBtn_Clicked(Base sender, ClickedEventArgs arguments) - { - Hide(); - mMainMenu.Show(); - - Networking.Network.DebounceClose("returning_to_main_menu"); - } - -} diff --git a/Intersect.Client/Interface/Menu/RegistrationWindow.cs b/Intersect.Client/Interface/Menu/RegistrationWindow.cs new file mode 100644 index 000000000..f0def83ae --- /dev/null +++ b/Intersect.Client/Interface/Menu/RegistrationWindow.cs @@ -0,0 +1,144 @@ +using Intersect.Client.Core; +using Intersect.Client.Framework.File_Management; +using Intersect.Client.Framework.Gwen.Control; +using Intersect.Client.General; +using Intersect.Client.Interface.Game.Chat; +using Intersect.Client.Localization; +using Intersect.Client.Networking; +using Intersect.Security; +using Intersect.Utilities; + +namespace Intersect.Client.Interface.Menu; + +public partial class RegistrationWindow : ImagePanel, IMainMenuWindow +{ + private readonly MainMenu _mainMenu; + + private readonly Label _registrationHeader; + private readonly TextBox _textBoxUsername; + private readonly TextBox _textBoxEmail; + private readonly TextBoxPassword _textBoxPassword; + private readonly TextBoxPassword _textBoxConfirmPassword; + private readonly Button _buttonRegister; + + //Init + public RegistrationWindow(Canvas parent, MainMenu mainMenu) : base(parent, nameof(RegistrationWindow)) + { + //Assign References + _mainMenu = mainMenu; + + //Menu Header + _registrationHeader = new Label(this, "RegistrationLabel"); + _registrationHeader.SetText(Strings.Registration.Title); + + //Register Username Label/Textbox + var _usernameContainer = new ImagePanel(this, "UsernamePanel"); + _ = new Label(_usernameContainer, "UsernameLabel") { Text = Strings.Registration.Username }; + _textBoxUsername = new TextBox(_usernameContainer, "UsernameField") { IsTabable = true }; + _textBoxUsername.SubmitPressed += (s, e) => TryRegister(); + + //Register Email Label/Textbox + var _emailContainer = new ImagePanel(this, "EmailPanel"); + _ = new Label(_emailContainer, "EmailLabel") { Text = Strings.Registration.Email }; + _textBoxEmail = new TextBox(_emailContainer, "EmailField") { IsTabable = true }; + _textBoxEmail.SubmitPressed += (s, e) => TryRegister(); + + //Register Password Label/Textbox + var _passwordContainer = new ImagePanel(this, "Password1Panel"); + _ = new Label(_passwordContainer, "Password1Label") { Text = Strings.Registration.Password }; + _textBoxPassword = new TextBoxPassword(_passwordContainer, "Password1Field") { IsTabable = true }; + _textBoxPassword.SubmitPressed += (s, e) => TryRegister(); + + //Register Confirm Password Label/Textbox + var _confirmPasswordContainer = new ImagePanel(this, "Password2Panel"); + _ = new Label(_confirmPasswordContainer, "Password2Label") { Text = Strings.Registration.ConfirmPassword }; + _textBoxConfirmPassword = new TextBoxPassword(_confirmPasswordContainer, "Password2Field") { IsTabable = true }; + _textBoxConfirmPassword.SubmitPressed += (s, e) => TryRegister(); + + //Register - Send Registration Button + _buttonRegister = new Button(this, "RegisterButton") { Text = Strings.Registration.Register }; + _buttonRegister.Clicked += (s, e) => TryRegister(); + + //Register - Back Button + var _buttonBack = new Button(this, "BackButton") { Text = Strings.Registration.Back }; + _buttonBack.Clicked += (s, e) => + { + Hide(); + _mainMenu.Show(); + Networking.Network.DebounceClose("returning_to_main_menu"); + }; + + LoadJsonUi(GameContentManager.UI.Menu, Graphics.Renderer?.GetResolutionString()); + } + + //Methods + public void Update() + { + if (!Networking.Network.IsConnected) + { + Hide(); + _mainMenu.Show(); + } + + // Re-Enable our buttons if we're not waiting for the server anymore with it disabled. + if (!Globals.WaitingOnServer && _buttonRegister.IsDisabled) + { + _buttonRegister.Enable(); + } + } + + public override void Show() + { + base.Show(); + _textBoxUsername.Focus(); + } + + void TryRegister() + { + if (Globals.WaitingOnServer) + { + return; + } + + if (!Networking.Network.IsConnected) + { + Interface.ShowError(Strings.Errors.NotConnected); + return; + } + + if (!FieldChecking.IsValidUsername(_textBoxUsername.Text, Strings.Regex.Username)) + { + Interface.ShowError(Strings.Errors.UsernameInvalid); + return; + } + + if (!FieldChecking.IsWellformedEmailAddress(_textBoxEmail.Text, Strings.Regex.Email)) + { + Interface.ShowError(Strings.Registration.EmailInvalid); + return; + } + + if (!FieldChecking.IsValidPassword(_textBoxPassword.Text, Strings.Regex.Password)) + { + Interface.ShowError(Strings.Errors.PasswordInvalid); + return; + } + + if (_textBoxPassword.Text != _textBoxConfirmPassword.Text) + { + Interface.ShowError(Strings.Registration.PasswordMismatch); + return; + } + + PacketSender.SendCreateAccount( + _textBoxUsername.Text, + PasswordUtils.ComputePasswordHash(_textBoxPassword.Text.Trim()), + _textBoxEmail.Text + ); + + Globals.WaitingOnServer = true; + _buttonRegister.Disable(); + ChatboxMsg.ClearMessages(); + Hide(); + } +}