From be910374dc81225863a55c1ada23074b0cb5f219 Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 18 Feb 2022 12:25:26 +0100 Subject: [PATCH 1/5] feat(accounts): support msa-client-id value --- launcher/minecraft/auth/AccountData.cpp | 5 +++++ launcher/minecraft/auth/AccountData.h | 1 + 2 files changed, 6 insertions(+) diff --git a/launcher/minecraft/auth/AccountData.cpp b/launcher/minecraft/auth/AccountData.cpp index 9b84fe1a..f791db14 100644 --- a/launcher/minecraft/auth/AccountData.cpp +++ b/launcher/minecraft/auth/AccountData.cpp @@ -327,6 +327,10 @@ bool AccountData::resumeStateFromV3(QJsonObject data) { } if(type == AccountType::MSA) { + auto clientIDV = data.value("msa-client-id"); + if (clientIDV.isString()) { + msaClientID = clientIDV.toString(); + } // leave msaClientID empty if it doesn't exist or isn't a string msaToken = tokenFromJSONV3(data, "msa"); userToken = tokenFromJSONV3(data, "utoken"); xboxApiToken = tokenFromJSONV3(data, "xrp-main"); @@ -360,6 +364,7 @@ QJsonObject AccountData::saveState() const { } else if (type == AccountType::MSA) { output["type"] = "MSA"; + output["msa-client-id"] = msaClientID; tokenToJSONV3(output, msaToken, "msa"); tokenToJSONV3(output, userToken, "utoken"); tokenToJSONV3(output, xboxApiToken, "xrp-main"); diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index 606c1ad1..1b6867de 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -81,6 +81,7 @@ struct AccountData { bool legacy = false; bool canMigrateToMSA = false; + QString msaClientID; Katabasis::Token msaToken; Katabasis::Token userToken; Katabasis::Token xboxApiToken; From 9c71f364d25df5a992c7067ecfca2e095abcc20f Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 18 Feb 2022 12:26:52 +0100 Subject: [PATCH 2/5] feat(accounts): add disabled account state --- launcher/LaunchController.cpp | 12 ++++++++++++ launcher/minecraft/auth/AccountData.h | 1 + launcher/minecraft/auth/AccountList.cpp | 3 +++ launcher/minecraft/auth/AccountTask.cpp | 8 ++++++++ launcher/minecraft/auth/AccountTask.h | 1 + launcher/minecraft/auth/MinecraftAccount.cpp | 3 +++ 6 files changed, 28 insertions(+) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 32fc99cb..11419358 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -228,6 +228,18 @@ void LaunchController::login() { emitFailed(errorString); return; } + case AccountState::Disabled: { + auto errorString = tr("The launcher's client identification changed. Please remove this account and add it again."); + QMessageBox::warning( + m_parentWidget, + tr("Client identification changed"), + errorString, + QMessageBox::StandardButton::Ok, + QMessageBox::StandardButton::Ok + ); + emitFailed(errorString); + return; + } case AccountState::Gone: { auto errorString = tr("The account no longer exists on the servers. It may have been migrated, in which case please add the new account you migrated this one to."); QMessageBox::warning( diff --git a/launcher/minecraft/auth/AccountData.h b/launcher/minecraft/auth/AccountData.h index 1b6867de..6749a471 100644 --- a/launcher/minecraft/auth/AccountData.h +++ b/launcher/minecraft/auth/AccountData.h @@ -47,6 +47,7 @@ enum class AccountState { Offline, Working, Online, + Disabled, Errored, Expired, Gone diff --git a/launcher/minecraft/auth/AccountList.cpp b/launcher/minecraft/auth/AccountList.cpp index 04470e1c..e404cdda 100644 --- a/launcher/minecraft/auth/AccountList.cpp +++ b/launcher/minecraft/auth/AccountList.cpp @@ -291,6 +291,9 @@ QVariant AccountList::data(const QModelIndex &index, int role) const case AccountState::Expired: { return tr("Expired", "Account status"); } + case AccountState::Disabled: { + return tr("Disabled", "Account status"); + } case AccountState::Gone: { return tr("Gone", "Account status"); } diff --git a/launcher/minecraft/auth/AccountTask.cpp b/launcher/minecraft/auth/AccountTask.cpp index 98d8d94d..321b350f 100644 --- a/launcher/minecraft/auth/AccountTask.cpp +++ b/launcher/minecraft/auth/AccountTask.cpp @@ -43,6 +43,8 @@ QString AccountTask::getStateMessage() const return tr("Authentication task succeeded."); case AccountTaskState::STATE_OFFLINE: return tr("Failed to contact the authentication server."); + case AccountTaskState::STATE_DISABLED: + return tr("Client ID has changed. New session needs to be created."); case AccountTaskState::STATE_FAILED_SOFT: return tr("Encountered an error during authentication."); case AccountTaskState::STATE_FAILED_HARD: @@ -78,6 +80,12 @@ bool AccountTask::changeState(AccountTaskState newState, QString reason) emitFailed(reason); return false; } + case AccountTaskState::STATE_DISABLED: { + m_data->errorString = reason; + m_data->accountState = AccountState::Disabled; + emitFailed(reason); + return false; + } case AccountTaskState::STATE_FAILED_SOFT: { m_data->errorString = reason; m_data->accountState = AccountState::Errored; diff --git a/launcher/minecraft/auth/AccountTask.h b/launcher/minecraft/auth/AccountTask.h index dac3f1b5..c2a5d86c 100644 --- a/launcher/minecraft/auth/AccountTask.h +++ b/launcher/minecraft/auth/AccountTask.h @@ -35,6 +35,7 @@ enum class AccountTaskState STATE_CREATED, STATE_WORKING, STATE_SUCCEEDED, + STATE_DISABLED, //!< MSA Client ID has changed. Tell user to reloginn STATE_FAILED_SOFT, //!< soft failure. authentication went through partially STATE_FAILED_HARD, //!< hard failure. main tokens are invalid STATE_FAILED_GONE, //!< hard failure. main tokens are invalid, and the account no longer exists diff --git a/launcher/minecraft/auth/MinecraftAccount.cpp b/launcher/minecraft/auth/MinecraftAccount.cpp index ffc81ed8..a604cadf 100644 --- a/launcher/minecraft/auth/MinecraftAccount.cpp +++ b/launcher/minecraft/auth/MinecraftAccount.cpp @@ -176,6 +176,9 @@ void MinecraftAccount::authFailed(QString reason) { switch (m_currentTask->taskState()) { case AccountTaskState::STATE_OFFLINE: + case AccountTaskState::STATE_DISABLED: { + // NOTE: user will need to fix this themselves. + } case AccountTaskState::STATE_FAILED_SOFT: { // NOTE: this doesn't do much. There was an error of some sort. } From 14717396eb9be5f14b23a1af50e1379e66cfaf3c Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 18 Feb 2022 12:27:34 +0100 Subject: [PATCH 3/5] feat(accounts): save client id in MSAStep --- launcher/minecraft/auth/steps/MSAStep.cpp | 4 +++- launcher/minecraft/auth/steps/MSAStep.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 779aee43..7d28c2c8 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -12,9 +12,10 @@ using OAuth2 = Katabasis::DeviceFlow; using Activity = Katabasis::Activity; MSAStep::MSAStep(AccountData* data, Action action) : AuthStep(data), m_action(action) { + m_clientId = APPLICATION->getMSAClientID(); OAuth2::Options opts; opts.scope = "XboxLive.signin offline_access"; - opts.clientIdentifier = APPLICATION->getMSAClientID(); + opts.clientIdentifier = m_clientId; opts.authorizationUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/devicecode"; opts.accessTokenUrl = "https://login.microsoftonline.com/consumers/oauth2/v2.0/token"; @@ -57,6 +58,7 @@ void MSAStep::perform() { m_oauth2->setExtraRequestParams(extraOpts); *m_data = AccountData(); + m_data->msaClientID = m_clientId; m_oauth2->login(); return; } diff --git a/launcher/minecraft/auth/steps/MSAStep.h b/launcher/minecraft/auth/steps/MSAStep.h index 49ba3542..301e1465 100644 --- a/launcher/minecraft/auth/steps/MSAStep.h +++ b/launcher/minecraft/auth/steps/MSAStep.h @@ -29,4 +29,5 @@ private slots: private: Katabasis::DeviceFlow *m_oauth2 = nullptr; Action m_action; + QString m_clientId; }; From c5d9944993832f16e76a9a63a402665c5321267b Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 18 Feb 2022 12:27:57 +0100 Subject: [PATCH 4/5] feat(accounts): interrupt MSAStep when client ID doesn't match --- launcher/minecraft/auth/steps/MSAStep.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/launcher/minecraft/auth/steps/MSAStep.cpp b/launcher/minecraft/auth/steps/MSAStep.cpp index 7d28c2c8..207d9373 100644 --- a/launcher/minecraft/auth/steps/MSAStep.cpp +++ b/launcher/minecraft/auth/steps/MSAStep.cpp @@ -49,6 +49,10 @@ void MSAStep::rehydrate() { void MSAStep::perform() { switch(m_action) { case Refresh: { + if (m_data->msaClientID != m_clientId) { + emit hideVerificationUriAndCode(); + emit finished(AccountTaskState::STATE_DISABLED, tr("Microsoft user authentication failed - client identification has changed.")); + } m_oauth2->refresh(); return; } From 80a29af497bec487f87a9ae545a2f94c3685f6df Mon Sep 17 00:00:00 2001 From: Sefa Eyeoglu Date: Fri, 18 Feb 2022 19:18:29 +0100 Subject: [PATCH 5/5] fix: typo for account disabled error messages --- launcher/LaunchController.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/launcher/LaunchController.cpp b/launcher/LaunchController.cpp index 11419358..40178b70 100644 --- a/launcher/LaunchController.cpp +++ b/launcher/LaunchController.cpp @@ -229,7 +229,7 @@ void LaunchController::login() { return; } case AccountState::Disabled: { - auto errorString = tr("The launcher's client identification changed. Please remove this account and add it again."); + auto errorString = tr("The launcher's client identification has changed. Please remove this account and add it again."); QMessageBox::warning( m_parentWidget, tr("Client identification changed"),