Merge pull request #180 from Scrumplex/feat-msa-clientid-detection
Detect MSA Client ID change
This commit is contained in:
		| @@ -228,6 +228,18 @@ void LaunchController::login() { | ||||
|                 emitFailed(errorString); | ||||
|                 return; | ||||
|             } | ||||
|             case AccountState::Disabled: { | ||||
|                 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"), | ||||
|                         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( | ||||
|   | ||||
| @@ -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"); | ||||
|   | ||||
| @@ -47,6 +47,7 @@ enum class AccountState { | ||||
|     Offline, | ||||
|     Working, | ||||
|     Online, | ||||
|     Disabled, | ||||
|     Errored, | ||||
|     Expired, | ||||
|     Gone | ||||
| @@ -81,6 +82,7 @@ struct AccountData { | ||||
|     bool legacy = false; | ||||
|     bool canMigrateToMSA = false; | ||||
|  | ||||
|     QString msaClientID; | ||||
|     Katabasis::Token msaToken; | ||||
|     Katabasis::Token userToken; | ||||
|     Katabasis::Token xboxApiToken; | ||||
|   | ||||
| @@ -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"); | ||||
|                     } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -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. | ||||
|         } | ||||
|   | ||||
| @@ -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"; | ||||
|  | ||||
| @@ -48,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; | ||||
|         } | ||||
| @@ -57,6 +62,7 @@ void MSAStep::perform() { | ||||
|             m_oauth2->setExtraRequestParams(extraOpts); | ||||
|  | ||||
|             *m_data = AccountData(); | ||||
|             m_data->msaClientID = m_clientId; | ||||
|             m_oauth2->login(); | ||||
|             return; | ||||
|         } | ||||
|   | ||||
| @@ -29,4 +29,5 @@ private slots: | ||||
| private: | ||||
|     Katabasis::DeviceFlow *m_oauth2 = nullptr; | ||||
|     Action m_action; | ||||
|     QString m_clientId; | ||||
| }; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user