From 638391d7aba972d27d05ec6fa28765a124e32006 Mon Sep 17 00:00:00 2001 From: Dunedan Date: Mon, 19 May 2025 16:51:33 +0200 Subject: [PATCH] Fix password change for certain usernames This fixes the ability for users with uppercase letters in their username to change their passwords, which wasn't possible before on non-Windows platforms. The underlying issue for that is https://github.com/processone/ejabberd/issues/4377 and in addition some inconsistent normalization of usernames in password change requests by gloox. This commit works around that by always using the local JID part as username for password requests, which got the nodeprep string profile already applied. It also fixes a problem that Windows users which were able to change their passwords, weren't able to login afterwards anymore, unless they typed their username in all lowercase in the login form. This was caused by using the all lowercase username as input for the password hash function, instead of using the username in the user supplied case. Fixes #7796 --- .../AccountSettingsPage.js | 10 +--------- source/lobby/IXmppClient.h | 3 ++- source/lobby/XmppClient.cpp | 19 +++++++++++++++---- source/lobby/XmppClient.h | 3 ++- source/lobby/scripting/JSInterface_Lobby.cpp | 3 ++- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/binaries/data/mods/public/gui/lobby/AccountSettingsPage/AccountSettingsPage.js b/binaries/data/mods/public/gui/lobby/AccountSettingsPage/AccountSettingsPage.js index 7a1849331e..78ced36bd9 100644 --- a/binaries/data/mods/public/gui/lobby/AccountSettingsPage/AccountSettingsPage.js +++ b/binaries/data/mods/public/gui/lobby/AccountSettingsPage/AccountSettingsPage.js @@ -98,14 +98,6 @@ var AccountSettingsPage = { if (Engine.GetGUIObjectByName("as_PasswordInputConfirm").caption !== newPass) throw new SetPasswordError(translate("Passwords do not match")); - const usn = Engine.LobbyGetJID(); - const atIndex = usn.indexOf("@"); - if (atIndex == -1) - { - // Probably can't happen too easily, so error out. - error("Invalid JID"); - throw new SetPasswordError(translate("Invalid JID, cannot change password.")); - } - return Engine.EncryptPassword(newPass, usn.substring(0, atIndex).toLowerCase()); + return Engine.EncryptPassword(newPass, Engine.LobbyGetUsername()); } }; diff --git a/source/lobby/IXmppClient.h b/source/lobby/IXmppClient.h index 491da0c60f..4aced9ee6d 100644 --- a/source/lobby/IXmppClient.h +++ b/source/lobby/IXmppClient.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -43,6 +43,7 @@ public: virtual void SetNick(const std::string& nick) = 0; virtual std::string GetNick() const = 0; virtual std::string GetJID() const = 0; + virtual std::string GetUsername() const = 0; virtual void ChangePassword(const std::string& newPassword) = 0; virtual void kick(const std::string& nick, const std::string& reason) = 0; virtual void ban(const std::string& nick, const std::string& reason) = 0; diff --git a/source/lobby/XmppClient.cpp b/source/lobby/XmppClient.cpp index e6c64b678a..697056cad9 100644 --- a/source/lobby/XmppClient.cpp +++ b/source/lobby/XmppClient.cpp @@ -1155,9 +1155,9 @@ const std::wstring& XmppClient::GetSubject() } /** - * Request nick change, real change via mucRoomHandler. + * Request MUC nick change, real change via mucRoomHandler. * - * @param nick Desired nickname + * @param nick Desired MUC nickname */ void XmppClient::SetNick(const std::string& nick) { @@ -1165,7 +1165,7 @@ void XmppClient::SetNick(const std::string& nick) } /** - * Get current nickname. + * Get current MUC nickname. */ std::string XmppClient::GetNick() const { @@ -1177,6 +1177,17 @@ std::string XmppClient::GetJID() const return m_client->jid().full(); } + +/** + * Get the XMPP username. + * + * @return current XMPP username + */ +std::string XmppClient::GetUsername() const +{ + return m_username; +} + /** * Change password for authenticated user. * @@ -1184,7 +1195,7 @@ std::string XmppClient::GetJID() const */ void XmppClient::ChangePassword(const std::string& newPassword) { - m_registration->changePassword(m_username, newPassword); + m_registration->changePassword(m_client->jid().username(), newPassword); } /** diff --git a/source/lobby/XmppClient.h b/source/lobby/XmppClient.h index 634c324c58..28730619f4 100644 --- a/source/lobby/XmppClient.h +++ b/source/lobby/XmppClient.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -88,6 +88,7 @@ public: void SetNick(const std::string& nick) override; std::string GetNick() const override; std::string GetJID() const override; + std::string GetUsername() const override; void ChangePassword(const std::string& newPassword) override; void kick(const std::string& nick, const std::string& reason) override; void ban(const std::string& nick, const std::string& reason) override; diff --git a/source/lobby/scripting/JSInterface_Lobby.cpp b/source/lobby/scripting/JSInterface_Lobby.cpp index 33765c3028..06076984f4 100644 --- a/source/lobby/scripting/JSInterface_Lobby.cpp +++ b/source/lobby/scripting/JSInterface_Lobby.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2024 Wildfire Games. +/* Copyright (C) 2025 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -218,6 +218,7 @@ void RegisterScriptFunctions(const ScriptRequest& rq) REGISTER_XMPP(SetNick, "LobbySetNick"); REGISTER_XMPP(GetNick, "LobbyGetNick"); REGISTER_XMPP(GetJID, "LobbyGetJID"); + REGISTER_XMPP(GetUsername, "LobbyGetUsername"); REGISTER_XMPP(ChangePassword, "LobbyChangePassword"); REGISTER_XMPP(kick, "LobbyKick"); REGISTER_XMPP(ban, "LobbyBan");