Skip to content

v1.11.1 - Hardening and cleanup pass

Choose a tag to compare

@EnO33 EnO33 released this 27 Apr 07:09

Six small refactors landed across separate commits, none of them user-visible. The integration behaves identically — this release is purely about code quality and laying ground-work for #12 (token caching).

Changes

  • Stricter cookie scoping — drop unsafe=True on the aiohttp.CookieJar. We only ever talk to portal hostnames, so refusing cookies that would only resolve via IP literals is defence-in-depth at zero cost.
  • Case-insensitive host comparison in redirect handler — yarl already normalises today, but lowering both sides explicitly protects future callers from a silent regression if they pass a capitalised allowed_host.
  • Drop dead branches in _http.py — after switching tenacity to reraise=True, the RetryError and trailing raise paths became unreachable. Replaced with a single AssertionError sentinel.
  • Drop redundant runtime isinstance check in _auth_callrequest_with_retry is typed dict[str, Any] and mypy strict enforces it.
  • Split self.token into _app_token + _ael_token — the same attribute previously carried two semantically different bearer tokens (short-lived app token vs long-lived AEL session token). Splitting them makes the lifecycle obvious and unblocks token caching across coordinator polls (#12).
  • Move credentials into PortalAuth — login/password/provider were duplicated on the client and the auth helper. Now they live on the helper that actually uses them; smaller surface for accidental leaks.

Verified

  • Full local validation (ruff, mypy strict, pytest 30 passed)
  • All 5 CI jobs green at every step (Lint, Typecheck, Pytest, Hassfest, HACS)
  • Live smoke test on a Raspberry Pi against SEM (Ventabren contract) — auth + fetch + statistics path all green

Closes #15.