Source code for satorbis_kit.auth.token_store

import base64
import json
import time
from dataclasses import dataclass, field
from typing import Optional


[docs] @dataclass class TokenStore: access_token: Optional[str] = field(default=None, repr=False) refresh_token: Optional[str] = field(default=None, repr=False) id_token: Optional[str] = field(default=None, repr=False) token_type: str = "Bearer" expires_at: Optional[float] = None @property def is_empty(self): return self.access_token is None @property def is_expired(self): if self.expires_at is None: return True return time.time() >= self.expires_at - 60
[docs] def update_from_raw(self, raw: dict): self.access_token = raw["access_token"] self.refresh_token = raw.get("refresh_token", self.refresh_token) self.id_token = raw.get("id_token", self.id_token) self.token_type = raw.get("token_type", "Bearer") self.expires_at = raw.get("expires_at") or ( time.time() + raw.get("expires_in", 3600) )
[docs] @staticmethod def decode_jwt_payload_str(token_str: str) -> dict: """Base64-decode a JWT payload without verifying the signature.""" try: parts = token_str.split(".") if len(parts) != 3: return {} padding = 4 - len(parts[1]) % 4 padded = parts[1] + "=" * (padding % 4) return json.loads(base64.urlsafe_b64decode(padded)) except Exception: return {}
[docs] def decode_jwt_payload(self) -> dict: """Decode the access token's JWT payload without signature verification.""" if not self.access_token: return {} return self.decode_jwt_payload_str(self.access_token)