From 3b2d6cf76f135c60f9b9ab6197b298b711a2e8b1 Mon Sep 17 00:00:00 2001 From: Daniel Scalzi Date: Wed, 9 Feb 2022 20:52:57 -0500 Subject: [PATCH] Implement friendly display of error codes if Microsoft authentication fails. --- app/assets/js/authmanager.js | 82 +++++++++++++++---------------- app/assets/js/scripts/landing.js | 2 +- app/assets/js/scripts/login.js | 17 ++++++- app/assets/js/scripts/settings.js | 23 +++++++++ 4 files changed, 80 insertions(+), 44 deletions(-) diff --git a/app/assets/js/authmanager.js b/app/assets/js/authmanager.js index 4aa1b783..5ec85289 100644 --- a/app/assets/js/authmanager.js +++ b/app/assets/js/authmanager.js @@ -13,7 +13,7 @@ const ConfigManager = require('./configmanager') const { LoggerUtil } = require('helios-core') const { RestResponseStatus } = require('helios-core/common') const { MojangRestAPI, mojangErrorDisplayable, MojangErrorCode } = require('helios-core/mojang') -const { MicrosoftAuth } = require('helios-core/microsoft') +const { MicrosoftAuth, microsoftErrorDisplayable, MicrosoftErrorCode } = require('helios-core/microsoft') const { AZURE_CLIENT_ID } = require('./ipcconstants') const log = LoggerUtil.getLogger('AuthManager') @@ -71,48 +71,48 @@ const AUTH_MODE = { FULL: 0, MS_REFRESH: 1, MC_REFRESH: 2 } * @returns An object with all auth data. AccessToken object will be null when mode is MC_REFRESH. */ async function fullMicrosoftAuthFlow(entryCode, authMode) { + try { - let accessTokenRaw - let accessToken - if(authMode !== AUTH_MODE.MC_REFRESH) { - const accessTokenResponse = await MicrosoftAuth.getAccessToken(entryCode, authMode === AUTH_MODE.MS_REFRESH, AZURE_CLIENT_ID) - if(accessTokenResponse.responseStatus === RestResponseStatus.ERROR) { - // TODO Fail. - return // TODO + let accessTokenRaw + let accessToken + if(authMode !== AUTH_MODE.MC_REFRESH) { + const accessTokenResponse = await MicrosoftAuth.getAccessToken(entryCode, authMode === AUTH_MODE.MS_REFRESH, AZURE_CLIENT_ID) + if(accessTokenResponse.responseStatus === RestResponseStatus.ERROR) { + return Promise.reject(microsoftErrorDisplayable(accessTokenResponse.microsoftErrorCode)) + } + accessToken = accessTokenResponse.data + accessTokenRaw = accessToken.access_token + } else { + accessTokenRaw = entryCode } - accessToken = accessTokenResponse.data - accessTokenRaw = accessToken.access_token - } else { - accessTokenRaw = entryCode - } - - const xblResponse = await MicrosoftAuth.getXBLToken(accessTokenRaw) - if(xblResponse.responseStatus === RestResponseStatus.ERROR) { - // TODO Fail. - return // TODO - } - const xstsResonse = await MicrosoftAuth.getXSTSToken(xblResponse.data) - if(xstsResonse.responseStatus === RestResponseStatus.ERROR) { - // TODO Fail. - return // TODO - } - const mcTokenResponse = await MicrosoftAuth.getMCAccessToken(xstsResonse.data) - if(mcTokenResponse.responseStatus === RestResponseStatus.ERROR) { - // TODO Fail. - return // TODO - } - const mcProfileResponse = await MicrosoftAuth.getMCProfile(mcTokenResponse.data.access_token) - if(mcProfileResponse.responseStatus === RestResponseStatus.ERROR) { - // TODO Fail. - return // TODO - } - return { - accessToken, - accessTokenRaw, - xbl: xblResponse.data, - xsts: xstsResonse.data, - mcToken: mcTokenResponse.data, - mcProfile: mcProfileResponse.data + + const xblResponse = await MicrosoftAuth.getXBLToken(accessTokenRaw) + if(xblResponse.responseStatus === RestResponseStatus.ERROR) { + return Promise.reject(microsoftErrorDisplayable(xblResponse.microsoftErrorCode)) + } + const xstsResonse = await MicrosoftAuth.getXSTSToken(xblResponse.data) + if(xstsResonse.responseStatus === RestResponseStatus.ERROR) { + return Promise.reject(microsoftErrorDisplayable(xstsResonse.microsoftErrorCode)) + } + const mcTokenResponse = await MicrosoftAuth.getMCAccessToken(xstsResonse.data) + if(mcTokenResponse.responseStatus === RestResponseStatus.ERROR) { + return Promise.reject(microsoftErrorDisplayable(mcTokenResponse.microsoftErrorCode)) + } + const mcProfileResponse = await MicrosoftAuth.getMCProfile(mcTokenResponse.data.access_token) + if(mcProfileResponse.responseStatus === RestResponseStatus.ERROR) { + return Promise.reject(microsoftErrorDisplayable(mcProfileResponse.microsoftErrorCode)) + } + return { + accessToken, + accessTokenRaw, + xbl: xblResponse.data, + xsts: xstsResonse.data, + mcToken: mcTokenResponse.data, + mcProfile: mcProfileResponse.data + } + } catch(err) { + log.error(err) + return Promise.reject(microsoftErrorDisplayable(MicrosoftErrorCode.UNKNOWN)) } } diff --git a/app/assets/js/scripts/landing.js b/app/assets/js/scripts/landing.js index 41021f0a..c15896c8 100644 --- a/app/assets/js/scripts/landing.js +++ b/app/assets/js/scripts/landing.js @@ -10,7 +10,7 @@ const { MojangRestAPI, getServerStatus } = require('helios-core/mojang') // Internal Requirements const DiscordWrapper = require('./assets/js/discordwrapper') const ProcessBuilder = require('./assets/js/processbuilder') -const { RestResponseStatus } = require('helios-core/common') +const { RestResponseStatus, isDisplayableError } = require('helios-core/common') // Launch Elements const launch_content = document.getElementById('launch_content') diff --git a/app/assets/js/scripts/login.js b/app/assets/js/scripts/login.js index 4bc79b9d..724f09c4 100644 --- a/app/assets/js/scripts/login.js +++ b/app/assets/js/scripts/login.js @@ -214,13 +214,26 @@ loginButton.addEventListener('click', () => { }, 1000) }).catch((displayableError) => { loginLoading(false) - setOverlayContent(displayableError.title, displayableError.desc, Lang.queryJS('login.tryAgain')) + + let actualDisplayableError + if(isDisplayableError(displayableError)) { + msftLoginLogger.error('Error while logging in.', displayableError) + actualDisplayableError = displayableError + } else { + // Uh oh. + msftLoginLogger.error('Unhandled error during login.', displayableError) + actualDisplayableError = { + title: 'Unknown Error During Login', + desc: 'An unknown error has occurred. Please see the console for details.' + } + } + + setOverlayContent(actualDisplayableError.title, actualDisplayableError.desc, Lang.queryJS('login.tryAgain')) setOverlayHandler(() => { formDisabled(false) toggleOverlay(false) }) toggleOverlay(true) - loggerLogin.log('Error while logging in.', displayableError) }) }) \ No newline at end of file diff --git a/app/assets/js/scripts/settings.js b/app/assets/js/scripts/settings.js index 119c026b..7250dd37 100644 --- a/app/assets/js/scripts/settings.js +++ b/app/assets/js/scripts/settings.js @@ -397,6 +397,29 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => { prepareSettings() }) }) + .catch((displayableError) => { + + let actualDisplayableError + if(isDisplayableError(displayableError)) { + msftLoginLogger.error('Error while logging in.', displayableError) + actualDisplayableError = displayableError + } else { + // Uh oh. + msftLoginLogger.error('Unhandled error during login.', displayableError) + actualDisplayableError = { + title: 'Unknown Error During Login', + desc: 'An unknown error has occurred. Please see the console for details.' + } + } + + switchView(getCurrentView(), viewOnClose, 500, 500, () => { + setOverlayContent(actualDisplayableError.title, actualDisplayableError.desc, Lang.queryJS('login.tryAgain')) + setOverlayHandler(() => { + toggleOverlay(false) + }) + toggleOverlay(true) + }) + }) } } })