diff --git a/CHANGELOG.md b/CHANGELOG.md index 2bf26b7..90f8cc1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), ## [Unreleased] +### Added +- `timezone="auto"`: resolve the browser timezone from the proxy egress IP. A session with a proxy and no explicit timezone now defaults to `auto` — a foreign proxy paired with the host TZ is the classic `timezone_mismatch` signal. The egress IP is discovered through the proxy (SOCKS supported) and mapped to its IANA zone with an offline mmdb (`daijro/geoip-all-in-one`, downloaded + cached on first use; `STEALTHFOX_GEOIP_MMDB` points at your own). Precedence: an explicit zone wins; `""`/`"auto"` without a proxy stay on the host TZ; `"host"`/`"local"` force the host TZ even behind a proxy. With a proxy, an unresolvable zone raises rather than silently falling back. +- `resolve_session_timezone(timezone, proxy)` and `ensure_geoip_mmdb()` re-exported at the package root (plus `GeoTimezoneError`) so integrations that own their launch can reproduce the resolution. +- `tests/test_geo.py`: 32 unit tests (precedence policy, proxy→requests translation, egress discovery, IP→IANA mapping, fail-early). + +### Changed +- New runtime dependencies: `requests[socks]` (SOCKS egress lookup), `maxminddb` (mmdb reader), `tzdata` (IANA database for `zoneinfo`, which Windows lacks). + ## [0.2.0] - 2026-05-28 ### Added diff --git a/src/invisible_playwright/config.py b/src/invisible_playwright/config.py index 3fa3dc5..c411512 100644 --- a/src/invisible_playwright/config.py +++ b/src/invisible_playwright/config.py @@ -66,7 +66,10 @@ def get_default_stealth_prefs( locale: BCP-47 tag (e.g. ``"en-US"``). Drives ``Accept-Language`` and ``navigator.language``. timezone: IANA timezone (e.g. ``"America/New_York"``). Empty means - use the host TZ. + use the host TZ. This pure pref builder does NOT resolve + ``"auto"`` (that needs the proxy + a network lookup at launch + time) — pass a concrete zone here, or use ``InvisiblePlaywright`` + / ``resolve_session_timezone(timezone, proxy)`` for ``"auto"``. extra_prefs: Optional dict overlaid LAST onto the generated prefs. humanize: When True (default), every mouse move is expanded into a Bezier trajectory by the patched Juggler. A float caps the diff --git a/src/invisible_playwright/launcher.py b/src/invisible_playwright/launcher.py index d277711..6de4818 100644 --- a/src/invisible_playwright/launcher.py +++ b/src/invisible_playwright/launcher.py @@ -136,8 +136,13 @@ class InvisiblePlaywright: a float caps the motion in seconds. locale: BCP-47 tag (e.g. ``"en-US"``). Drives the ``Accept-Language`` header and ``navigator.language``. - timezone: IANA timezone (e.g. ``"America/New_York"``). Empty - means use the host TZ. + timezone: IANA zone (e.g. ``"America/New_York"``) — used as-is + when set. ``""`` (default) or ``"auto"`` resolves the zone + from the proxy egress IP when a proxy is set (one lookup + through the proxy + an offline mmdb), otherwise the host TZ. + ``"host"`` / ``"local"`` forces the host TZ even behind a + proxy. With a proxy, an unresolvable zone raises rather than + silently falling back to the host TZ (``timezone_mismatch``). extra_prefs: Optional dict of Firefox prefs overlayed on top of the generated profile — useful for niche tweaks without monkey-patching the package.