1212import urllib .request
1313import uuid
1414from typing import Any , Callable , Dict , Iterable , List , Literal , Optional , Sequence , TypedDict , Union
15+
16+ from typing_extensions import NotRequired
1517from cryptography .exceptions import InvalidSignature
1618from cryptography .hazmat .primitives .asymmetric .ed25519 import Ed25519PublicKey
1719
@@ -30,6 +32,11 @@ class ValidateLicenseSuccess(TypedDict):
3032 app_variables : Optional [Dict [str , Any ]]
3133 license_variables : Optional [Dict [str , Any ]]
3234 key_id : Optional [str ]
35+ session_expires_at : NotRequired [str ]
36+ license_expires_at : NotRequired [Optional [str ]]
37+ max_hwid_slots : NotRequired [int ]
38+ hwid_count : NotRequired [int ]
39+ license_label : NotRequired [str ]
3340
3441
3542class ValidateLicenseFailure (TypedDict ):
@@ -158,7 +165,7 @@ def validate_license(self, license_key: str) -> ValidateLicenseResult:
158165 response_obj = self ._post_json ("/auth/validate" , body , skip_failure_hook = True )
159166 expected_nonce = str (body .get ("nonce" , "" )).strip ()
160167 parsed = self ._parse_validate_success (response_obj , expected_nonce )
161- return {
168+ result : ValidateLicenseSuccess = {
162169 "valid" : True ,
163170 "session_token" : parsed ["session_token" ],
164171 "expires_in" : parsed ["expires_in" ],
@@ -167,6 +174,17 @@ def validate_license(self, license_key: str) -> ValidateLicenseResult:
167174 "license_variables" : parsed ["license_variables" ],
168175 "key_id" : parsed ["key_id" ],
169176 }
177+ if "session_expires_at" in parsed :
178+ result ["session_expires_at" ] = parsed ["session_expires_at" ]
179+ if "license_expires_at" in parsed :
180+ result ["license_expires_at" ] = parsed ["license_expires_at" ]
181+ if "max_hwid_slots" in parsed :
182+ result ["max_hwid_slots" ] = parsed ["max_hwid_slots" ]
183+ if "hwid_count" in parsed :
184+ result ["hwid_count" ] = parsed ["hwid_count" ]
185+ if "license_label" in parsed :
186+ result ["license_label" ] = parsed ["license_label" ]
187+ return result
170188 except Exception as exc :
171189 return {"valid" : False , "code" : str (exc ), "error" : str (exc )}
172190
@@ -345,7 +363,7 @@ def _parse_validate_success(
345363 if expires_in is None :
346364 raise ValueError ("missing_expiresIn" )
347365
348- return {
366+ out : Dict [ str , Any ] = {
349367 "session_token" : session_token ,
350368 "expires_in" : int (expires_in ),
351369 "session_data" : dict (payload_json ),
@@ -357,6 +375,26 @@ def _parse_validate_success(
357375 "raw_payload_b64" : raw_payload_b64 ,
358376 "signature" : signature ,
359377 }
378+ se = payload_json .get ("sessionExpiresAt" )
379+ if isinstance (se , str ) and se != "" :
380+ out ["session_expires_at" ] = se
381+ if "licenseExpiresAt" in payload_json :
382+ le = payload_json ["licenseExpiresAt" ]
383+ out ["license_expires_at" ] = le if isinstance (le , str ) else None
384+ if "maxHwidSlots" in payload_json :
385+ try :
386+ out ["max_hwid_slots" ] = int (payload_json ["maxHwidSlots" ])
387+ except (TypeError , ValueError ):
388+ pass
389+ if "hwidCount" in payload_json :
390+ try :
391+ out ["hwid_count" ] = int (payload_json ["hwidCount" ])
392+ except (TypeError , ValueError ):
393+ pass
394+ ll = payload_json .get ("licenseLabel" )
395+ if isinstance (ll , str ) and ll != "" :
396+ out ["license_label" ] = ll
397+ return out
360398
361399 def _apply_signed_response (
362400 self ,
0 commit comments