diff --git a/tconnectsync/api/android.py b/tconnectsync/api/android.py index 2c97b78..d6b42d2 100644 --- a/tconnectsync/api/android.py +++ b/tconnectsync/api/android.py @@ -29,6 +29,10 @@ class AndroidApi: ANDROID_API_USERNAME = base64.b64decode('QzIzMzFDRDYtRDQ1MC00OTVFLTlDMTktNjcyMTUyMzBDODVD').decode() ANDROID_API_PASSWORD = base64.b64decode('dHo0MzNLVzVRREM5VjdmIXo2QF4ybyZZNlNHR1lo').decode() + # These credentials are used by tconnect web + TCONNECT_WEB_USERNAME = base64.b64decode('M0U2MzU3QkEtRjYyNS00REQyLUI2NUYtNEI1RTgxNDRBQTZG').decode() + TCONNECT_WEB_PASSWORD = base64.b64decode('cUMyaXFIc2w3OFFoR0RYdCpMenFwb1pxZTl3eHN6').decode() + ANDROID_USER_AGENT = 'Dalvik/2.1.0 (Linux; U; Android 12; Pixel 4a Build/SP2A.220305.012)' # These tokens are separate from the "standard" tdcservices API @@ -65,15 +69,17 @@ class AndroidApi: raise ApiLoginException(r.status_code, 'Received HTTP %s during login: %s' % (r.status_code, r.text)) j = r.json() - if "user" not in j or not j["user"]: - raise ApiException(r.status_code, 'No user details present in AndroidApi oauth response: %s' % r.text) + # tconnect web returns a null user + # if "user" not in j or not j["user"]: + # raise ApiException(r.status_code, 'No user details present in AndroidApi oauth response: %s' % r.text) self.accessToken = j["accessToken"] self.accessTokenExpiresAt = j["accessTokenExpiresAt"] # NOTE: the refresh token is currently unused, instead a new access # token is obtained from scratch by re-logging in when it expires. - self.refreshToken = j["refreshToken"] - self.refreshTokenExpiresAt = j["refreshTokenExpiresAt"] + if "refreshToken" in j and "refreshTokenExpiresAt" in j: + self.refreshToken = j["refreshToken"] + self.refreshTokenExpiresAt = j["refreshTokenExpiresAt"] self.userId = j["user"]["id"] logger.info("Logged in to AndroidApi successfully (expiration: %s, %s)" % (self.accessTokenExpiresAt, timeago(self.accessTokenExpiresAt))) diff --git a/tconnectsync/api/controliq.py b/tconnectsync/api/controliq.py index e6ae8b9..3737007 100644 --- a/tconnectsync/api/controliq.py +++ b/tconnectsync/api/controliq.py @@ -14,7 +14,7 @@ class ControlIQApi: BASE_URL = 'https://tdcservices.tandemdiabetes.com/' LOGIN_URL = 'https://tconnect.tandemdiabetes.com/login.aspx?ReturnUrl=%2f' - LAST_CONFIRMED_SOFTWARE_VERSION = 't:connect 7.17.1.2' + LAST_CONFIRMED_SOFTWARE_VERSION = 't:connect 7.17.2.3' userGuid = None accessToken = None @@ -51,9 +51,21 @@ class ControlIQApi: raise ApiException(fwd.status_code, 'Error retrieving t:connect login cookies.') self.userGuid = req.cookies['UserGUID'] - self.accessToken = req.cookies['accessToken'] - self.accessTokenExpiresAt = req.cookies['accessTokenExpiresAt'] - logger.info("Logged in to ControlIQApi successfully (expiration: %s, %s)" % (self.accessTokenExpiresAt, timeago(self.accessTokenExpiresAt))) + if 'accessToken' in req.cookies and 'accessTokenExpiresAt' in req.cookies: + self.accessToken = req.cookies['accessToken'] + self.accessTokenExpiresAt = req.cookies['accessTokenExpiresAt'] + logger.info("Logged in to ControlIQApi successfully via accessToken cookie (expiration: %s, %s)" % (self.accessTokenExpiresAt, timeago(self.accessTokenExpiresAt))) + else: + logger.info("No accessToken cookie found when logging in to ControlIQApi. Triggering AndroidApi auth") + + from .android import AndroidApi + android = AndroidApi(email, password) + self.accessToken = android.accessToken + self.accessTokenExpiresAt = android.accessTokenExpiresAt + + logger.info("Logged in to AndroidApi successfully via accessToken param (expiration: %s, %s)" % (self.accessTokenExpiresAt, timeago(self.accessTokenExpiresAt))) + + self.loginSession = s return True @@ -96,6 +108,9 @@ class ControlIQApi: return None def needs_relogin(self): + if not self.accessTokenExpiresAt: + return False + diff = (arrow.get(self.accessTokenExpiresAt) - arrow.get()) return (diff.seconds <= 5 * 60)