After the client_id change, extract_jwt still validates the id_token
audience against TDC_OIDC_CLIENT_ID (the OIDC-standard case). But since
the token exchange wasn't captured, we can't be certain Tandem sets
aud=client_id on the id_token. If it doesn't, fall back to decoding with
verify_aud disabled (signature + issuer still verified) and log a
warning, rather than failing login outright.
The Tandem Source web app now authenticates with client_id
0oa4wnbvtladeyVZX4h7 (US); the old 0oa27ho9tpZE9Arjy4h7 no longer
appears in the current build. This value is used both for the OIDC
authorize/token requests and the id_token audience check, which stay
consistent. EU client_id left unchanged (no EU capture to verify).
Match the Tandem Source web app's getLogIDList() as observed in the live
GET api/reports/bff/pump-logs request (from the captured HAR). Adds the
FSL3 event ids 477 (join), 480 (data), 486 (stop); reorders to match the
frontend. No removals (was 52 ids, now 55).
Annotate the 11 event processors, the ProcessTimeRange orchestrator, and
UpdateProfiles. The shared processor interface is now typed:
__init__(tconnect, nightscout, tconnect_device_id, pretend, features),
enabled() -> bool, process(events, time_start, time_end) -> List[dict],
write(ns_entries) -> int. Converter helpers return Optional[dict] since
they fall through to None on type mismatch.
ProcessTimeRange.process() returns Tuple[int, Optional[int]] and its
tconnectDevice param reuses the PumpEventMetadata TypedDict. Client
params (TConnectApi/NightscoutApi/BaseEvent) use TYPE_CHECKING-guarded
imports with string forward refs to avoid import cycles at runtime.
Annotate NightscoutApi methods and the module-level date helpers. Adds a
DateLike alias (str | datetime | arrow.Arrow) for the timestamp/filter
params. Writers return None; the last_uploaded_* getters return
Optional[dict]; api_status/current_profile return dict.
Response shapes are kept as loose dict/Optional[dict] rather than
TypedDicts since the Nightscout API shape varies across versions; only
inputs (which we control) are tightly typed.
Annotate method signatures and dynamic JSON response types. Adds
TypedDicts for the responses whose shapes are confirmed from call sites
and logs:
- PumpEventMetadata (+ nested LastUpload) for pump_event_metadata()
- JwtClaims for the decoded id_token stored on jwtData; pumperId and
accountId are UUID strings, not ints
pump_events_raw() returns a base64 str (not Any). pumper_info() stays
Any since it has no callers and its shape is never logged. TypedDict is
imported with a typing_extensions fallback for Python 3.7.
api_headers() hardcoded Origin/Referer to tconnect.tandemdiabetes.com,
but requests target SOURCE_URL (source.tandemdiabetes.com /
source.eu.tandemdiabetes.com). The WAF enforces same-origin and
returned HTTP 403 ("The request is blocked"). Derive Origin/Referer
from SOURCE_URL so both US and EU regions match.