42#include <unordered_map>
51 std::span<ChatCommandBuilder const>
GetCommands()
const override
79 {
"onlinelist", accountOnlinelistCommandTable },
82 {
"set", accountSetCommandTable },
88 {
"account", accountCommandTable },
96 if (!masterKey.IsAvailable())
112 TC_LOG_ERROR(
"misc",
"Account {} not found in login database when processing .account 2fa setup command.", accountId);
118 if (!result->Fetch()->IsNull())
127 static std::unordered_map<uint32, Trinity::Crypto::TOTP::Secret> suggestions;
132 if (!pair.second && token)
137 Trinity::Crypto::AEEncryptWithRandomIV<Trinity::Crypto::AES>(pair.first->second, *masterKey);
143 suggestions.erase(pair.first);
160 if (!masterKey.IsAvailable())
176 TC_LOG_ERROR(
"misc",
"Account {} not found in login database when processing .account 2fa setup command.", accountId);
182 Field* field = result->Fetch();
197 bool success = Trinity::Crypto::AEDecrypt<Trinity::Crypto::AES>(secret, *masterKey);
200 TC_LOG_ERROR(
"misc",
"Account {} has invalid ciphertext in TOTP token.", accountId);
248 if (accountName.find(
'@') != std::string::npos)
255 switch (
sAccountMgr->CreateAccount(accountName, password, email.value_or(
"")))
261 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {}) created Account {} (Email: '{}')",
264 accountName, email.value_or(
""));
368 size_t sessionsMatchCount = 0;
371 for (SessionMap::value_type
const& sessionPair : sessionsMap)
388 if (mapId && *mapId != playerMapId)
392 if (zoneId && *zoneId != playerZoneId)
395 if (!sessionsMatchCount)
412 ++sessionsMatchCount;
415 if (limit && sessionsMatchCount >= limit)
420 if (!sessionsMatchCount)
437 stmt->
setString(0, location->CountryCode);
444 handler->
PSendSysMessage(
"No IP2Location information - account not locked");
488 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the provided email [{}] is not equal to registration email [{}].",
500 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the provided password is wrong.",
506 if (email == oldEmail)
514 if (email != emailConfirm)
519 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change email, but the confirm email does not match.",
531 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Changed Email from [{}] to [{}].",
561 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change password, but the provided old password is wrong.",
574 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} Tried to change password, but the entered email [{}] is wrong.",
577 confirmEmail.value_or(
""));
582 if (newPassword != confirmPassword)
597 TC_LOG_INFO(
"entities.player.character",
"Account: {} (IP: {}) Character:[{}] {} changed password.",
626 pwConfig ==
PW_EMAIL ?
"Highest level: Email input required." :
627 pwConfig ==
PW_RBAC ?
"Special level: Your account may require email input depending on settings. That is the case if another line is printed." :
628 "Unknown security level: Config error?"));
728 accountName.emplace();
752 if (targetSecurity >= playerSecurity || securityLevel >= playerSecurity)
785 sAccountMgr->UpdateAccountAccess(
nullptr, accountId, securityLevel, realmID);
802 if (!targetAccountId)
814 if (password != confirmPassword)
853 if (!targetAccountId)
874 if (!masterKey.IsAvailable())
896 Trinity::Crypto::AEEncryptWithRandomIV<Trinity::Crypto::AES>(*decoded, *masterKey);
917 if (!targetAccountId)
929 if (email != confirmEmail)
941 TC_LOG_INFO(
"entities.player.character",
"ChangeEmail: Account {} [Id: {}] had it's email changed to {}.",
942 accountName, targetAccountId, email);
972 if (!targetAccountId)
984 if (email != confirmEmail)
996 TC_LOG_INFO(
"entities.player.character",
"ChangeRegEmail: Account {} [Id: {}] had it's Registration Email changed to {}.",
997 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__, message__,...)
#define TC_LOG_INFO(filterType__, message__,...)
@ 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)
ObjectGuid const & GetGUID() const
virtual bool HasPermission(uint32 permission) const
Player * getSelectedPlayer()
WorldSession * GetSession()
void SetSentErrorMessage(bool val)
void PSendSysMessage(char const *fmt, Args &&... args)
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 noexcept
bool IsNull() const noexcept
std::string ToString() const
WorldSession * GetSession() const
void setBinary(uint8 index, std::vector< uint8 > &&value)
void setString(uint8 index, std::string &&value)
void setUInt32(uint8 index, uint32 value)
void setBool(uint8 index, bool value)
void setUInt8(uint8 index, uint8 value)
void setNull(uint8 index)
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 HandleAccountSetAddonCommand(ChatHandler *handler, Optional< std::string > &accountName, uint8 expansion)
Set/Unset the expansion level for an account.
static bool HandleAccountOnlineListCommandWithParameters(ChatHandler *handler, Optional< std::string_view > const &ipAddress, Optional< uint32 > limit, Optional< uint32 > mapId, Optional< uint32 > zoneId)
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)
static bool HandleAccountCreateCommand(ChatHandler *handler, std::string const &accountName, std::string const &password, Optional< std::string > const &email)
Create an account.
static bool HandleAccountSetSecLevelCommand(ChatHandler *handler, Optional< std::string > &accountName, uint8 securityLevel, Optional< int32 > realmId)
static bool HandleAccountSet2FACommand(ChatHandler *handler, std::string &accountName, std::string_view secret)
static bool HandleAccountSetPasswordCommand(ChatHandler *handler, std::string &accountName, std::string const &password, std::string const &confirmPassword)
Set password for account.
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 HandleAccountLockIpCommand(ChatHandler *handler, bool state)
static bool HandleAccount2FARemoveCommand(ChatHandler *handler, Optional< uint32 > token)
static bool HandleAccountSetEmailCommand(ChatHandler *handler, std::string &accountName, std::string const &email, std::string const &confirmEmail)
Set normal email for account.
static bool HandleAccountOnlineListWithZoneFilterCommand(ChatHandler *handler, uint32 zoneId)
std::span< ChatCommandBuilder const > GetCommands() const override
static bool HandleAccountOnlineListCommand(ChatHandler *handler)
Display info on users currently in the realm.
static bool HandleAccountLockCountryCommand(ChatHandler *handler, bool state)
static bool HandleAccountOnlineListWithLimitCommand(ChatHandler *handler, uint32 limit)
static bool HandleAccountOnlineListWithIpFilterCommand(ChatHandler *handler, std::string_view ipAddress)
static bool HandleAccountCommand(ChatHandler *handler)
static bool HandleAccountDeleteCommand(ChatHandler *handler, std::string &accountName)
static bool HandleAccountSetRegEmailCommand(ChatHandler *handler, std::string &accountName, std::string const &email, std::string const &confirmEmail)
Change registration email for account.
void AddSC_account_commandscript()
std::unordered_map< uint32, WorldSession * > SessionMap
@ CONFIG_ACC_PASSCHANGESEC
ChatCommandBuilder const [] ChatCommandTable
std::array< uint8, S > GetRandomBytes()
@ 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)