[utils] Use JS to get SID response to work on GTK WebKit

This commit is contained in:
derrod 2021-10-06 20:36:14 +02:00
parent fcf8bee6eb
commit 917cfc259e

View file

@ -21,8 +21,8 @@ logout_url = 'https://www.epicgames.com/id/logout?productName=epic-games&redirec
window_js = ''' window_js = '''
window.ue = { window.ue = {
signinprompt: { signinprompt: {
requestexchangecodesignin: pywebview.api.complete_login, requestexchangecodesignin: pywebview.api.set_exchange_code,
registersignincompletecallback: pywebview.api.trigger_logout registersignincompletecallback: pywebview.api.trigger_sid_exchange
}, },
common: { common: {
launchexternalurl: pywebview.api.open_url_external, launchexternalurl: pywebview.api.open_url_external,
@ -34,6 +34,17 @@ window.ue = {
} }
''' '''
get_sid_js = '''
function on_loaded() {
pywebview.api.login_sid(this.responseText);
}
var sid_req = new XMLHttpRequest();
sid_req.addEventListener("load", on_loaded);
sid_req.open("GET", "/id/api/redirect?");
sid_req.send();
'''
class MockLauncher: class MockLauncher:
def __init__(self, callback=None): def __init__(self, callback=None):
@ -52,20 +63,7 @@ class MockLauncher:
if self.inject_js: if self.inject_js:
self.window.evaluate_js(window_js) self.window.evaluate_js(window_js)
if 'id/api/redirect' in url: if 'logout' in url:
body = self.window.get_elements('body')[0]['textContent']
try:
j = json.loads(body)
self.sid = j['sid']
logger.debug(f'Got SID (stage 2)!')
if self.callback:
logger.debug(f'Calling login callback...')
self.callback_result = self.callback(self.sid)
except Exception as e:
logger.error(f'Loading SID response failed with {e!r}')
logger.debug('Starting browser logout...')
self.window.load_url(logout_url)
elif 'logout' in url:
# prepare to close browser after logout redirect # prepare to close browser after logout redirect
self.destroy_on_load = True self.destroy_on_load = True
elif self.destroy_on_load: elif self.destroy_on_load:
@ -79,12 +77,7 @@ class MockLauncher:
def open_url_external(self, url): def open_url_external(self, url):
webbrowser.open(url) webbrowser.open(url)
def trigger_logout(self, *args, **kwargs): def set_exchange_code(self, exchange_code):
self.inject_js = False
# first obtain SID, then log out
self.window.load_url(sid_url)
def complete_login(self, exchange_code):
logger.debug('Got exchange code (stage 1)!') logger.debug('Got exchange code (stage 1)!')
# we cannot use this exchange code as our login would be invalidated # we cannot use this exchange code as our login would be invalidated
# after logging out on the website. Hence we do the dance of using # after logging out on the website. Hence we do the dance of using
@ -92,6 +85,25 @@ class MockLauncher:
# that remains valid after logging out. # that remains valid after logging out.
self.exchange_code = exchange_code self.exchange_code = exchange_code
def trigger_sid_exchange(self, *args, **kwargs):
self.inject_js = False
# first obtain SID, then log out
self.window.evaluate_js(get_sid_js)
def login_sid(self, sid_json):
try:
j = json.loads(sid_json)
self.sid = j['sid']
logger.debug(f'Got SID (stage 2)!')
if self.callback:
logger.debug(f'Calling login callback...')
self.callback_result = self.callback(self.sid)
except Exception as e:
logger.error(f'Loading SID response failed with {e!r}')
finally:
logger.debug('Starting browser logout...')
self.window.load_url(logout_url)
def do_webview_login(callback=None): def do_webview_login(callback=None):
api = MockLauncher(callback=callback) api = MockLauncher(callback=callback)