Skip to content

Commit a818628

Browse files
committed
feat: MS Login v2.0
1 parent 2e1ab3c commit a818628

File tree

4 files changed

+104
-130
lines changed

4 files changed

+104
-130
lines changed

app/assets/js/scripts/login.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -235,5 +235,4 @@ loginButton.addEventListener('click', () => {
235235
})
236236
toggleOverlay(true)
237237
})
238-
239-
})
238+
})

app/assets/js/scripts/settings.js

+20-16
Original file line numberDiff line numberDiff line change
@@ -333,8 +333,9 @@ document.getElementById('settingsAddMojangAccount').onclick = (e) => {
333333

334334
// Bind the add microsoft account button.
335335
document.getElementById('settingsAddMicrosoftAccount').onclick = (e) => {
336+
document.getElementById("waitingText").innerHTML = "Please login in the window that has just opened"
336337
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
337-
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGIN, VIEWS.settings, VIEWS.settings)
338+
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGIN, VIEWS.landing, VIEWS.settings)
338339
})
339340
}
340341

@@ -363,7 +364,8 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
363364
})
364365
toggleOverlay(true)
365366
})
366-
} else if(arguments_[0] === MSFT_REPLY_TYPE.SUCCESS) {
367+
} else if (arguments_[0] === MSFT_REPLY_TYPE.SUCCESS) {
368+
document.getElementById("waitingText").innerHTML = "Retrieving your account information from Microsoft"
367369
const queryMap = arguments_[1]
368370
const viewOnClose = arguments_[2]
369371

@@ -374,7 +376,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
374376
// This is probably if you messed up the app registration with Azure.
375377
console.log('Error getting authCode, is Azure application registered correctly?')
376378
console.log(error)
377-
console.log(error_description)
379+
console.log(errorDesc)
378380
console.log('Full query map', queryMap)
379381
let error = queryMap.error // Error might be 'access_denied' ?
380382
let errorDesc = queryMap.error_description
@@ -386,7 +388,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
386388
setOverlayHandler(() => {
387389
toggleOverlay(false)
388390
})
389-
toggleOverlay(true)
391+
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
390392

391393
})
392394
} else {
@@ -395,6 +397,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGIN, (_, ...arguments_) => {
395397

396398
const authCode = queryMap.code
397399
AuthManager.addMicrosoftAccount(authCode).then(value => {
400+
document.getElementById("waitingText").innerHTML = "Finished"
398401
updateSelectedAccount(value)
399402
switchView(getCurrentView(), viewOnClose, 500, 500, () => {
400403
prepareSettings()
@@ -479,7 +482,7 @@ function bindAuthAccountLogOut(){
479482
} else {
480483
processLogOut(val, isLastAccount)
481484
}
482-
485+
483486
}
484487
})
485488
}
@@ -499,6 +502,7 @@ function processLogOut(val, isLastAccount){
499502
if(targetAcc.type === 'microsoft') {
500503
msAccDomElementCache = parent
501504
switchView(getCurrentView(), VIEWS.waiting, 500, 500, () => {
505+
document.getElementById("waitingText").innerHTML = "Removing your Microsoft account from the launcher" //We actually don't have to wait anything from Mirosoft
502506
ipcRenderer.send(MSFT_OPCODE.OPEN_LOGOUT, uuid, isLastAccount)
503507
})
504508
} else {
@@ -509,16 +513,16 @@ function processLogOut(val, isLastAccount){
509513
updateSelectedAccount(selAcc)
510514
validateSelectedAccount()
511515
}
512-
if(isLastAccount) {
513-
loginOptionsCancelEnabled(false)
514-
loginOptionsViewOnLoginSuccess = VIEWS.settings
515-
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
516-
switchView(getCurrentView(), VIEWS.loginOptions)
517-
}
518-
})
519-
$(parent).fadeOut(250, () => {
520-
parent.remove()
516+
$(parent).fadeOut(250, () => {
517+
parent.remove()
518+
})
521519
})
520+
if (isLastAccount) {
521+
loginOptionsCancelEnabled(false)
522+
loginOptionsViewOnLoginSuccess = VIEWS.landing
523+
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
524+
switchView(getCurrentView(), VIEWS.loginOptions)
525+
}
522526
}
523527
}
524528

@@ -551,7 +555,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
551555
const prevSelAcc = ConfigManager.getSelectedAccount()
552556

