""" Auth-field normalizers — applied to the raw incoming message *before* the auth check runs. Protocol fields (pubkey, sig, …) are still present here. Add one entry per breaking auth-field change: ("X.Y.Z", transformer_fn) Entries must stay in ascending version order. """ from __future__ import annotations from typing import Callable from browser_cli.version_manager import parse_version # ── v0.9.3 ──────────────────────────────────────────────────────────────────── def _auth_0_9_3(msg: dict) -> dict: """pubkey validation tightened to lowercase hex; normalize for older clients.""" changed: dict = {} pk = msg.get("pubkey") if isinstance(pk, str) and pk: changed["pubkey"] = pk.lower() if msg.get("command") in {"browser-cli.auth.trust", "browser-cli.auth.policy"}: args = msg.get("args") or {} trust_pk = args.get("pubkey") identifier = args.get("identifier") patched = dict(args) if isinstance(trust_pk, str) and trust_pk: patched["pubkey"] = trust_pk.lower() if isinstance(identifier, str) and identifier and len(identifier) == 64: patched["identifier"] = identifier.lower() if patched != args: changed["args"] = patched return {**msg, **changed} if changed else msg # ── registry ────────────────────────────────────────────────────────────────── _AUTH_COMPAT: list[tuple[str, Callable[[dict], dict]]] = [ ("0.9.3", _auth_0_9_3), ] def adapt_auth(msg: dict, client_version: str) -> dict: """Apply all auth normalizers needed to bring msg up to the current format.""" cv = parse_version(client_version) for version, fn in _AUTH_COMPAT: if cv < parse_version(version): msg = fn(msg) return msg