@@ -66,7 +66,6 @@ def _random_browser_headers() -> dict[str, str]:
6666 "Android/33; Dalvik/2.1.0"
6767)
6868DI_TOKEN_URL = "https://diauth.garmin.com/di-oauth2-service/oauth/token" # noqa: S105
69- IT_TOKEN_URL = "https://services.garmin.com/api/oauth/token" # noqa: S105
7069DI_GRANT_TYPE = (
7170 "https://connectapi.garmin.com/di-oauth2-service/oauth/grant/service_ticket"
7271)
@@ -75,11 +74,6 @@ def _random_browser_headers() -> dict[str, str]:
7574 "GARMIN_CONNECT_MOBILE_ANDROID_DI_2024Q4" ,
7675 "GARMIN_CONNECT_MOBILE_ANDROID_DI" ,
7776)
78- IT_CLIENT_IDS = (
79- "GARMIN_CONNECT_MOBILE_ANDROID_2025Q2" ,
80- "GARMIN_CONNECT_MOBILE_ANDROID_2024Q4" ,
81- "GARMIN_CONNECT_MOBILE_ANDROID" ,
82- )
8377
8478
8579def _build_basic_auth (client_id : str ) -> str :
@@ -115,9 +109,6 @@ def __init__(self, domain: str = "garmin.com", **kwargs: Any) -> None:
115109 self .di_token : str | None = None
116110 self .di_refresh_token : str | None = None
117111 self .di_client_id : str | None = None
118- self .it_token : str | None = None
119- self .it_refresh_token : str | None = None
120- self .it_client_id : str | None = None
121112
122113 # JWT_WEB cookie auth (fallback when DI token is unavailable)
123114 self .jwt_web : str | None = None
@@ -807,36 +798,6 @@ def _exchange_service_ticket(
807798 self .di_refresh_token = di_refresh
808799 self .di_client_id = di_client_id
809800
810- # Exchange DI for IT token
811- it_candidates = self ._it_client_id_candidates (di_client_id or DI_CLIENT_IDS [0 ])
812- for client_id in it_candidates :
813- r = self ._http_post (
814- f"{ IT_TOKEN_URL } ?grant_type=connect2_exchange" ,
815- headers = _native_headers (
816- {
817- "Accept" : "application/json,text/plain,*/*" ,
818- "Content-Type" : "application/x-www-form-urlencoded" ,
819- }
820- ),
821- data = {
822- "client_id" : client_id ,
823- "connect_access_token" : di_token ,
824- },
825- timeout = 30 ,
826- )
827- if not r .ok :
828- _LOGGER .debug ("IT exchange failed for %s: %s" , client_id , r .status_code )
829- continue
830- try :
831- data = r .json ()
832- self .it_token = data ["access_token" ]
833- self .it_refresh_token = data .get ("refresh_token" )
834- self .it_client_id = client_id
835- break
836- except Exception as e :
837- _LOGGER .debug ("IT token parse failed for %s: %s" , client_id , e )
838- continue
839-
840801 def _refresh_di_token (self ) -> None :
841802 """Refresh the DI Bearer token using the stored refresh token."""
842803 if not self .di_refresh_token or not self .di_client_id :
@@ -881,20 +842,6 @@ def _extract_client_id_from_jwt(self, token: str) -> str | None:
881842 except Exception :
882843 return None
883844
884- def _it_client_id_candidates (self , di_client_id : str ) -> tuple [str , ...]:
885- derived = (
886- di_client_id .replace ("_DI_" , "_" )
887- if "_DI_" in di_client_id
888- else (
889- di_client_id [:- 3 ] if di_client_id .endswith ("_DI" ) else IT_CLIENT_IDS [0 ]
890- )
891- )
892- seen : list [str ] = []
893- for v in [self .it_client_id , derived , * IT_CLIENT_IDS ]:
894- if v and v not in seen :
895- seen .append (v )
896- return tuple (seen )
897-
898845 def _token_expires_soon (self ) -> bool :
899846 token = self .di_token or self .jwt_web
900847 if not token :
@@ -972,13 +919,6 @@ def dumps(self) -> str:
972919 "di_token" : self .di_token ,
973920 "di_refresh_token" : self .di_refresh_token ,
974921 "di_client_id" : self .di_client_id ,
975- "it_token" : self .it_token ,
976- "it_refresh_token" : self .it_refresh_token ,
977- "it_client_id" : self .it_client_id ,
978- # JWT_WEB fields
979- "jwt_web" : self .jwt_web ,
980- "csrf_token" : self .csrf_token ,
981- "cookies" : {c .name : c .value for c in self .cs .cookies .jar },
982922 }
983923 return json .dumps (data )
984924
@@ -1008,24 +948,6 @@ def loads(self, tokenstore: str) -> None:
1008948 self .di_token = data .get ("di_token" )
1009949 self .di_refresh_token = data .get ("di_refresh_token" )
1010950 self .di_client_id = data .get ("di_client_id" )
1011- self .it_token = data .get ("it_token" )
1012- self .it_refresh_token = data .get ("it_refresh_token" )
1013- self .it_client_id = data .get ("it_client_id" )
1014- self .jwt_web = data .get ("jwt_web" )
1015- self .csrf_token = data .get ("csrf_token" )
1016-
1017- # Restore cookies if no DI token
1018- if not self .di_token :
1019- sso_cookies = {"CASTGC" , "CASRMC" , "CASMFA" , "SESSION" , "__VCAP_ID__" }
1020- connect_cookies = {"JWT_WEB" , "session" , "__cflb" }
1021- for k , v in data .get ("cookies" , {}).items ():
1022- if k in sso_cookies :
1023- self .cs .cookies .set (k , v , domain = f"sso.{ self .domain } " )
1024- elif k in connect_cookies :
1025- self .cs .cookies .set (k , v , domain = f".connect.{ self .domain } " )
1026- else :
1027- self .cs .cookies .set (k , v , domain = f".{ self .domain } " )
1028-
1029951 if not self .is_authenticated :
1030952 raise GarminConnectAuthenticationError ("Missing tokens from dict load" )
1031953 except Exception as e :
0 commit comments