Files
AnabasisChatRemove/auth_webview.py
Денисов Александр Андреевич 0a82ad7e3e
Some checks are pending
Desktop Release / release (push) Waiting to run
Desktop CI / tests (push) Successful in 1m51s
Add VK callback auth support and admin demotion
2026-06-05 19:01:52 +03:00

132 lines
3.4 KiB
Python

import os
import sys
import json
import threading
from urllib.parse import urlparse, parse_qs, unquote
import webview
AUTH_USER_AGENT = (
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) "
"AppleWebKit/537.36 (KHTML, like Gecko) "
"Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
)
def extract_token(url_string):
token = None
expires_in = 3600
parsed = urlparse(url_string)
if parsed.fragment:
params = parse_qs(parsed.fragment)
else:
params = parse_qs(parsed.query)
if 'access_token' in params:
token = params['access_token'][0]
if 'expires_in' in params:
try:
expires_in = int(params['expires_in'][0])
except ValueError:
pass
if not token:
start_marker = "access_token%253D"
end_marker = "%25"
start_index = url_string.find(start_marker)
if start_index != -1:
token_start_index = start_index + len(start_marker)
remaining_url = url_string[token_start_index:]
end_index = remaining_url.find(end_marker)
if end_index != -1:
raw_token = remaining_url[:end_index]
else:
amp_index = remaining_url.find('&')
if amp_index != -1:
raw_token = remaining_url[:amp_index]
else:
raw_token = remaining_url
token = unquote(raw_token)
return token, expires_in
def main_auth(auth_url, output_path):
stop_polling = threading.Event()
polling_started = threading.Event()
def poll_url():
while not stop_polling.wait(0.75):
try:
url = window.get_current_url()
except Exception:
continue
if not url:
continue
token, expires_in = extract_token(url)
if not token:
continue
stop_polling.set()
data = {"token": token, "expires_in": expires_in}
with open(output_path, "w", encoding="utf-8") as f:
json.dump(data, f)
try:
window.destroy()
except Exception:
pass
return
def start_polling():
if polling_started.is_set():
return
polling_started.set()
thread = threading.Thread(target=poll_url, name="vk-auth-url-poller", daemon=True)
thread.start()
def on_loaded():
start_polling()
def on_closed():
stop_polling.set()
window = webview.create_window("VK Авторизация", auth_url)
window.events.loaded += on_loaded
try:
window.events.closed += on_closed
except Exception:
pass
webview.start(
start_polling,
gui="edgechromium" if os.name == "nt" else None,
private_mode=True,
storage_path=None,
user_agent=AUTH_USER_AGENT,
)
stop_polling.set()
def main():
# Supports both: `python auth_webview.py <auth_url> <output_path>`
# and: `python auth_webview.py --auth <auth_url> <output_path>`
args = sys.argv[1:]
if len(args) == 3 and args[0] == "--auth":
auth_url, output_path = args[1], args[2]
elif len(args) == 2:
auth_url, output_path = args[0], args[1]
else:
print("Usage: auth_webview.py [--auth] <auth_url> <output_path>")
return 1
main_auth(auth_url, output_path)
return 0
if __name__ == "__main__":
sys.exit(main())