553557
msftLogoutLogger.info('Logout Successful. uuid:', uuid)
554-
558+
555559
AuthManager.removeMicrosoftAccount(uuid)
556560
.then(() => {
557561
if(!isLastAccount && uuid === prevSelAcc.uuid){
@@ -562,7 +566,7 @@ ipcRenderer.on(MSFT_OPCODE.REPLY_LOGOUT, (_, ...arguments_) => {
562566
}
563567
if(isLastAccount) {
564568
loginOptionsCancelEnabled(false)
565-
loginOptionsViewOnLoginSuccess = VIEWS.settings
569+
loginOptionsViewOnLoginSuccess = VIEWS.landing
566570
loginOptionsViewOnLoginCancel = VIEWS.loginOptions
567571
switchView(getCurrentView(), VIEWS.loginOptions)
568572
}

app/waiting.ejs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div id="waitingContent">
33
<div class="waitingSpinner"></div>
44
<div id="waitingTextContainer">
5-
<h2>Waiting for Microsoft..</h2>
5+
<h2 id="waitingText">Waiting for Microsoft..</h2>
66
</div>
77
</div>
88
</div>

index.js

+82-111
Original file line numberDiff line numberDiff line change
@@ -105,116 +105,8 @@ ipcMain.handle(SHELL_OPCODE.TRASH_ITEM, async (event, ...args) => {
105105
app.disableHardwareAcceleration()
106106

107107

108-
const REDIRECT_URI_PREFIX = 'https://login.microsoftonline.com/common/oauth2/nativeclient?'
109-
110-
// Microsoft Auth Login
111-
let msftAuthWindow
112-
let msftAuthSuccess
113-
let msftAuthViewSuccess
114-
let msftAuthViewOnClose
115-
ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
116-
if (msftAuthWindow) {
117-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN, msftAuthViewOnClose)
118-
return
119-
}
120-
msftAuthSuccess = false
121-
msftAuthViewSuccess = arguments_[0]
122-
msftAuthViewOnClose = arguments_[1]
123-
msftAuthWindow = new BrowserWindow({
124-
title: 'Microsoft Login',
125-
backgroundColor: '#222222',
126-
width: 520,
127-
height: 600,
128-
frame: true,
129-
icon: getPlatformIcon('SealCircle')
130-
})
131-
132-
msftAuthWindow.on('closed', () => {
133-
msftAuthWindow = undefined
134-
})
135-
136-
msftAuthWindow.on('close', () => {
137-
if(!msftAuthSuccess) {
138-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED, msftAuthViewOnClose)
139-
}
140-
})
141-
142-
msftAuthWindow.webContents.on('did-navigate', (_, uri) => {
143-
if (uri.startsWith(REDIRECT_URI_PREFIX)) {
144-
let queries = uri.substring(REDIRECT_URI_PREFIX.length).split('#', 1).toString().split('&')
145-
let queryMap = {}
146-
147-
queries.forEach(query => {
148-
const [name, value] = query.split('=')
149-
queryMap[name] = decodeURI(value)
150-
})
151-
152-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.SUCCESS, queryMap, msftAuthViewSuccess)
153-
154-
msftAuthSuccess = true
155-
msftAuthWindow.close()
156-
msftAuthWindow = null
157-
}
158-
})
159-
160-
msftAuthWindow.removeMenu()
161-
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`)
162-
})
163-
164-
// Microsoft Auth Logout
165-
let msftLogoutWindow
166-
let msftLogoutSuccess
167-
let msftLogoutSuccessSent
168-
ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
169-
if (msftLogoutWindow) {
170-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN)
171-
return
172-
}
173-
174-
msftLogoutSuccess = false
175-
msftLogoutSuccessSent = false
176-
msftLogoutWindow = new BrowserWindow({
177-
title: 'Microsoft Logout',
178-
backgroundColor: '#222222',
179-
width: 520,
180-
height: 600,
181-
frame: true,
182-
icon: getPlatformIcon('SealCircle')
183-
})
184-
185-
msftLogoutWindow.on('closed', () => {
186-
msftLogoutWindow = undefined
187-
})
188-
189-
msftLogoutWindow.on('close', () => {
190-
if(!msftLogoutSuccess) {
191-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED)
192-
} else if(!msftLogoutSuccessSent) {
193-
msftLogoutSuccessSent = true
194-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.SUCCESS, uuid, isLastAccount)
195-
}
196-
})
197-
198-
msftLogoutWindow.webContents.on('did-navigate', (_, uri) => {
199-
if(uri.startsWith('https://login.microsoftonline.com/common/oauth2/v2.0/logoutsession')) {
200-
msftLogoutSuccess = true
201-
setTimeout(() => {
202-
if(!msftLogoutSuccessSent) {
203-
msftLogoutSuccessSent = true
204-
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGOUT, MSFT_REPLY_TYPE.SUCCESS, uuid, isLastAccount)
205-
}
108+
206109

207-
if(msftLogoutWindow) {
208-
msftLogoutWindow.close()
209-
msftLogoutWindow = null
210-
}
211-
}, 5000)
212-
}
213-
})
214-
215-
msftLogoutWindow.removeMenu()
216-
msftLogoutWindow.loadURL('https://login.microsoftonline.com/common/oauth2/v2.0/logout')
217-
})
218110

219111
// Keep a global reference of the window object, if you don't, the window will
220112
// be closed automatically when the JavaScript object is garbage collected.
@@ -223,8 +115,8 @@ let win
223115
function createWindow() {
224116

225117
win = new BrowserWindow({
226-
width: 980,
227-
height: 552,
118+
width: 1143,
119+
height: 700,
228120
icon: getPlatformIcon('SealCircle'),
229121
frame: false,
230122
webPreferences: {
@@ -350,4 +242,83 @@ app.on('activate', () => {
350242
if (win === null) {
351243
createWindow()
352244
}
245+
})
246+
247+
const REDIRECT_URI_PREFIX = 'https://login.microsoftonline.com/common/oauth2/nativeclient?'
248+
249+
// Microsoft Auth Login
250+
let msftAuthWindow
251+
let msftAuthSuccess
252+
let msftAuthViewSuccess
253+
let msftAuthViewOnClose
254+
ipcMain.on(MSFT_OPCODE.OPEN_LOGIN, (ipcEvent, ...arguments_) => {
255+
/*
256+
Clear cookies from live.com and github.com from Microsoft Login, since there isn't an actual way to invalidate Microsoft access token
257+
*/
258+
session.defaultSession.cookies.get({ domain: 'live.com' }).then((cookies) => {
259+
for (let cookie of cookies) {
260+
let urlcookie = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`;
261+
session.defaultSession.cookies.remove(urlcookie, cookie.name)
262+
}
263+
})
264+
session.defaultSession.cookies.get({ domain: 'github.com' }).then((cookies) => {
265+
for (let cookie of cookies) {
266+
let urlcookie = `http${cookie.secure ? "s" : ""}://${cookie.domain.replace(/$\./, "") + cookie.path}`;
267+
session.defaultSession.cookies.remove(urlcookie, cookie.name)
268+
}
269+
})
270+
if (msftAuthWindow) {
271+
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.ALREADY_OPEN, msftAuthViewOnClose)
272+
return
273+
}
274+
msftAuthSuccess = false
275+
msftAuthViewSuccess = arguments_[0]
276+
msftAuthViewOnClose = arguments_[1]
277+
msftAuthWindow = new BrowserWindow({
278+
parent: win,
279+
modal: true,
280+
resizable: false,
281+
title: 'Microsoft Login',
282+
backgroundColor: '#222222',
283+
width: 520,
284+
height: 700,
285+
frame: true,
286+
icon: getPlatformIcon('SealCircle')
287+
})
288+
289+
msftAuthWindow.on('closed', () => {
290+
msftAuthWindow = undefined
291+
})
292+
293+
msftAuthWindow.on('close', () => {
294+
if (!msftAuthSuccess) {
295+
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.ERROR, MSFT_ERROR.NOT_FINISHED, msftAuthViewOnClose)
296+
}
297+
})
298+
299+
msftAuthWindow.webContents.on('did-navigate', (_, uri) => {
300+
if (uri.startsWith(REDIRECT_URI_PREFIX)) {
301+
let queries = uri.substring(REDIRECT_URI_PREFIX.length).split('#', 1).toString().split('&')
302+
let queryMap = {}
303+
304+
queries.forEach(query => {
305+
const [name, value] = query.split('=')
306+
queryMap[name] = decodeURI(value)
307+
})
308+
309+
ipcEvent.reply(MSFT_OPCODE.REPLY_LOGIN, MSFT_REPLY_TYPE.SUCCESS, queryMap, msftAuthViewSuccess)
310+
311+
msftAuthSuccess = true
312+
msftAuthWindow.close()
313+
msftAuthWindow = null
314+
}
315+
})
316+
317+
msftAuthWindow.removeMenu()
318+
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
319+
})
320+
321+
// Microsoft Auth Logout
322+
ipcMain.on(MSFT_OPCODE.OPEN_LOGOUT, (ipcEvent, uuid, isLastAccount) => {
323+
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
353324
})

0 commit comments

Comments
 (0)