Login flow now uses the returned verification_uri;
to prefill the user_code on the activation page
This commit is contained in:
1 parent
689afdddbe
commit
c4cfa5372f
3 files changed
+13
-11
No files matched your search
@@ -581,7 +581,7 @@ class LoginForm:
|
|||||||
continue
|
continue
|
||||||
return login_data
|
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)
|
self.update(_("gui", "login", "required"), None)
|
||||||
# ensure the window isn't hidden into tray when this runs
|
# ensure the window isn't hidden into tray when this runs
|
||||||
self._manager.grab_attention(sound=False)
|
self._manager.grab_attention(sound=False)
|
||||||
@@ -589,7 +589,7 @@ class LoginForm:
|
|||||||
await self.wait_for_login_press()
|
await self.wait_for_login_press()
|
||||||
self._manager.print(f"Enter this code on the Twitch's device activation page: {user_code}")
|
self._manager.print(f"Enter this code on the Twitch's device activation page: {user_code}")
|
||||||
await asyncio.sleep(4)
|
await asyncio.sleep(4)
|
||||||
webopen("https://www.twitch.tv/activate")
|
webopen(page_url)
|
||||||
|
|
||||||
def update(self, status: str, user_id: int | None):
|
def update(self, status: str, user_id: int | None):
|
||||||
if user_id is not None:
|
if user_id is not None:
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ class _AuthState:
|
|||||||
}
|
}
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
|
now = datetime.now(timezone.utc)
|
||||||
async with self._twitch.request(
|
async with self._twitch.request(
|
||||||
"POST", "https://id.twitch.tv/oauth2/device", headers=headers, data=payload
|
"POST", "https://id.twitch.tv/oauth2/device", headers=headers, data=payload
|
||||||
) as response:
|
) as response:
|
||||||
@@ -136,17 +137,17 @@ class _AuthState:
|
|||||||
# "expires_in": 1800,
|
# "expires_in": 1800,
|
||||||
# "interval": 5,
|
# "interval": 5,
|
||||||
# "user_code": "8 chars [A-Z]",
|
# "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()
|
response_json: JsonType = await response.json()
|
||||||
device_code: str = response_json["device_code"]
|
device_code: str = response_json["device_code"]
|
||||||
user_code: str = response_json["user_code"]
|
user_code: str = response_json["user_code"]
|
||||||
interval: int = response_json["interval"]
|
interval: int = response_json["interval"]
|
||||||
|
verification_uri: URL = URL(response_json["verification_uri"])
|
||||||
expires_at = now + timedelta(seconds=response_json["expires_in"])
|
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
|
# 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 = {
|
payload = {
|
||||||
"client_id": self._twitch._client_type.CLIENT_ID,
|
"client_id": self._twitch._client_type.CLIENT_ID,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ from datetime import datetime, timezone
|
|||||||
from collections import abc, OrderedDict
|
from collections import abc, OrderedDict
|
||||||
from typing import Any, Literal, Callable, Generic, Mapping, TypeVar, ParamSpec, cast
|
from typing import Any, Literal, Callable, Generic, Mapping, TypeVar, ParamSpec, cast
|
||||||
|
|
||||||
import yarl
|
from yarl import URL
|
||||||
from PIL.ImageTk import PhotoImage
|
from PIL.ImageTk import PhotoImage
|
||||||
from PIL import Image as Image_module
|
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,
|
# NOTE: IntEnum cannot be used, as it will get serialized as a plain integer,
|
||||||
# then loaded back as an integer as well.
|
# then loaded back as an integer as well.
|
||||||
d = obj.value
|
d = obj.value
|
||||||
elif isinstance(obj, yarl.URL):
|
elif isinstance(obj, URL):
|
||||||
d = str(obj)
|
d = str(obj)
|
||||||
else:
|
else:
|
||||||
raise TypeError(obj)
|
raise TypeError(obj)
|
||||||
@@ -190,7 +190,7 @@ def _serialize(obj: Any) -> Any:
|
|||||||
_MISSING = object()
|
_MISSING = object()
|
||||||
SERIALIZE_ENV: dict[str, Callable[[Any], object]] = {
|
SERIALIZE_ENV: dict[str, Callable[[Any], object]] = {
|
||||||
"set": set,
|
"set": set,
|
||||||
"URL": yarl.URL,
|
"URL": URL,
|
||||||
"PriorityMode": PriorityMode,
|
"PriorityMode": PriorityMode,
|
||||||
"datetime": lambda d: datetime.fromtimestamp(d, timezone.utc),
|
"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)
|
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":
|
if IS_PACKAGED and sys.platform == "linux":
|
||||||
# https://pyinstaller.org/en/stable/
|
# https://pyinstaller.org/en/stable/
|
||||||
# runtime-information.html#ld-library-path-libpath-considerations
|
# runtime-information.html#ld-library-path-libpath-considerations
|
||||||
@@ -268,7 +269,7 @@ def webopen(url: str):
|
|||||||
# pop current
|
# pop current
|
||||||
os.environ.pop(ld_env)
|
os.environ.pop(ld_env)
|
||||||
|
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url_str)
|
||||||
|
|
||||||
if ld_path_curr is not None:
|
if ld_path_curr is not None:
|
||||||
os.environ[ld_env] = ld_path_curr
|
os.environ[ld_env] = ld_path_curr
|
||||||
@@ -276,7 +277,7 @@ def webopen(url: str):
|
|||||||
# pop original
|
# pop original
|
||||||
os.environ.pop(ld_env)
|
os.environ.pop(ld_env)
|
||||||
else:
|
else:
|
||||||
webbrowser.open_new_tab(url)
|
webbrowser.open_new_tab(url_str)
|
||||||
|
|
||||||
|
|
||||||
class ExponentialBackoff:
|
class ExponentialBackoff:
|
||||||
|
|||||||
Reference in new issue
Block a user