mirror of
https://github.com/dscalzi/HeliosLauncher.git
synced 2024-12-22 19:52:14 -08:00
Compare commits
4 Commits
2ce437416b
...
af5147ceec
Author | SHA1 | Date | |
---|---|---|---|
|
af5147ceec | ||
|
e6cf76b436 | ||
|
5fb312628a | ||
|
a818628e46 |
@ -233,5 +233,4 @@ loginButton.addEventListener('click', () => {
|
|||||||
})
|
})
|
||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
})
|
})
|
@ -353,8 +353,9 @@ document.getElementById('settingsAddMojangAccount').onclick = (e) => {
|
|||||||
|
|
||||||
// Bind the add microsoft account button.
|
// Bind the add microsoft account button.
|
||||||
document.getElementById('settingsAddMicrosoftAccount').onclick = (e) => {
|
document.getElementById('settingsAddMicrosoftAccount').onclick = (e) => {
|
||||||
|
document.getElementById("waitingText").innerHTML = "Please login in the window that has just opened"
|
||||||
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
||||||
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGIN, VIEWS.settings, VIEWS.settings)
|
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGIN, VIEWS.landing, VIEWS.settings)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,6 +385,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
toggleOverlay(true)
|
toggleOverlay(true)
|
||||||
})
|
})
|
||||||
} else if (arguments_[0] === MSFT_REPLY_TYPE.SUCCESS) {
|
} else if (arguments_[0] === MSFT_REPLY_TYPE.SUCCESS) {
|
||||||
|
document.getElementById("waitingText").innerHTML = "Retrieving your account information from Microsoft"
|
||||||
const queryMap = arguments_[1]
|
const queryMap = arguments_[1]
|
||||||
const viewOnClose = arguments_[2]
|
const viewOnClose = arguments_[2]
|
||||||
|
|
||||||
@ -406,7 +408,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
setOverlayHandler(() => {
|
setOverlayHandler(() => {
|
||||||
toggleOverlay(false)
|
toggleOverlay(false)
|
||||||
})
|
})
|
||||||
toggleOverlay(true)
|
if (errorDesc !== "The user has denied access to the scope requested by the client application.") toggleOverlay(true)//If the user clicks "Back" button and closes the window
|
||||||
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -415,6 +417,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
|
|||||||
|
|
||||||
const authCode = queryMap.code
|
const authCode = queryMap.code
|
||||||
AuthManager.addMicrosoftAccount(authCode).then(value => {
|
AuthManager.addMicrosoftAccount(authCode).then(value => {
|
||||||
|
document.getElementById("waitingText").innerHTML = "Finished"
|
||||||
updateSelectedAccount(value)
|
updateSelectedAccount(value)
|
||||||
switchView(getCurrentView(), viewOnClose, 500, 500, async () => {
|
switchView(getCurrentView(), viewOnClose, 500, 500, async () => {
|
||||||
await prepareSettings()
|
await prepareSettings()
|
||||||
@ -519,6 +522,7 @@ function processLogOut(val, isLastAccount){
|
|||||||
if(targetAcc.type === 'microsoft') {
|
if(targetAcc.type === 'microsoft') {
|
||||||
msAccDomElementCache = parent
|
msAccDomElementCache = parent
|
||||||
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
|
||||||
|
document.getElementById("waitingText").innerHTML = "Removing your Microsoft account from the launcher" //We actually don't have to wait anything from Mirosoft
|
||||||
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGOUT, uuid, isLastAccount)
|
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGOUT, uuid, isLastAccount)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@ -529,16 +533,16 @@ 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()
|
||||||
})
|
})
|
||||||
|
})
|
||||||
|
if (isLastAccount) {
|
||||||
|
loginOptionsCancelEnabled(false)
|
||||||
|
loginOptionsViewOnLoginSuccess = VIEWS.landing
|
||||||
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
|
switchView(getCurrentView(), VIEWS.loginOptions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -582,7 +586,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
|
|||||||
}
|
}
|
||||||
if(isLastAccount) {
|
if(isLastAccount) {
|
||||||
loginOptionsCancelEnabled(false)
|
loginOptionsCancelEnabled(false)
|
||||||
loginOptionsViewOnLoginSuccess = VIEWS.settings
|
loginOptionsViewOnLoginSuccess = VIEWS.landing
|
||||||
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
|
||||||
switchView(getCurrentView(), VIEWS.loginOptions)
|
switchView(getCurrentView(), VIEWS.loginOptions)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<div id="waitingContent">
|
<div id="waitingContent">
|
||||||
<div class="waitingSpinner"></div>
|
<div class="waitingSpinner"></div>
|
||||||
<div id="waitingTextContainer">
|
<div id="waitingTextContainer">
|
||||||
<h2>Waiting for Microsoft..</h2>
|
<h2 id="waitingText">Waiting for Microsoft..</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
@ -18,18 +18,35 @@ Authenticating with Microsoft is fully supported by Helios Launcher.
|
|||||||
- Select **Mobile and desktop applications**.
|
- Select **Mobile and desktop applications**.
|
||||||
- Choose `https://login.microsoftonline.com/common/oauth2/nativeclient` as the **Redirect URI**.
|
- Choose `https://login.microsoftonline.com/common/oauth2/nativeclient` as the **Redirect URI**.
|
||||||
- Select **Configure** to finish adding the platform.
|
- Select **Configure** to finish adding the platform.
|
||||||
|
8. Go to **Credentials & secrets**.
|
||||||
|
- Select **Client secrets**.
|
||||||
|
- Click **New client secret**.
|
||||||
|
- Set a description.
|
||||||
|
- Click **Add**.
|
||||||
|
- Don't copy the client secret, adding one is just a requirement from Microsoft.
|
||||||
8. Navigate back to **Overview**.
|
8. Navigate back to **Overview**.
|
||||||
9. Copy **Application (client) ID**.
|
9. Copy **Application (client) ID**.
|
||||||
|
|
||||||
|
|
||||||
Reference: https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
|
|
||||||
|
|
||||||
## Adding the Azure Client ID to Helios Launcher.
|
## Adding the Azure Client ID to Helios Launcher.
|
||||||
|
|
||||||
In `app/assets/js/ipcconstants.js` you'll find **`AZURE_CLIENT_ID`**. Set it to your application's id.
|
In `app/assets/js/ipcconstants.js` you'll find **`AZURE_CLIENT_ID`**. Set it to your application's id.
|
||||||
|
|
||||||
Note: Azure Client ID is NOT a secret value and **can** be stored in git. Reference: https://stackoverflow.com/questions/57306964/are-azure-active-directorys-tenantid-and-clientid-considered-secrets
|
Note: Azure Client ID is NOT a secret value and **can** be stored in git. Reference: https://stackoverflow.com/questions/57306964/are-azure-active-directorys-tenantid-and-clientid-considered-secrets
|
||||||
|
|
||||||
|
Then relaunch your app, and login. You'll be greeted with an error message, because the app isn't whitelisted yet. Microsoft needs some activity on the app before whitelisting it. __Trying to log in before requesting whitelist is mandatory.__
|
||||||
|
|
||||||
|
## Requesting whitelisting from Microsoft
|
||||||
|
|
||||||
|
1. Ensure you have completed every step of this doc page.
|
||||||
|
2. Fill [this form](https://aka.ms/mce-reviewappid) with the required information. Remember this is a new appID for approval. You can find both the Client ID and the Tenant ID on the overview page in the Azure Portal.
|
||||||
|
3. Give Microsoft some time to review your app.
|
||||||
|
4. Once you have received Microsoft's approval, allow up to 24 hours for the changes to apply.
|
||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
You can now authenticate with Microsoft through the launcher.
|
You can now authenticate with Microsoft through the launcher.
|
||||||
|
|
||||||
|
References:
|
||||||
|
- https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app
|
||||||
|
- https://help.minecraft.net/hc/en-us/articles/16254801392141
|
191
index.js
191
index.js
@ -105,116 +105,8 @@ ipcMain.handle(SHELL_OPCODE.TRASH_ITEM, async (event, ...args) => {
|
|||||||
app.disableHardwareAcceleration()
|
app.disableHardwareAcceleration()
|
||||||
|
|
||||||
|
|
||||||
const REDIRECT_URI_PREFIX = 'https://login.microsoftonline.com/common/oauth2/nativeclient?'
|
|
||||||
|
|
||||||
// Microsoft Auth Login
|
|
||||||
let msftAuthWindow
|
|
||||||
let msftAuthSuccess
|
|
||||||
let msftAuthViewSuccess
|
|
||||||
let msftAuthViewOnClose
|
|
||||||
ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
|
|
||||||
if (msftAuthWindow) {
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN, msftAuthViewOnClose)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
msftAuthSuccess = false
|
|
||||||
msftAuthViewSuccess = arguments_[0]
|
|
||||||
msftAuthViewOnClose = arguments_[1]
|
|
||||||
msftAuthWindow = new BrowserWindow({
|
|
||||||
title: 'Microsoft Login',
|
|
||||||
backgroundColor: '#222222',
|
|
||||||
width: 520,
|
|
||||||
height: 600,
|
|
||||||
frame: true,
|
|
||||||
icon: getPlatformIcon('SealCircle')
|
|
||||||
})
|
|
||||||
|
|
||||||
msftAuthWindow.on('closed', () => {
|
|
||||||
msftAuthWindow = undefined
|
|
||||||
})
|
|
||||||
|
|
||||||
msftAuthWindow.on('close', () => {
|
|
||||||
if(!msftAuthSuccess) {
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED, msftAuthViewOnClose)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
msftAuthWindow.webContents.on('did-navigate', (_, uri) => {
|
|
||||||
if (uri.startsWith(REDIRECT_URI_PREFIX)) {
|
|
||||||
let queries = uri.substring(REDIRECT_URI_PREFIX.length).split('#', 1).toString().split('&')
|
|
||||||
let queryMap = {}
|
|
||||||
|
|
||||||
queries.forEach(query => {
|
|
||||||
const [name, value] = query.split('=')
|
|
||||||
queryMap[name] = decodeURI(value)
|
|
||||||
})
|
|
||||||
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.SUCCESS, queryMap, msftAuthViewSuccess)
|
|
||||||
|
|
||||||
msftAuthSuccess = true
|
|
||||||
msftAuthWindow.close()
|
|
||||||
msftAuthWindow = null
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
msftAuthWindow.removeMenu()
|
|
||||||
msftAuthWindow.loadURL(`https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?prompt=select_account&client_id=${AZURE_CLIENT_ID}&response_type=code&scope=XboxLive.signin%20offline_access&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient`)
|
|
||||||
})
|
|
||||||
|
|
||||||
// Microsoft Auth Logout
|
|
||||||
let msftLogoutWindow
|
|
||||||
let msftLogoutSuccess
|
|
||||||
let msftLogoutSuccessSent
|
|
||||||
ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
|
|
||||||
if (msftLogoutWindow) {
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
msftLogoutSuccess = false
|
|
||||||
msftLogoutSuccessSent = false
|
|
||||||
msftLogoutWindow = new BrowserWindow({
|
|
||||||
title: 'Microsoft Logout',
|
|
||||||
backgroundColor: '#222222',
|
|
||||||
width: 520,
|
|
||||||
height: 600,
|
|
||||||
frame: true,
|
|
||||||
icon: getPlatformIcon('SealCircle')
|
|
||||||
})
|
|
||||||
|
|
||||||
msftLogoutWindow.on('closed', () => {
|
|
||||||
msftLogoutWindow = undefined
|
|
||||||
})
|
|
||||||
|
|
||||||
msftLogoutWindow.on('close', () => {
|
|
||||||
if(!msftLogoutSuccess) {
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED)
|
|
||||||
} else if(!msftLogoutSuccessSent) {
|
|
||||||
msftLogoutSuccessSent = true
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.SUCCESS, uuid, isLastAccount)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
msftLogoutWindow.webContents.on('did-navigate', (_, uri) => {
|
|
||||||
if(uri.startsWith('https://login.microsoftonline.com/common/oauth2/v2.0/logoutsession')) {
|
|
||||||
msftLogoutSuccess = true
|
|
||||||
setTimeout(() => {
|
|
||||||
if(!msftLogoutSuccessSent) {
|
|
||||||
msftLogoutSuccessSent = true
|
|
||||||
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.SUCCESS, uuid, isLastAccount)
|
|
||||||
}
|
|
||||||
|
|
||||||
if(msftLogoutWindow) {
|
|
||||||
msftLogoutWindow.close()
|
|
||||||
msftLogoutWindow = null
|
|
||||||
}
|
|
||||||
}, 5000)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
msftLogoutWindow.removeMenu()
|
|
||||||
msftLogoutWindow.loadURL('https://login.microsoftonline.com/common/oauth2/v2.0/logout')
|
|
||||||
})
|
|
||||||
|
|
||||||
// Keep a global reference of the window object, if you don't, the window will
|
// Keep a global reference of the window object, if you don't, the window will
|
||||||
// be closed automatically when the JavaScript object is garbage collected.
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||||
@ -223,8 +115,8 @@ let win
|
|||||||
function createWindow() {
|
function createWindow() {
|
||||||
|
|
||||||
win = new BrowserWindow({
|
win = new BrowserWindow({
|
||||||
width: 980,
|
width: 1143,
|
||||||
height: 552,
|
height: 700,
|
||||||
icon: getPlatformIcon('SealCircle'),
|
icon: getPlatformIcon('SealCircle'),
|
||||||
frame: false,
|
frame: false,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
@ -351,3 +243,82 @@ app.on('activate', () => {
|
|||||||
createWindow()
|
createWindow()
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const REDIRECT_URI_PREFIX = 'https://login.microsoftonline.com/common/oauth2/nativeclient?'
|
||||||
|
|
||||||
|
// Microsoft Auth Login
|
||||||
|
let msftAuthWindow
|
||||||
|
let msftAuthSuccess
|
||||||
|
let msftAuthViewSuccess
|
||||||
|
let msftAuthViewOnClose
|
||||||
|
ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
|
||||||
|
/*
|
||||||
|
Clear cookies from live.com and github.com from Microsoft Login, since there isn't an actual way to invalidate Microsoft access token
|
||||||
|
*/
|
||||||
|
session.defaultSession.cookies.get({ domain: 'live.com' }).then((cookies) => {
|
||||||
|
for (let cookie of cookies) {
|
||||||
|
let urlcookie = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`;
|
||||||
|
session.defaultSession.cookies.remove(urlcookie, cookie.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
session.defaultSession.cookies.get({ domain: 'github.com' }).then((cookies) => {
|
||||||
|
for (let cookie of cookies) {
|
||||||
|
let urlcookie = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`;
|
||||||
|
session.defaultSession.cookies.remove(urlcookie, cookie.name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (msftAuthWindow) {
|
||||||
|
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN, msftAuthViewOnClose)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
msftAuthSuccess = false
|
||||||
|
msftAuthViewSuccess = arguments_[0]
|
||||||
|
msftAuthViewOnClose = arguments_[1]
|
||||||
|
msftAuthWindow = new BrowserWindow({
|
||||||
|
parent: win,
|
||||||
|
modal: true,
|
||||||
|
resizable: false,
|
||||||
|
title: 'Microsoft Login',
|
||||||
|
backgroundColor: '#222222',
|
||||||
|
width: 520,
|
||||||
|
height: 700,
|
||||||
|
frame: true,
|
||||||
|
icon: getPlatformIcon('SealCircle')
|
||||||
|
})
|
||||||
|
|
||||||
|
msftAuthWindow.on('closed', () => {
|
||||||
|
msftAuthWindow = undefined
|
||||||
|
})
|
||||||
|
|
||||||
|
msftAuthWindow.on('close', () => {
|
||||||
|
if (!msftAuthSuccess) {
|
||||||
|
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED, msftAuthViewOnClose)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
msftAuthWindow.webContents.on('did-navigate', (_, uri) => {
|
||||||
|
if (uri.startsWith(REDIRECT_URI_PREFIX)) {
|
||||||
|
let queries = uri.substring(REDIRECT_URI_PREFIX.length).split('#', 1).toString().split('&')
|
||||||
|
let queryMap = {}
|
||||||
|
|
||||||
|
queries.forEach(query => {
|
||||||
|
const [name, value] = query.split('=')
|
||||||
|
queryMap[name] = decodeURI(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.SUCCESS, queryMap, msftAuthViewSuccess)
|
||||||
|
|
||||||
|
msftAuthSuccess = true
|
||||||
|
msftAuthWindow.close()
|
||||||
|
msftAuthWindow = null
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
msftAuthWindow.removeMenu()
|
||||||
|
msftAuthWindow.loadURL(`https://login.live.com/oauth20_authorize.srf?prompt=select_account&client_id=${AZURE_CLIENT_ID}&response_type=code&scope=XboxLive.signin%20offline_access&redirect_uri=https://login.microsoftonline.com/common/oauth2/nativeclient&cobrandid=8058f65d-ce06-4c30-9559-473c9275a65d`) //Cobrandid adds the Minecraft branding on the login page
|
||||||
|
})
|
||||||
|
|
||||||
|
// Microsoft Auth Logout
|
||||||
|
ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
|
||||||
|
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.SUCCESS, uuid, isLastAccount) //Just reply to the event, since logout pop up isn't that much useful
|
||||||
|
})
|
Loading…
Reference in New Issue
Block a user