43#include <unordered_map>
80 {
"onlinelist", accountOnlinelistCommandTable },
83 {
"set", accountSetCommandTable },
89 {
"account", accountCommandTable },
97 if (!masterKey.IsAvailable())
113 TC_LOG_ERROR(
"misc",
"Account {} not found in login database when processing .account 2fa setup command.", accountId);
119 if (!result->Fetch()->IsNull())
128 static std::unordered_map<uint32, Trinity::Crypto::TOTP::Secret> suggestions;
133 if (!pair.second && token)
138 Trinity::Crypto::AEEncryptWithRandomIV<Trinity::Crypto::AES>(pair.first->second, *masterKey);
144 suggestions.erase(pair.first);
161 if (!masterKey.IsAvailable())
177 TC_LOG_ERROR(
"misc",
"Account {} not found in login database when processing .account 2fa setup command.", accountId);
183 Field* field = result->Fetch();
198 bool success = Trinity::Crypto::AEDecrypt<Trinity::Crypto::AES>(secret, *masterKey);
201 TC_LOG_ERROR(
"misc",
"Account {} has invalid ciphertext in TOTP token.", accountId);
249 if (accountName.find(
'@') != std::string::npos)
256 switch (
sAccountMgr->CreateAccount(accountName, password, email.value_or(
"")))
262 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {}) created Account {} (Email: '{}')",
265 accountName, email.value_or(
""));
369 size_t sessionsMatchCount = 0;
372 for (SessionMap::value_type
const& sessionPair : sessionsMap)
389 if (mapId && mapId != playerMapId)
393 if (zoneId && zoneId != playerZoneId)
396 if (!sessionsMatchCount)
413 ++sessionsMatchCount;
416 if (limit && sessionsMatchCount >= limit)
421 if (!sessionsMatchCount)
438 stmt->
setString(0, location->CountryCode);
445 handler->
PSendSysMessage(
"No IP2Location information - account not locked");
489 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the provided email [{}] is not equal to registration email [{}].",
501 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the provided password is wrong.",
507 if (email == oldEmail)
515 if (email != emailConfirm)
520 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the confirm email does not match.",
532 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Changed Email from [{}] to [{}].",
562 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change password, but the provided old password is wrong.",
575 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change password, but the entered email [{}] is wrong.",
578 confirmEmail.value_or(
""));
583 if (newPassword != confirmPassword)
598 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} changed password.",
627 pwConfig ==
PW_EMAIL ?
"Highest level: Email input required." :
628 pwConfig ==
PW_RBAC ?
"Special level: Your account may require email input depending on settings. That is the case if another line is printed." :
629 "Unknown security level: Config error?"));
638 std::string emailoutput;
647 emailoutput = (*result)[0].GetString();
684 accountName.emplace();
734 accountName.emplace();
758 if (targetSecurity >= playerSecurity || securityLevel >= playerSecurity)
791 sAccountMgr->UpdateAccountAccess(
nullptr, accountId, securityLevel, realmID);
808 if (!targetAccountId)
820 if (password != confirmPassword)
859 if (!targetAccountId)
880 if (!masterKey.IsAvailable())
902 Trinity::Crypto::AEEncryptWithRandomIV<Trinity::Crypto::AES>(*decoded, *masterKey);
923 if (!targetAccountId)
935 if (email != confirmEmail)
947 TC_LOG_INFO(
"entities.player.character",
"ChangeEmail: Account {} [Id: {}] had it's email changed to {}.",
948 accountName, targetAccountId, email);
978 if (!targetAccountId)
990 if (email != confirmEmail)
1002 TC_LOG_INFO(
"entities.player.character",
"ChangeRegEmail: Account {} [Id: {}] had it's Registration Email changed to {}.",
1003 accountName, targetAccountId, email);
std::shared_ptr< PreparedResultSet > PreparedQueryResult
DatabaseWorkerPool< LoginDatabaseConnection > LoginDatabase
Accessor to the realm/login database.
@ LANG_ACCOUNT_ALREADY_EXIST
@ LANG_COMMAND_ACC_LOCK_COUNTRY_HELP
@ LANG_COMMAND_ACC_SET_2FA_HELP
@ LANG_ACCOUNT_USE_BNET_COMMANDS
@ LANG_2FA_SECRET_TOO_LONG
@ LANG_COMMAND_NOTCHANGEPASSWORD
@ LANG_COMMAND_ACCLOCKLOCKED
@ LANG_COMMAND_ACC_SET_SEC_REGMAIL_HELP
@ LANG_COMMAND_EMAIL_OUTPUT
@ LANG_ACCOUNT_PASS_TOO_LONG
@ LANG_COMMAND_ACC_EMAIL_HELP
@ LANG_ACCOUNT_LIST_EMPTY
@ LANG_YOU_CHANGE_SECURITY
@ LANG_COMMAND_ACC_2FA_REMOVE_HELP
@ LANG_2FA_SECRET_INVALID
@ LANG_COMMAND_WRONGOLDPASSWORD
@ LANG_ACCOUNT_NOT_DELETED_SQL_ERROR
@ LANG_ACCOUNT_LIST_HEADER
@ LANG_COMMAND_ACC_SET_ADDON_HELP
@ LANG_COMMAND_ACCOUNT_HELP
@ LANG_2FA_REMOVE_NEED_TOKEN
@ LANG_COMMAND_ACC_PASSWORD_HELP
@ LANG_COMMAND_WRONGEMAIL
@ LANG_COMMAND_ACC_ADDON_HELP
@ LANG_COMMAND_ACC_DELETE_HELP
@ LANG_COMMAND_ACCLOCKUNLOCKED
@ LANG_COMMAND_ACC_2FA_SETUP_HELP
@ LANG_COMMAND_ACC_CREATE_HELP
@ LANG_NEW_EMAILS_NOT_MATCH
@ LANG_ACCOUNT_NOT_CREATED_SQL_ERROR
@ LANG_2FA_COMMANDS_NOT_SETUP
@ LANG_2FA_SECRET_SET_COMPLETE
@ LANG_ACCOUNT_NOT_CREATED
@ LANG_COMMAND_NOTCHANGEEMAIL
@ LANG_YOURS_SECURITY_IS_LOW
@ LANG_NEW_PASSWORDS_NOT_MATCH
@ LANG_2FA_SECRET_SUGGESTION
@ LANG_OLD_EMAIL_IS_NEW_EMAIL
@ LANG_ACCOUNT_LIST_BAR_HEADER
@ LANG_2FA_SETUP_COMPLETE
@ LANG_COMMAND_ACC_SET_SEC_EMAIL_HELP
@ LANG_COMMAND_ACC_SET_PASSWORD_HELP
@ LANG_ACCOUNT_NOT_DELETED
@ LANG_COMMAND_ACC_SET_SECLEVEL_HELP
@ LANG_RBAC_EMAIL_REQUIRED
@ LANG_COMMAND_ACC_LOCK_IP_HELP
@ LANG_ACCOUNT_NAME_TOO_LONG
@ LANG_2FA_REMOVE_COMPLETE
@ LANG_COMMAND_ACC_ONLINELIST_HELP
#define TC_LOG_ERROR(filterType__,...)
#define TC_LOG_INFO(filterType__,...)
@ LOGIN_SEL_ACCOUNT_ACCESS_SECLEVEL_TEST
@ LOGIN_UPD_ACCOUNT_TOTP_SECRET
@ LOGIN_UPD_ACCOUNT_LOCK_COUNTRY
@ LOGIN_SEL_ACCOUNT_TOTP_SECRET
std::optional< T > Optional
Optional helper class to wrap optional values within.
bool Utf8ToUpperOnlyLatin(std::string &utf8String)
static AccountOpResult ChangeRegEmail(uint32 accountId, std::string newEmail)
static AccountOpResult DeleteAccount(uint32 accountId)
static AccountOpResult ChangeEmail(uint32 accountId, std::string newEmail)
static uint32 GetSecurity(uint32 accountId, int32 realmId)
static AccountOpResult ChangePassword(uint32 accountId, std::string newPassword)
static bool IsConsoleAccount(uint32 gmlevel)
static bool CheckPassword(std::string username, std::string password)
static bool CheckEmail(uint32 accountId, std::string newEmail)
static uint32 GetId(std::string_view username)
static bool GetName(uint32 accountId, std::string &name)
virtual bool HasPermission(uint32 permission) const
Player * getSelectedPlayer()
WorldSession * GetSession()
void PSendSysMessage(const char *fmt, Args &&... args)
void SetSentErrorMessage(bool val)
virtual void SendSysMessage(std::string_view str, bool escapeCharacters=false)
bool HasLowerSecurityAccount(WorldSession *target, uint32 account, bool strong=false)
Class used to access individual fields of database query result.
std::vector< uint8 > GetBinary() const
std::string ToString() const
static ObjectGuid GetGUID(Object const *o)
WorldSession * GetSession() const
void setUInt8(const uint8 index, const uint8 value)
void setBool(const uint8 index, const bool value)
void setBinary(const uint8 index, const std::vector< uint8 > &value)
void setUInt32(const uint8 index, const uint32 value)
void setNull(const uint8 index)
void setString(const uint8 index, const std::string &value)
static constexpr size_t IV_SIZE_BYTES
static constexpr size_t TAG_SIZE_BYTES
constexpr uint32 GetMapId() const
std::string const & GetName() const
Player session in the World.
AccountTypes GetSecurity() const
Player * GetPlayer() const
std::string const & GetAccountName() const
std::string const & GetRemoteAddress() const
uint32 GetAccountId() const
uint8 GetAccountExpansion() const
std::string const & GetPlayerName() const
static bool HandleAccountPasswordCommand(ChatHandler *handler, std::string const &oldPassword, std::string const &newPassword, std::string const &confirmPassword, Optional< std::string > const &confirmEmail)
static bool HandleAccount2FASetupCommand(ChatHandler *handler, Optional< uint32 > token)
ChatCommandTable GetCommands() const override
static bool HandleAccountCreateCommand(ChatHandler *handler, std::string const &accountName, std::string const &password, Optional< std::string > const &email)
Create an account.
static bool HandleAccountSetRegEmailCommand(ChatHandler *handler, std::string accountName, std::string const &email, std::string const &confirmEmail)
Change registration email for account.
static bool HandleAccountSetEmailCommand(ChatHandler *handler, std::string accountName, std::string const &email, std::string const &confirmEmail)
Set normal email for account.
static bool HandleAccountSetPasswordCommand(ChatHandler *handler, std::string accountName, std::string const &password, std::string const &confirmPassword)
Set password for account.
static bool HandleAccountSet2FACommand(ChatHandler *handler, std::string accountName, std::string secret)
static bool HandleAccountAddonCommand(ChatHandler *handler, uint8 expansion)
static bool HandleAccountOnlineListWithMapFilterCommand(ChatHandler *handler, uint32 mapId)
static bool HandleAccountEmailCommand(ChatHandler *handler, std::string const &oldEmail, std::string const &password, std::string const &email, std::string const &emailConfirm)
static bool HandleAccountOnlineListCommandWithParameters(ChatHandler *handler, Optional< std::string > ipAddress, Optional< uint32 > limit, Optional< uint32 > mapId, Optional< uint32 > zoneId)
static bool HandleAccountLockIpCommand(ChatHandler *handler, bool state)
static bool HandleAccount2FARemoveCommand(ChatHandler *handler, Optional< uint32 > token)
static bool HandleAccountOnlineListWithZoneFilterCommand(ChatHandler *handler, uint32 zoneId)
static bool HandleAccountOnlineListCommand(ChatHandler *handler)
Display info on users currently in the realm.
static bool HandleAccountOnlineListWithIpFilterCommand(ChatHandler *handler, std::string ipAddress)
static bool HandleAccountLockCountryCommand(ChatHandler *handler, bool state)
static bool HandleAccountSetAddonCommand(ChatHandler *handler, Optional< std::string > accountName, uint8 expansion)
Set/Unset the expansion level for an account.
static bool HandleAccountOnlineListWithLimitCommand(ChatHandler *handler, uint32 limit)
static bool HandleAccountDeleteCommand(ChatHandler *handler, std::string accountName)
static bool HandleAccountCommand(ChatHandler *handler)
static bool HandleAccountSetSecLevelCommand(ChatHandler *handler, Optional< std::string > accountName, uint8 securityLevel, Optional< int32 > realmId)
void AddSC_account_commandscript()
std::unordered_map< uint32, WorldSession * > SessionMap
@ CONFIG_ACC_PASSCHANGESEC
std::vector< ChatCommandBuilder > ChatCommandTable
void TC_COMMON_API GetRandomBytes(uint8 *buf, size_t len)
@ RBAC_PERM_MAY_CHECK_OWN_EMAIL
@ RBAC_PERM_COMMAND_ACCOUNT_DELETE
@ RBAC_PERM_COMMAND_ACCOUNT_2FA_REMOVE
@ RBAC_PERM_COMMAND_ACCOUNT_SET_ADDON
@ RBAC_PERM_COMMAND_ACCOUNT_SET_SECLEVEL
@ RBAC_PERM_COMMAND_ACCOUNT_ADDON
@ RBAC_PERM_COMMAND_ACCOUNT_ONLINE_LIST
@ RBAC_PERM_COMMAND_ACCOUNT
@ RBAC_PERM_COMMAND_ACCOUNT_2FA_SETUP
@ RBAC_PERM_COMMAND_ACCOUNT_CREATE
@ RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_EMAIL
@ RBAC_PERM_COMMAND_ACCOUNT_EMAIL
@ RBAC_PERM_COMMAND_ACCOUNT_PASSWORD
@ RBAC_PERM_COMMAND_ACCOUNT_LOCK_COUNTRY
@ RBAC_PERM_COMMAND_ACCOUNT_LOCK_IP
@ RBAC_PERM_COMMAND_ACCOUNT_SET_2FA
@ RBAC_PERM_COMMAND_ACCOUNT_SET_PASSWORD
@ RBAC_PERM_EMAIL_CONFIRM_FOR_PASS_CHANGE
@ RBAC_PERM_COMMAND_ACCOUNT_SET_SEC_REGMAIL
std::vector< uint8 > Secret
static bool ValidateToken(Secret const &key, uint32 token)
static constexpr size_t RECOMMENDED_SECRET_LENGTH
static Optional< std::vector< uint8 > > Decode(std::string_view data)
static std::string Encode(std::vector< uint8 > const &data)