mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-12-22 11:42:14 -08:00
Compare commits
4 Commits
8b23847c29
...
3b2d6cf76f
Author | SHA1 | Date | |
---|---|---|---|
|
3b2d6cf76f | ||
|
47aaee5214 | ||
|
ce52b520ae | ||
|
d95e85aa40 |
@ -13,7 +13,7 @@ const ConfigManager = require('./configmanager')
|
|||||||
const { LoggerUtil } = require('helios-core')
|
const { LoggerUtil } = require('helios-core')
|
||||||
const { RestResponseStatus } = require('helios-core/common')
|
const { RestResponseStatus } = require('helios-core/common')
|
||||||
const { MojangRestAPI, mojangErrorDisplayable, MojangErrorCode } = require('helios-core/mojang')
|
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 { AZURE_CLIENT_ID } = require('./ipcconstants')
|
||||||
|
|
||||||
const log = LoggerUtil.getLogger('AuthManager')
|
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.
|
* @returns An object with all auth data. AccessToken object will be null when mode is MC_REFRESH.
|
||||||
*/
|
*/
|
||||||
async function fullMicrosoftAuthFlow(entryCode, authMode) {
|
async function fullMicrosoftAuthFlow(entryCode, authMode) {
|
||||||
|
try {
|
||||||
|
|
||||||
let accessTokenRaw
|
let accessTokenRaw
|
||||||
let accessToken
|
let accessToken
|
||||||
if(authMode !== AUTH_MODE.MC_REFRESH) {
|
if(authMode !== AUTH_MODE.MC_REFRESH) {
|
||||||
const accessTokenResponse = await MicrosoftAuth.getAccessToken(entryCode, authMode === AUTH_MODE.MS_REFRESH, AZURE_CLIENT_ID)
|
const accessTokenResponse = await MicrosoftAuth.getAccessToken(entryCode, authMode === AUTH_MODE.MS_REFRESH, AZURE_CLIENT_ID)
|
||||||
if(accessTokenResponse.responseStatus === RestResponseStatus.ERROR) {
|
if(accessTokenResponse.responseStatus === RestResponseStatus.ERROR) {
|
||||||
// TODO Fail.
|
return Promise.reject(microsoftErrorDisplayable(accessTokenResponse.microsoftErrorCode))
|
||||||
return // TODO
|
}
|
||||||
|
accessToken = accessTokenResponse.data
|
||||||
|
accessTokenRaw = accessToken.access_token
|
||||||
|
} else {
|
||||||
|
accessTokenRaw = entryCode
|
||||||
}
|
}
|
||||||
accessToken = accessTokenResponse.data
|
|
||||||
accessTokenRaw = accessToken.access_token
|
const xblResponse = await MicrosoftAuth.getXBLToken(accessTokenRaw)
|
||||||
} else {
|
if(xblResponse.responseStatus === RestResponseStatus.ERROR) {
|
||||||
accessTokenRaw = entryCode
|
return Promise.reject(microsoftErrorDisplayable(xblResponse.microsoftErrorCode))
|
||||||
}
|
}
|
||||||
|
const xstsResonse = await MicrosoftAuth.getXSTSToken(xblResponse.data)
|
||||||
const xblResponse = await MicrosoftAuth.getXBLToken(accessTokenRaw)
|
if(xstsResonse.responseStatus === RestResponseStatus.ERROR) {
|
||||||
if(xblResponse.responseStatus === RestResponseStatus.ERROR) {
|
return Promise.reject(microsoftErrorDisplayable(xstsResonse.microsoftErrorCode))
|
||||||
// TODO Fail.
|
}
|
||||||
return // TODO
|
const mcTokenResponse = await MicrosoftAuth.getMCAccessToken(xstsResonse.data)
|
||||||
}
|
if(mcTokenResponse.responseStatus === RestResponseStatus.ERROR) {
|
||||||
const xstsResonse = await MicrosoftAuth.getXSTSToken(xblResponse.data)
|
return Promise.reject(microsoftErrorDisplayable(mcTokenResponse.microsoftErrorCode))
|
||||||
if(xstsResonse.responseStatus === RestResponseStatus.ERROR) {
|
}
|
||||||
// TODO Fail.
|
const mcProfileResponse = await MicrosoftAuth.getMCProfile(mcTokenResponse.data.access_token)
|
||||||
return // TODO
|
if(mcProfileResponse.responseStatus === RestResponseStatus.ERROR) {
|
||||||
}
|
return Promise.reject(microsoftErrorDisplayable(mcProfileResponse.microsoftErrorCode))
|
||||||
const mcTokenResponse = await MicrosoftAuth.getMCAccessToken(xstsResonse.data)
|
}
|
||||||
if(mcTokenResponse.responseStatus === RestResponseStatus.ERROR) {
|
return {
|
||||||
// TODO Fail.
|
accessToken,
|
||||||
return // TODO
|
accessTokenRaw,
|
||||||
}
|
xbl: xblResponse.data,
|
||||||
const mcProfileResponse = await MicrosoftAuth.getMCProfile(mcTokenResponse.data.access_token)
|
xsts: xstsResonse.data,
|
||||||
if(mcProfileResponse.responseStatus === RestResponseStatus.ERROR) {
|
mcToken: mcTokenResponse.data,
|
||||||
// TODO Fail.
|
mcProfile: mcProfileResponse.data
|
||||||
return // TODO
|
}
|
||||||
}
|
} catch(err) {
|
||||||
return {
|
log.error(err)
|
||||||
accessToken,
|
return Promise.reject(microsoftErrorDisplayable(MicrosoftErrorCode.UNKNOWN))
|
||||||
accessTokenRaw,
|
|
||||||
xbl: xblResponse.data,
|
|
||||||
xsts: xstsResonse.data,
|
|
||||||
mcToken: mcTokenResponse.data,
|
|
||||||
mcProfile: mcProfileResponse.data
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,7 +10,7 @@ const { MojangRestAPI, getServerStatus } = require('helios-core/mojang')
|
|||||||
// Internal Requirements
|
// Internal Requirements
|
||||||
const DiscordWrapper = require('./assets/js/discordwrapper')
|
const DiscordWrapper = require('./assets/js/discordwrapper')
|
||||||
const ProcessBuilder = require('./assets/js/processbuilder')
|
const ProcessBuilder = require('./assets/js/processbuilder')
|
||||||
const { RestResponseStatus } = require('helios-core/common')
|
const { RestResponseStatus, isDisplayableError } = require('helios-core/common')
|
||||||
|
|
||||||
// Launch Elements
|
// Launch Elements
|
||||||
const launch_content = document.getElementById('launch_content')
|
const launch_content = document.getElementById('launch_content')
|
||||||
|
@ -214,13 +214,26 @@ loginButton.addEventListener('click', () => {
|
|||||||
}, 1000)
|
}, 1000)
|
||||||
}).catch((displayableError) => {
|
}).catch((displayableError) => {
|
||||||
loginLoading(false)
|
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(() => {
|
setOverlayHandler(() => {
|
||||||
formDisabled(false)
|
formDisabled(false)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
})
|
})
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
loggerLogin.log('Error while logging in.', displayableError)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
@ -1,9 +1,22 @@
|
|||||||
|
const loginOptionsCancelContainer = document.getElementById('loginOptionCancelContainer')
|
||||||
const loginOptionMicrosoft = document.getElementById('loginOptionMicrosoft')
|
const loginOptionMicrosoft = document.getElementById('loginOptionMicrosoft')
|
||||||
const loginOptionMojang = document.getElementById('loginOptionMojang')
|
const loginOptionMojang = document.getElementById('loginOptionMojang')
|
||||||
|
const loginOptionsCancelButton = document.getElementById('loginOptionCancelButton')
|
||||||
|
|
||||||
|
let loginOptionsCancellable = false
|
||||||
|
|
||||||
let loginOptionsViewOnLoginSuccess
|
let loginOptionsViewOnLoginSuccess
|
||||||
let loginOptionsViewOnLoginCancel
|
let loginOptionsViewOnLoginCancel
|
||||||
let loginOptionsViewOnCancel
|
let loginOptionsViewOnCancel
|
||||||
|
let loginOptionsViewCancelHandler
|
||||||
|
|
||||||
|
function loginOptionsCancelEnabled(val){
|
||||||
|
if(val){
|
||||||
|
$(loginOptionsCancelContainer).show()
|
||||||
|
} else {
|
||||||
|
$(loginOptionsCancelContainer).hide()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loginOptionMicrosoft.onclick = (e) => {
|
loginOptionMicrosoft.onclick = (e) => {
|
||||||
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
||||||
@ -21,4 +34,17 @@ loginOptionMojang.onclick = (e) => {
|
|||||||
loginViewOnCancel = loginOptionsViewOnLoginCancel
|
loginViewOnCancel = loginOptionsViewOnLoginCancel
|
||||||
loginCancelEnabled(true)
|
loginCancelEnabled(true)
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
loginOptionsCancelButton.onclick = (e) => {
|
||||||
|
switchView(getCurrentView(), loginOptionsViewOnCancel, 500, 500, () => {
|
||||||
|
// Clear login values (Mojang login)
|
||||||
|
// No cleanup needed for Microsoft.
|
||||||
|
loginUsername.value = ''
|
||||||
|
loginPassword.value = ''
|
||||||
|
if(loginOptionsViewCancelHandler != null){
|
||||||
|
loginOptionsViewCancelHandler()
|
||||||
|
loginOptionsViewCancelHandler = null
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
@ -197,6 +197,9 @@ document.getElementById('accountSelectConfirm').addEventListener('click', () =>
|
|||||||
const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
|
const authAcc = ConfigManager.setSelectedAccount(listings[i].getAttribute('uuid'))
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
updateSelectedAccount(authAcc)
|
updateSelectedAccount(authAcc)
|
||||||
|
if(getCurrentView() === VIEWS.settings) {
|
||||||
|
prepareSettings()
|
||||||
|
}
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
return
|
return
|
||||||
@ -207,6 +210,9 @@ document.getElementById('accountSelectConfirm').addEventListener('click', () =>
|
|||||||
const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
|
const authAcc = ConfigManager.setSelectedAccount(listings[0].getAttribute('uuid'))
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
updateSelectedAccount(authAcc)
|
updateSelectedAccount(authAcc)
|
||||||
|
if(getCurrentView() === VIEWS.settings) {
|
||||||
|
prepareSettings()
|
||||||
|
}
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
|
@ -397,6 +397,29 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
prepareSettings()
|
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)
|
||||||
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@ -445,7 +468,6 @@ function bindAuthAccountLogOut(){
|
|||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
processLogOut(val, isLastAccount)
|
processLogOut(val, isLastAccount)
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
switchView(getCurrentView(), VIEWS.login)
|
|
||||||
})
|
})
|
||||||
setDismissHandler(() => {
|
setDismissHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
@ -476,7 +498,6 @@ function processLogOut(val, isLastAccount){
|
|||||||
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
||||||
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGOUT, uuid, isLastAccount)
|
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGOUT, uuid, isLastAccount)
|
||||||
})
|
})
|
||||||
// TODO ADD LOGIC FOR LAST ACCOUNT - SAME AS SOLUTION FOR FIRST TIME LOGIN!
|
|
||||||
} else {
|
} else {
|
||||||
AuthManager.removeMojangAccount(uuid).then(() => {
|
AuthManager.removeMojangAccount(uuid).then(() => {
|
||||||
if(!isLastAccount && uuid === prevSelAcc.uuid){
|
if(!isLastAccount && uuid === prevSelAcc.uuid){
|
||||||
@ -485,6 +506,12 @@ function processLogOut(val, isLastAccount){
|
|||||||
updateSelectedAccount(selAcc)
|
updateSelectedAccount(selAcc)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
|
if(isLastAccount) {
|
||||||
|
loginOptionsCancelEnabled(false)
|
||||||
|
loginOptionsViewOnLoginSuccess = VIEWS.settings
|
||||||
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
|
switchView(getCurrentView(), VIEWS.loginOptions)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
$(parent).fadeOut(250, () => {
|
$(parent).fadeOut(250, () => {
|
||||||
parent.remove()
|
parent.remove()
|
||||||
@ -530,13 +557,21 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
|
|||||||
updateSelectedAccount(selAcc)
|
updateSelectedAccount(selAcc)
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
|
if(isLastAccount) {
|
||||||
|
loginOptionsCancelEnabled(false)
|
||||||
|
loginOptionsViewOnLoginSuccess = VIEWS.settings
|
||||||
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
|
switchView(getCurrentView(), VIEWS.loginOptions)
|
||||||
|
}
|
||||||
if(msAccDomElementCache) {
|
if(msAccDomElementCache) {
|
||||||
msAccDomElementCache.remove()
|
msAccDomElementCache.remove()
|
||||||
msAccDomElementCache = null
|
msAccDomElementCache = null
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
switchView(getCurrentView(), VIEWS.settings, 500, 500)
|
if(!isLastAccount) {
|
||||||
|
switchView(getCurrentView(), VIEWS.settings, 500, 500)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -88,8 +88,11 @@ function showMainUI(data){
|
|||||||
currentView = VIEWS.landing
|
currentView = VIEWS.landing
|
||||||
$(VIEWS.landing).fadeIn(1000)
|
$(VIEWS.landing).fadeIn(1000)
|
||||||
} else {
|
} else {
|
||||||
currentView = VIEWS.login
|
loginOptionsCancelEnabled(false)
|
||||||
$(VIEWS.login).fadeIn(1000)
|
loginOptionsViewOnLoginSuccess = VIEWS.landing
|
||||||
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
|
currentView = VIEWS.loginOptions
|
||||||
|
$(VIEWS.loginOptions).fadeIn(1000)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -331,20 +334,46 @@ async function validateSelectedAccount(){
|
|||||||
'Select Another Account'
|
'Select Another Account'
|
||||||
)
|
)
|
||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
document.getElementById('loginUsername').value = selectedAcc.username
|
|
||||||
validateEmail(selectedAcc.username)
|
const isMicrosoft = selectedAcc.type === 'microsoft'
|
||||||
loginViewOnSuccess = getCurrentView()
|
|
||||||
loginViewOnCancel = getCurrentView()
|
if(isMicrosoft) {
|
||||||
if(accLen > 0){
|
// Empty for now
|
||||||
loginViewCancelHandler = () => {
|
} else {
|
||||||
ConfigManager.addMojangAuthAccount(selectedAcc.uuid, selectedAcc.accessToken, selectedAcc.username, selectedAcc.displayName)
|
// Mojang
|
||||||
|
// For convenience, pre-populate the username of the account.
|
||||||
|
document.getElementById('loginUsername').value = selectedAcc.username
|
||||||
|
validateEmail(selectedAcc.username)
|
||||||
|
}
|
||||||
|
|
||||||
|
loginOptionsViewOnLoginSuccess = getCurrentView()
|
||||||
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
|
|
||||||
|
if(accLen > 0) {
|
||||||
|
loginOptionsViewOnCancel = getCurrentView()
|
||||||
|
loginOptionsViewCancelHandler = () => {
|
||||||
|
if(isMicrosoft) {
|
||||||
|
ConfigManager.addMicrosoftAuthAccount(
|
||||||
|
selectedAcc.uuid,
|
||||||
|
selectedAcc.accessToken,
|
||||||
|
selectedAcc.username,
|
||||||
|
selectedAcc.expiresAt,
|
||||||
|
selectedAcc.microsoft.access_token,
|
||||||
|
selectedAcc.microsoft.refresh_token,
|
||||||
|
selectedAcc.microsoft.expires_at
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
ConfigManager.addMojangAuthAccount(selectedAcc.uuid, selectedAcc.accessToken, selectedAcc.username, selectedAcc.displayName)
|
||||||
|
}
|
||||||
ConfigManager.save()
|
ConfigManager.save()
|
||||||
validateSelectedAccount()
|
validateSelectedAccount()
|
||||||
}
|
}
|
||||||
loginCancelEnabled(true)
|
loginOptionsCancelEnabled(true)
|
||||||
|
} else {
|
||||||
|
loginOptionsCancelEnabled(false)
|
||||||
}
|
}
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
switchView(getCurrentView(), VIEWS.login)
|
switchView(getCurrentView(), VIEWS.loginOptions)
|
||||||
})
|
})
|
||||||
setDismissHandler(() => {
|
setDismissHandler(() => {
|
||||||
if(accLen > 1){
|
if(accLen > 1){
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
* Script for welcome.ejs
|
* Script for welcome.ejs
|
||||||
*/
|
*/
|
||||||
document.getElementById('welcomeButton').addEventListener('click', e => {
|
document.getElementById('welcomeButton').addEventListener('click', e => {
|
||||||
|
loginOptionsCancelEnabled(false) // False by default, be explicit.
|
||||||
loginOptionsViewOnLoginSuccess = VIEWS.landing
|
loginOptionsViewOnLoginSuccess = VIEWS.landing
|
||||||
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
switchView(VIEWS.welcome, VIEWS.loginOptions)
|
switchView(VIEWS.welcome, VIEWS.loginOptions)
|
||||||
|
Loading…
Reference in New Issue
Block a user