Login flow now uses the returned verification_uri;

to prefill the user_code on the activation page
This commit is contained in:
DevilXD
2025-02-03 21:31:06 +01:00
parent 689afdddbe
commit c4cfa5372f
3 changed files with 13 additions and 11 deletions

4
gui.py
View File

@@ -581,7 +581,7 @@ class LoginForm:
continue
return login_data
async def ask_enter_code(self, user_code: str) -> None:
async def ask_enter_code(self, page_url: URL, user_code: str) -> None:
self.update(_("gui", "login", "required"), None)
# ensure the window isn't hidden into tray when this runs
self._manager.grab_attention(sound=False)
@@ -589,7 +589,7 @@ class LoginForm:
await self.wait_for_login_press()
self._manager.print(f"Enter this code on the Twitch's device activation page: {user_code}")
await asyncio.sleep(4)
webopen("https://www.twitch.tv/activate")
webopen(page_url)
def update(self, status: str, user_id: int | None):
if user_id is not None:

View File

@@ -128,6 +128,7 @@ class _AuthState:
}
while True:
try:
now = datetime.now(timezone.utc)
async with self._twitch.request(
"POST", "https://id.twitch.tv/oauth2/device", headers=headers, data=payload
) as response:
@@ -136,17 +137,17 @@ class _AuthState:
# "expires_in": 1800,
# "interval": 5,
# "user_code": "8 chars [A-Z]",
# "verification_uri": "https://www.twitch.tv/activate"
# "verification_uri": "https://www.twitch.tv/activate?device-code=ABCDEFGH"
# }
now = datetime.now(timezone.utc)
response_json: JsonType = await response.json()
device_code: str = response_json["device_code"]
user_code: str = response_json["user_code"]
interval: int = response_json["interval"]
verification_uri: URL = URL(response_json["verification_uri"])
expires_at = now + timedelta(seconds=response_json["expires_in"])
# Print the code to the user, open them the activate page so they can type it in
await login_form.ask_enter_code(user_code)
await login_form.ask_enter_code(verification_uri, user_code)
payload = {
"client_id": self._twitch._client_type.CLIENT_ID,

View File

@@ -21,7 +21,7 @@ from datetime import datetime, timezone
from collections import abc, OrderedDict
from typing import Any, Literal, Callable, Generic, Mapping, TypeVar, ParamSpec, cast
import yarl
from yarl import URL
from PIL.ImageTk import PhotoImage
from PIL import Image as Image_module
@@ -176,7 +176,7 @@ def _serialize(obj: Any) -> Any:
# NOTE: IntEnum cannot be used, as it will get serialized as a plain integer,
# then loaded back as an integer as well.
d = obj.value
elif isinstance(obj, yarl.URL):
elif isinstance(obj, URL):
d = str(obj)
else:
raise TypeError(obj)
@@ -190,7 +190,7 @@ def _serialize(obj: Any) -> Any:
_MISSING = object()
SERIALIZE_ENV: dict[str, Callable[[Any], object]] = {
"set": set,
"URL": yarl.URL,
"URL": URL,
"PriorityMode": PriorityMode,
"datetime": lambda d: datetime.fromtimestamp(d, timezone.utc),
}
@@ -254,7 +254,8 @@ def json_save(path: Path, contents: Mapping[Any, Any], *, sort: bool = False) ->
json.dump(contents, file, default=_serialize, sort_keys=sort, indent=4)
def webopen(url: str):
def webopen(url: URL | str):
url_str = str(url)
if IS_PACKAGED and sys.platform == "linux":
# https://pyinstaller.org/en/stable/
# runtime-information.html#ld-library-path-libpath-considerations
@@ -268,7 +269,7 @@ def webopen(url: str):
# pop current
os.environ.pop(ld_env)
webbrowser.open_new_tab(url)
webbrowser.open_new_tab(url_str)
if ld_path_curr is not None:
os.environ[ld_env] = ld_path_curr
@@ -276,7 +277,7 @@ def webopen(url: str):
# pop original
os.environ.pop(ld_env)
else:
webbrowser.open_new_tab(url)
webbrowser.open_new_tab(url_str)
class ExponentialBackoff: