-
Notifications
You must be signed in to change notification settings - Fork 4
/
open-webview-popup.ts
106 lines (94 loc) · 4.21 KB
/
open-webview-popup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import {WebviewTag} from 'electron'
import {parseAuthRedirect} from './parse-auth-redirect'
/**
* Opens a popup window to sign in to Riot
* The promise resolves with the access token and expiration time
* If the window is closed, the promise rejects with an error message
* @param context The Insomnia context, used for opening a dialog element
*/
export async function openWebViewPopup(context: any) {
return new Promise<ReturnType<typeof parseAuthRedirect>>((resolve, reject) => {
const valWebView = document.createElement('webview') as WebviewTag
valWebView.style.display = 'none'
valWebView.classList.add('val-webview')
valWebView.nodeintegration = false
// Set partition to avoid Insomnia stripping out the Origin headers needed for CORS
valWebView.partition = 'persist:valorant'
let shownSignIn = false
let readyForHide = false
let cleanedUp = false
// Event handler to check for tokens in the urls of navigated and redirected events
const checkForToken = async (event: Electron.DidRedirectNavigationEvent | Electron.DidNavigateEvent) => {
if (event.url.startsWith('https://playvalorant.com/') && event.url.includes('access_token')) {
cleanupWebView()
// Close model
if(shownSignIn) {
const closeButtons = document.getElementsByClassName('modal__close-btn') as HTMLCollectionOf<HTMLButtonElement>
if(closeButtons.length !== 0) {
readyForHide = true
for(const closeButton of closeButtons) {
closeButton.click()
}
}
}
try {
resolve(parseAuthRedirect(event.url))
} catch(e) {
reject(e)
}
}
}
// Event handler for when the modal is closed
const hideHandler = () => {
cleanupWebView()
if(!readyForHide) {
reject('Window closed')
}
}
const redirectHandler = (event: Electron.DidRedirectNavigationEvent) => {
checkForToken(event)
}
const navigateHandler = (event: Electron.DidNavigateEvent) => {
if (event.url.startsWith('https://authenticate.riotgames.com') && !shownSignIn) {
shownSignIn = true
// Add styling to dom
const styleID = 'val-auth-style'
if(document.getElementById(styleID) === null) {
const style = document.createElement('style')
style.id = styleID
style.innerHTML = `
div:has(> .val-webview) {
height: 100%;
}
`
document.head.appendChild(style)
}
document.body.removeChild(valWebView)
valWebView.style.removeProperty('display')
context.app.dialog('Riot Sign In', valWebView, {
tall: true,
wide: true,
onHide: hideHandler
})
}
checkForToken(event)
}
const cleanupWebView = () => {
if(cleanedUp) return
cleanedUp = true
valWebView.removeEventListener('did-redirect-navigation', redirectHandler)
valWebView.removeEventListener('did-navigate', navigateHandler)
// Ignore errors relating to the webview not being attached to the dom
try {
valWebView.stop()
} catch(ignored) {}
if (!shownSignIn) {
document.body.removeChild(valWebView)
}
}
valWebView.addEventListener('did-redirect-navigation', redirectHandler)
valWebView.addEventListener('did-navigate', navigateHandler)
valWebView.src = 'https://auth.riotgames.com/authorize?redirect_uri=https%3A%2F%2Fplayvalorant.com%2Fopt_in&client_id=play-valorant-web-prod&response_type=token%20id_token&nonce=1&scope=account%20openid'
document.body.appendChild(valWebView)
})
}