Commit Graph
100 Commits
Author SHA1 Message Date
CloakHQ 42924aaf99 fix(cli): don't report a false launch failure in info on Windows
Chromium only handles --version on POSIX, so on Windows the switch is
ignored and a browser starts instead of printing. The 10s probe then
timed out and a healthy install was reported as broken, flashing a
window on screen each run.

Probe with --no-startup-window there: it exits immediately, opens no
window, and a broken binary still exits non-zero. No version is
reported on Windows, as nothing is printed. Linux and macOS unchanged.

Test uses a stub that hangs unless the flag is passed, mirroring the
real binary rather than a print-and-exit stub.
2026-07-26 19:27:53 +02:00
CloakHQ a5f2c33ff9 release: v0.5.2 — preview release channel + Chromium 150.0.7871.114.4 (Linux) 2026-07-25 08:35:34 +02:00
CloakHQ 240bf61bec feat(cli): print the wrapper version in info across all wrappers 2026-07-25 00:53:09 +02:00
CloakHQ 69a168ae0a test: isolate Python/JS suites from the real ~/.cloakbrowser
A license.key or cached Pro marker in the developer's cache dir resolved the
box as Pro, flipping version-gated defaults (headless no_viewport, inline proxy
auth) and failing 9 Python + 4 JS tests locally. Both suites now run against a
temp cache dir.
2026-07-24 19:52:07 +02:00
CloakHQ f709dba519 feat: add preview release channel across all wrappers
Add a preview release channel system to all wrappers (Python, JavaScript, .NET),
allowing users to opt into newer binary builds before they go stable.

- Python: preview/stable channel resolution in download, launch, CLI
  (install, update, clear-cache), and license validation
- JavaScript: preview/stable channel in CLI, launch, license, and config
- .NET: preview/stable channel in CLI, license, diagnostics, and config
- All wrappers: channel fallback indicator, auto-update gate,
  CLOAKBROWSER_RELEASE_CHANNEL env var support
- Harden channel resolution: reuse the resolution sidecar on offline lookups,
  defensive marker/JSON parsing, atomic version-marker writes, a launch-time
  preview-to-stable fallback notice, channel-aware info download URL, and
  Python/JS/.NET parity for the fallback default
- Binary 150.0.7871.114.4 changelog (Linux x64 + arm64)
- Updated READMEs, CHANGELOG, and tests for all wrappers
2026-07-24 11:47:28 +02:00
CloakHQ c6673e3eda feat(cloakserve): on-demand close endpoint (POST /fingerprint/{seed}/close)
Adds ChromePool.terminate_seed() + a close route that tears down one seed's
Chrome immediately and frees its slot, instead of waiting out the idle timeout.
Profile is preserved (goes through _cleanup_process). Idempotent.
2026-07-23 03:57:42 +02:00
CloakHQ 36390b5359 release: v0.5.1 — geoip CONNECT Host header fix (js) 2026-07-23 03:36:36 +02:00
CloakHQ d640970d4a fix(geoip): send tunnel target in CONNECT Host header (js)
Node derives Host from the proxy hostname unless set explicitly; strict
backconnect proxies reject the mismatch, silently falling back to the
gateway's geo instead of the real exit IP.
2026-07-23 03:31:16 +02:00
CloakHQ efe6f503a0 release: v0.5.0 — free tier via GitHub sign-in + geoip raw-flag fix 2026-07-22 22:20:03 +02:00
CloakHQ 1b1e349815 feat(free-tier): GitHub-login free tier across all three wrappers
cloakbrowser login gets a free key via GitHub sign-in (or saves a paid key); logout reverts. Launch banner and info are now tier-aware (keyless / free / pro). A free key drops any version pin so it always gets the latest build (server force-serves latest; a pinned manifest would fail checksum). Python, JS, and .NET kept in sync. README documents the free tier + commands.
2026-07-22 22:02:09 +02:00
CloakHQ 0c2d19183a fix(geoip): preserve explicit tz/locale raw flags in args over geoip
A raw --fingerprint-timezone/--lang/--fingerprint-locale in args is now
promoted to an explicit value in maybe_resolve_geoip, so geoip only fills
the values the user did not set. Mirrors the timezone=/locale= param path.
Python, JS, and .NET, with tests.
2026-07-22 07:38:15 +02:00
CloakHQ a554a97b24 release: v0.4.13 — geoip DB refresh fix + drop 7-day trial copy 2026-07-22 04:10:39 +02:00
CloakHQ b90e249793 fix(geoip): quote cloakbrowser[geoip] in user-facing error messages
zsh globs the unquoted bracket, so a user copy-pasting the printed
install hint hits a shell error. Quote it in both messages; update the
test that pinned the old string.
2026-07-22 03:34:24 +02:00
CloakHQ d290c2ac57 fix(geoip): atomic DB replace + single-download guard (#458)
geoip.py used Path.rename which cannot overwrite on Windows, so a stale
DB never refreshed and every launch re-downloaded ~70 MB in a loop. No
lock meant concurrent launches each fired their own download.

- Python: os.replace + threading.Lock (initial + background paths)
- .NET: File.Move(overwrite) + SemaphoreSlim guard
- JS: shared in-flight promise (rename already overwrites)
- tests: overwrite + concurrent single-download coverage

pyproject: bump classifier to Production/Stable
2026-07-22 03:15:35 +02:00
CloakHQ fd2b6024c6 release: v0.4.12 — Chromium 150 version facts + banner fix
Points the READMEs at 150 as the latest Pro binary (71 patches, all five
platforms) and bumps the Pro major in the launch banner and the info
upgrade hint across Python, JS, and .NET.
2026-07-18 23:30:16 +02:00
CloakHQ 86d1d76b81 release: v0.4.11 — proxy auth + license errors + info session count 2026-07-16 12:51:16 +02:00
CloakHQ d2a72f1238 feat(cli): show active session count in info
A Pro license now gets a "Sessions: N seats in use" line, answering
"how many sessions do I have running?" without asking support.

Never cached (a cached count is a wrong count), skipped under --quick to
keep `info` network-free, and prints "unavailable" rather than a made-up
number when the count cannot be determined.

Python, JS and .NET.
2026-07-15 06:02:17 +02:00
CloakHQ ca232fd598 feat(license): surface Pro binary license failures as clear errors
The Pro binary exits with a distinct code per license failure; the wrappers ignored it, so a user got a bare "browser closed" error with no reason.

Add CloakBrowserLicenseError plus a launch-error parser that maps the exit code to a clear message, mirrored across the Python, JS, and .NET wrappers. Non-license failures pass through unchanged.
2026-07-15 01:22:13 +02:00
CloakHQ 2e379e402b docs: update BINARY-LICENSE to v1.3
Discretionary refusal/revocation, fair-use throttle, trial-abuse ban
(stacking paid subs explicitly allowed), suspend pending investigation,
self-amendment clause. Acceptable Use + Indemnification party lists
aligned with Disclaimer/Limitation of Liability.
2026-07-14 23:53:09 +02:00
CloakHQ 111b725e8c Fix authenticated HTTP proxies across all platforms
Route authenticated HTTP/HTTPS proxies through the browser's native proxy
authentication only on binaries that support it, resolved per platform and
binary version via a capability gate (sibling to the existing viewport and
window-geometry gates). Older binaries, including the free macOS and ARM
builds, fall back to the standard Playwright proxy path instead of emitting
credentials the binary cannot parse, so authenticated proxies keep working on
macOS and ARM instead of silently failing. Applied across the Python,
JavaScript, Puppeteer, and .NET wrappers.
2026-07-11 02:11:08 +02:00
CloakHQ 08415d9b26 release: v0.4.10 — iframe humanize + JS CLI npx fixes (#427, #428) 2026-07-09 23:21:52 +02:00
CloakHQ 3c3e0f477c docs: update BINARY-LICENSE to v1.2 (version-agnostic terms, pricing and key clauses) 2026-07-09 23:09:25 +02:00
CloakHQ 1ae7605a43 fix: humanize=True resolves iframe locators in the owning frame (#428)
With humanize=True, Locator/frame actions on an element inside an iframe
(frame.locator("#btn").click(), fill(), hover(), the frame.click(...)
equivalents) raised ElementNotAttachedError because the humanize layer
resolved every selector against the main frame. Route sub-frame locators
and frame-level actions through the owning frame's own document, keeping
humanized mouse motion inside the iframe; native fallback when the box
can't be read or the frame is detached. Python only (JS and .NET were
already frame-correct).

Adds mocked routing unit tests (sub-frame -> owning frame, main-frame ->
page, unpatched -> native), the human_click arg-order + _frame_fill
fallback guards, and @slow real-binary iframe integration tests.
2026-07-09 20:36:24 +02:00
CloakHQ 045219b488 fix: JS CLI silently exited via npx/symlinked bin (#427)
Entry-point guard compared import.meta.url to an unresolved process.argv[1];
Node resolves import.meta.url through symlinks but argv[1] stays as invoked,
so npm/pnpm/npx bin symlinks never matched and no subcommand ran. Realpath
the invoked path before comparing.
2026-07-09 03:40:40 +02:00
CloakHQ 0624df83fc release: v0.4.9 — Pro trial promo, info/update version parity, font check fixes 2026-07-09 03:10:53 +02:00
CloakHQ 0664bd8d0c feat: promote 7-day Pro trial in banner, CLI hint, and READMEs
Free-tier launch banner and 'cloakbrowser info' upgrade hint now advertise
the 7-day free Pro trial (Chromium 148) across Python, JS, and .NET; same
CTA added to both READMEs. Also surface binary verification failures verbatim
instead of falling back to a cached build (transient-only fallback).
2026-07-08 22:13:34 +02:00
CloakHQ a00bccac78 fix: info/update never diverge from the Pro build that actually launches
info now shows the cached build that will launch AND the server's latest
Pro version on separate lines, so the two can no longer silently diverge
(a customer saw info report latest while launch ran a stale cache).

- Pro version resolution: unpinned launch prefers the server latest when it
  is newer than or replaces a missing cached build, else stays on cache;
  advances the version marker so info and later offline launches match.
- update command is license-aware: a valid Pro key updates the Pro binary,
  everyone else updates free.
- Replace the fire-and-forget Pro background update thread with a foreground
  rate-limited check (one network call/hour), honoring CLOAKBROWSER_AUTO_UPDATE=false.
- A valid Pro license never falls back to the free binary: get_effective_version
  returns None when no Pro build is cached; resolution fails loudly instead.
- Tampering signal (BinaryVerificationError) surfaces verbatim on the unpinned
  upgrade path — the cached-Pro fallback is only for transient download failures.
- get_effective_version(pro) requires the binary be executable, so info can't
  report a build launch would reject.
- info --quick stays network-free (skips the server latest lookup); prints a
  'not downloaded yet' line instead of 'None' when offline with no cache.
- Align the JS .last_update_check marker to seconds (Python/.NET parity).
- Mirror across Python, JS, and .NET wrappers; add update/CLI tests.
2026-07-08 18:57:38 +02:00
CloakHQ ae7fd43be7 feat: info/doctor reports Windows + Office font completeness
Windows font check now covers the full 8-font set (adds the two monospace
fonts) and reports a strict N/8 count; the launch-time warning fires on any
incomplete set, not just when none are present. Adds a separate Office-font
group (10 fonts) reported as an informational N/10 with no install nudge.

Ported across all three wrappers (Python, JS, .NET) to keep them in sync.
2026-07-07 21:58:01 +02:00
CloakHQ 5a1e2978e4 docs: add 215.5 binary changelog entry + license-through-proxy 'for now' note 2026-07-05 22:10:52 +02:00
CloakHQ 330d7b851e release: v0.4.8 — geoip works proxy-free (132 locales) + maximized window + flag docs 2026-07-05 21:32:31 +02:00
CloakHQ 01c6105128 fix: harden geoip proxy-free + maximize parity (review follow-ups)
Follow-up fixes for the geoip-no-proxy and start-maximized commits:

- geoip: resolve the egress IP before the DB check so a DB-download failure
  still yields the WebRTC exit IP — the proxy WebRTC spoof survives a DB hiccup
- geoip: skip the exit-IP echo call on no-proxy + explicit tz/locale (the WebRTC
  IP would just be the real connection IP the site already sees — a no-op)
- launch_context: suppress auto --start-maximized when the caller set an explicit
  viewport, matching JS across Python and .NET
- docker: poll for X readiness before starting openbox instead of a blind sleep
  (avoids a silent window-manager startup race)
- refactor: extract the WebRTC exit-IP append into one helper per wrapper
- remove a dead isPrivateIp in the JS wrapper
- tests: fix stale no-proxy geoip assertions; add launch_context parity + .NET
  geoip coverage

Python, JS and .NET wrappers kept in parity.
2026-07-04 23:21:20 +02:00
CloakHQ d029f2170f feat: open the browser window maximized on 148.0.7778.215.4+ builds
Default headed and headless launches to a maximized window (fills the
screen) on binaries at or above the same threshold as the headless
no-viewport default. Suppressed when the caller sets --window-size /
--window-position / --start-maximized or an explicit viewport; older
builds are unchanged. Version-gated via a dedicated helper sharing the
no-viewport threshold. Mirrored across Python, JS and .NET with parity tests.

The Docker image runs openbox so headed --start-maximized is honored
(bare Xvfb has no window manager; headless is unaffected).
2026-07-04 22:11:43 +02:00
CloakHQ 88d62e04ca feat: geoip works without a proxy + expand locale map to 132 countries
When geoip=True and no proxy is set, resolve the machine's own public IP
directly (echo services, no proxy) and use it for timezone, locale, and the
WebRTC exit IP — same path as the proxied case. Previously geoip no-oped
without a proxy, leaving UTC + en-US in bare Docker/cloud launches.

Expand COUNTRY_LOCALE_MAP from 50 to 132 countries across all three wrappers
(Python, JS, .NET) so far more egress IPs resolve a locale.

Mirrored in cloakbrowser/, js/src/, and dotnet/. Tests added for the no-proxy
resolution path.
2026-07-04 05:13:53 +02:00
CloakHQ a3e0994a31 release: v0.4.7 — update cloaktest 2026-07-03 00:17:18 +02:00
CloakHQ 49a9cfc51b release: v0.4.6 — pass Pro license key to browser process + version-gated headless viewport 2026-07-02 20:12:30 +02:00
CloakHQ f54c870a88 feat: version-gate headless no_viewport across all three wrappers
Headed launches already skip Playwright's emulated viewport (no_viewport)
because a fixed CDP viewport on a real window forces outerWidth < innerWidth,
a physically impossible geometry that's a bot tell. Headless historically kept
a fixed DEFAULT_VIEWPORT since there's no window chrome to make coherent
without emulation — but a newer Chromium build (>=148.0.7778.215.4) now
reports coherent dimensions in headless too, so it can drop the emulated
viewport the same way headed does.

Added binary_supports_headless_no_viewport() (mirrored in Python, JS, .NET) to
gate this per resolved binary version: local overrides with no declared
version stay on the old fixed-viewport path (unknown version = safe default),
while an explicit browser_version/CLOAKBROWSER_VERSION always wins so internal
builds can opt in. HEADLESS_NO_VIEWPORT_MIN_VERSION is currently set to a
version that hasn't shipped yet, so this is a no-op until that build is live —
behavior is byte-identical to today for every existing binary.
2026-07-02 03:47:11 +02:00
CloakHQ 60d978826c fix: pass Pro license key to browser process
- Pass the resolved license key via environment (CLOAKBROWSER_LICENSE_KEY)
  when launching the Chromium binary so the Pro binary can authenticate.
- Inject key when a custom user_env is provided with default file source:
  Playwright replaces (not merges) the child env, which can drop HOME and
  prevent the binary from finding ~/.cloakbrowser/license.key.
- Normalize user_env by filtering None/undefined values consistently across
  Python, JS, and .NET wrappers.
- Add HomeDirOverride test seam to the .NET wrapper for cache path mocking.
2026-07-01 07:41:23 +02:00
CloakHQ b4fdf63bd8 release: v0.4.5 — info diagnostics command + Windows-font notice 2026-06-29 01:28:38 +02:00
CloakHQ bd7f0797ed feat: expand info CLI into a launch-aware diagnostics command
info (plus a doctor alias) now reports the binary that will actually
launch for the resolved license instead of whatever is cached on disk:
it resolves and validates the license, shows the real tier, and on a
keyless or invalid key reports the free binary. Adds a launch test
(chrome --version) with a Linux missing-shared-library probe, a
Windows-font check (Linux only), GeoIP DB presence, and optional-dep
checks. --quick skips the launch test; --json emits machine output.
Python, JS, and .NET, with tests.
2026-06-29 00:54:38 +02:00
CloakHQ 18eedeeb17 feat: warn on Windows-spoof without Windows fonts on Linux + free banner cadence
One-time, suppressible startup warning when spoofing Windows on a Linux host
with no Windows fonts detected (fc-list probe of the documented base set),
across Python, JS, and .NET. The first-launch banner now re-shows to free
users every 3 days; Pro users still see it once.
2026-06-28 23:15:38 +02:00
CloakHQ b502301b28 docs: update FPJS detection table wording for persistent contexts 2026-06-28 02:17:07 +02:00
CloakHQ a8dc0caf7a release: v0.4.4 — version pinning/rollback + per-OS Pro resolution, Chromium 148.0.7778.215.3 2026-06-28 00:06:40 +02:00
CloakHQ 5d222e5b0b feat: send X-Platform on Pro version check for per-OS latest resolution
The version-check request (get_pro_latest_version) now sends the platform
tag so the server can return a per-OS LATEST pointer, letting us advance
one OS at a time. Mirrored across Python, JS, and .NET clients; older
clients send no header and keep tracking the global LATEST floor.
2026-06-26 20:47:37 +02:00
CloakHQ 2c7543d6e9 feat: add exact version pinning via browser_version param and CLOAKBROWSER_VERSION env
Pro/Free users can pin a specific Chromium version:
  launch(browser_version='148.0.7778.215.2')
  CLOAKBROWSER_VERSION=148.0.7778.215.2

- normalize_requested_version() validates version format (4-5 segs, no path traversal)
- Free path: downloads pinned version from public URL
- Pro path: routes pinned version through existing license validation API
- Pinning does NOT overwrite the 'latest' version marker
- JS: browserVersion option, normalizeRequestedVersion(), env support
- .NET: BrowserVersion option, NormalizeRequestedVersion(), env support
2026-06-26 19:11:07 +02:00
CloakHQ 0bb3737a29 docs(readme): add star history chart + separate .NET note 2026-06-24 07:19:44 +02:00
CloakHQ ad2f768774 release: v0.4.3 — .NET 8 client + macOS Pro
- .NET 8 / C# client published to NuGet (PR #385, @evelaa123)
- macOS Pro binary now available (darwin arm64 + Intel), so Pro downloads
  the latest build on every platform
- README: Platforms table split into Free/Pro; drop the stale Roadmap and the
  macOS-fingerprint troubleshooting note
2026-06-24 01:11:00 +02:00
CloakHQ 1247828889 feat(download): ship macOS Pro binary, drop the macOS free-fallback stopgap
The macOS Pro build (darwin arm64 + Intel) is now served alongside Linux and
Windows, so a Pro license downloads the latest binary on macOS like every
other platform.

Reverts the v0.4.2 stopgap that, on macOS only, silently fell back to the free
binary when the Pro download returned 404 (there was no macOS Pro build yet). A
valid license now hard-fails on any Pro download error on every platform — no
silent downgrade — restoring the wrapper's stated invariant. Applied across the
Python, JS, and .NET wrappers; removes the now-unused DownloadHttpError type and
its tests.

README: macOS listed as available for Pro.
2026-06-24 00:37:49 +02:00
CloakHQ 0bbbaf3634 docs(readme): mention the .NET client (now on NuGet) + polish the package readme
Main README: add the .NET / C# install block + credit the .NET client.
dotnet/README (NuGet page): fix license-key example (ck_live_ -> cb_),
add free/Pro tier framing + plans link, add a persistent-context example,
drop the repo-only pre-install/CLI commands for package consumers.
2026-06-23 21:53:24 +02:00
CloakHQ d981897e1c ci: publish .NET client to NuGet + gate PRs on dotnet build/test
- ci.yml: build + test the dotnet client on every push/PR
- publish.yml: publish-nuget job (OIDC trusted publishing via NuGet/login),
  wire the workflow_dispatch job selector so single jobs can run,
  validate tag == csproj <Version>
- csproj: pack dotnet/README.md as the NuGet package readme
2026-06-23 20:43:30 +02:00
CloakHQ 7e9388e981 release: v0.4.2 — macOS Pro license falls back to free binary 2026-06-23 10:46:48 +02:00
CloakHQ 343a3e8e28 fix(download): fall back to free binary on macOS when Pro 404s
A Pro license on macOS currently has no binary to download. Rather than
hard-failing a paying customer, fall back to the free binary with a clear
notice. Scoped to the 404 case only: transient and checksum-verification
failures still hard-fail (no silent downgrade), and once the macOS Pro
build ships the 404 disappears and Pro is served automatically.

JS side adds DownloadHttpError to carry the HTTP status through fetch's
generic error path so the 404 can be distinguished from transient failures.
2026-06-23 10:41:04 +02:00
CloakHQ 6acd9fe277 release: v0.4.1 — humanize headed-scroll fix, Widevine Docker auto-fetch 2026-06-23 03:43:06 +02:00
CloakHQ 61365cea48 feat(docker): opt-in Widevine CDM auto-fetch for persistent contexts
Add bin/fetch-widevine.py — a stdlib-only fetcher that pulls the Widevine CDM from Google's component server (arch-aware, sha256-verified, atomic, cached). The Docker entrypoint runs it when CLOAKBROWSER_FETCH_WIDEVINE is set (off by default), exporting CLOAKBROWSER_WIDEVINE_CDM so persistent profiles get a working CDM without a local Chrome to copy from. Fail-soft; skips when a CDM is already set or CLOAKBROWSER_WIDEVINE=0. Bare-metal Linux users can run the script directly. README: document the flag, drop the outdated storage-quota note.
2026-06-23 03:13:22 +02:00
CloakHQ 8570deaa19 chore: promote Pro tier in first-launch banner, drop header badge 2026-06-23 03:09:36 +02:00
CloakHQ 9c3ed2dcba fix(humanize): fall back to window dims when viewport is null
Headed launches default to no_viewport, so page.viewport_size is None and
human scroll raised "Viewport size not available". Fall back to live
window.innerWidth/innerHeight. Covers Playwright (py sync/async, JS) and
Puppeteer paths.
2026-06-23 01:34:07 +02:00
CloakHQ 29679a73bf docs(readme): refresh test-results stamp to Jun 2026 / Chromium 148 2026-06-22 04:05:36 +02:00
CloakHQ db9eb4bbf0 chore: prepare 0.4.0 — version bump, Pro tier changelog + README + license v1.1 2026-06-22 03:08:27 +02:00
CloakHQ 10f492e95b feat: add Pro tier license validation and download routing 2026-06-21 04:08:45 +02:00
CloakHQ 660b6bf58c feat(security): verify binaries with pinned Ed25519 signature on SHA256SUMS
Replace the same-origin checksum with a detached Ed25519 signature
(SHA256SUMS.sig) verified against a pinned public key before extraction,
closing #308: a compromised download mirror can no longer certify a
tampered binary. The signed manifest also binds the release version,
rejecting a forced downgrade to an older signed build.

Verification is mandatory and non-bypassable on the official download path;
custom CLOAKBROWSER_DOWNLOAD_URL mirrors keep the legacy skippable checksum.
Silent auto-update is preserved for everyone because only a constant public
key is pinned, not per-version hashes. Older installed wrappers are
unaffected — the version= line is ignored by their checksum parser.

Python uses cryptography; JS uses node:crypto. Adds tamper, downgrade, and
fail-closed tests in both languages.
2026-06-21 02:42:18 +02:00
CloakHQ 50bf14b3f9 fix(wrapper): track real window geometry on headed launches
Headed launches applied a fixed emulated viewport on top of the real
browser window, yielding outerWidth < innerWidth (an impossible window).
Default headed new_page()/new_context() to no_viewport so the page tracks
the real window; headless keeps a deterministic viewport. Covers Python
launch/launch_context/launch_persistent_context (+async) and the JS
Playwright/Puppeteer wrappers. Explicit viewport still honored.
2026-06-20 22:53:53 +02:00
CloakHQ d67c21abbe refactor: remove optional patchright backend
Patchright scored identically to plain Playwright on reCAPTCHA v3 (the
binary handles stealth at C++ level) while breaking proxy auth and
add_init_script (#27). Removed the backend param, CLOAKBROWSER_BACKEND
env var, the patchright extra, and the two backend-specific tests.
Stock Playwright is now the only backend.
2026-06-20 21:50:22 +02:00
CloakHQ 776630e08b release: v0.3.32 — Windows extraction security fix, Widevine CDM seeding, cloakserve fixes 2026-06-20 03:17:07 +02:00
CloakHQ 402a884088 fix(download): pass extract paths to PowerShell via env vars
Windows zip extraction interpolated archive/dest paths directly into the
PowerShell -Command string. A single quote in the path (e.g. a Windows
account like C:\Users\O'Brien) closed the string literal early, breaking
extraction and creating a code-injection shape. execFileSync guards the
OS-shell boundary but not the PowerShell interpreter inside.

Pass both paths via env vars ($env:CB_ARCHIVE / $env:CB_DEST) so
PowerShell reads them as data, never as code. No escaping needed.

Python wrapper unaffected (zipfile module + argv).
2026-06-20 02:19:48 +02:00
CloakHQ 39db492b04 fix(examples): wait for reCAPTCHA score to render before screenshot (#374)
networkidle raced the async scoring and the dead button-click never ran.
Wait on the rendered result instead. Verified 4/4 in Docker.
2026-06-15 17:58:50 +02:00
CloakHQ b06499b0c1 test(humanize): deterministic timing for password CDP test
Zero typing_delay so the '!'-uses-CDP assertion no longer races the
5s default timeout under random thinking-pauses + CI load. Test only
checks which chars route through CDP, not timing.
2026-06-09 17:38:09 +02:00
CloakHQ dcf9ba55d6 feat(widevine): auto-seed CDM hint file for persistent contexts (Linux)
Sideloaded Widevine works on the first launch of a persistent context
instead of needing a manual two-launch hint-file workaround. The wrapper
writes Chromium's CDM hint file into the profile before launch when a
WidevineCdm directory is present next to the binary.

- New cloakbrowser/widevine.py and js/src/widevine.ts: resolve a sideloaded
  CDM (CLOAKBROWSER_WIDEVINE_CDM env var, else next to the binary) and seed
  the hint file. Linux only; no-op elsewhere. CLOAKBROWSER_WIDEVINE=0 disables.
- Never bundles/downloads/copies the CDM (proprietary); seeds only when the
  user-provided CDM is already present.
- Wired into launch_persistent_context[_async] and launchPersistentContext.
- README + js/README: Widevine / DRM section, env vars, FPJS tradeoff note.
- Tests: tests/test_widevine.py, js/tests/widevine.test.ts, persistent-context
  integration assertions.
2026-05-29 22:59:59 +02:00
CloakHQ 0caa14bf7b release: v0.3.31 — proxy credential routing, humanize iframe fixes 2026-05-26 20:30:28 +02:00
CloakHQ 2a99081850 docs: add recommended config to quick-start, FPJS troubleshooting, update contributors
- Add production-ready snippet (proxy, geoip, headless, humanize) near top of both READMEs
- Add "Detected by FingerprintJS?" troubleshooting with verified flags:
  noise=false, screen dimensions, storage quota, geoip, residential proxy
- Add @sparanoid to contributors (Docker Xvfb lock fix)
- Update @eofreternal credit (iframe pointer-events fix)
- Fix stale "48 patches" in JS README
2026-05-26 18:46:13 +02:00
CloakHQ 7fc577e5c6 fix(humanize): port #303 iframe pointer-events fix to Python
Mirror the JS fix from #303 in the sync and async Python actionability
checks: compute and apply the iframe coordinate offset before
elementFromPoint, and fail open when the check itself cannot run. Add
fail-open regression tests for both Python and JS.
2026-05-25 01:17:05 +02:00
CloakHQ 0f3dc7201b chore(deps): bump JS dev dependencies
puppeteer-core 21→25 (fixes CVEs in tar-fs, ws),
typescript 5→6, @types/node 20→25, playwright-core 1.58→1.60.
Vitest stays on v1 (v4 breaks dynamic import mocking).
2026-05-24 23:57:47 +02:00
CloakHQ 41be4e0e30 chore(ci): add pip and npm ecosystems to Dependabot 2026-05-24 23:17:45 +02:00
CloakHQ 58ccdb683c fix(humanize): use shared deadline for timeout budget in frame and ElementHandle methods (#307)
Frame-level methods (click, dblclick, hover, dragAndDrop) passed the raw
timeout to each sequential operation independently, causing 3x actual
wait time when elements don't exist. ElementHandle methods had a similar
2x issue between actionability and pointer-events checks.

Port the deadline + remainingMs() pattern already used by page-level
methods. Also fix bot detection test selector after site added a hidden
duplicate submit button.
2026-05-24 23:12:07 +02:00
CloakHQ 8028ddefef feat: route HTTP proxy credentials through --proxy-server
Bypass Playwright's CDP Fetch.authRequired interceptor for authenticated
HTTP proxies by passing inline credentials via Chrome's --proxy-server
flag. Chrome sends Proxy-Authorization preemptively, avoiding the 407
round-trip that breaks on some proxies and Google domains (#182).

Gated on platform (linux-x64, windows-x64) and binary version >= 146.0.7680.177.5.
Unsupported platforms fall back to Playwright's proxy dict.
Puppeteer falls back to page.authenticate() on unsupported platforms.
2026-05-21 05:51:03 +02:00
CloakHQ 7e626ee7a1 release: v0.3.30 — binary 146.0.7680.177.5, rendering consistency fixes 2026-05-21 05:09:10 +02:00
CloakHQ b91274cc98 release: v0.3.29 — extension loading, composable JS helpers, cloakserve origin guard 2026-05-20 08:26:04 +02:00
CloakHQ 7a9a61d4de feat(js): add launchPersistentContext to Puppeteer wrapper (#261)
Expose userDataDir support via launchPersistentContext() for
cloakbrowser/puppeteer, matching the existing Playwright API.
Includes proxy auth, geoip, and humanize support.
2026-05-18 18:32:45 +02:00
CloakHQ 0437a3f1f5 docs: update contributors and add extension_paths examples 2026-05-15 21:18:49 +02:00
Cloak-HQ b0ea580cba feat(humanize): add Playwright-style actionability checks (#228)
* feat(humanize): add Playwright-style actionability checks to all interaction methods

Humanized locator/page methods now perform pre-action validation matching
Playwright's native behavior: attached, visible, enabled, editable, stable,
and receives-pointer-events checks with retry loop and backoff.

- New error hierarchy: ActionabilityError base with ElementNotAttachedError,
  ElementNotVisibleError, ElementNotStableError, ElementNotEnabledError,
  ElementNotEditableError, ElementNotReceivingEventsError
- force=True parameter skips all actionability checks (matches Playwright)
- Shared deadline across all steps (checks + scroll + stable + pointer)
- Post-scroll stability check only runs when scroll actually happened
- Chained methods (type/fill/check/uncheck/press) skip inner click checks
  but still run pointer-events check at actual click coordinates
- Frame methods now forward kwargs (force, timeout, human_config)
- Locator patches forward force via _forward_kwargs
- Python sync + async, JS/TS implementation

* fix(humanize): forward human_config in all chained methods, use evaluate args in handle pointer checks

- Add human_config=kwargs.get("human_config") to check/uncheck/select_option/press inner calls (sync+async+JS)
- Convert check_pointer_events_handle from f-string interpolation to evaluate args pattern (sync+async+JS)

* fix(humanize): strip custom kwargs before forwarding to Playwright select_option

originals.select_option(**kwargs) passes human_config/force to Playwright
which rejects unknown kwargs with TypeError.
2026-05-15 20:57:17 +02:00
CloakHQ 6f4f92e7c7 fix(security): add URL validation and SSRF protection to Lambda handler (#233)
Restrict Lambda handler to http/https URLs, block private/internal IPs,
remove caller-controlled extra_args and wait_for_function, re-validate
URL after navigation to catch redirect-based SSRF.
2026-05-13 18:55:07 +02:00
CloakHQ db0b5f1946 release: v0.3.28 — cloakserve path traversal fix, GeoIP timeout guard, humanize iframe scope 2026-05-11 21:43:14 +02:00
CloakHQ babef04e07 fix(cloakserve): sanitize fingerprint seed to prevent path traversal (#217)
Validate seed format with strict regex, add path containment check
before rmtree, and bind to 127.0.0.1 by default on bare metal.
2026-05-11 21:36:09 +02:00
CloakHQ f8026a7b39 chore: clean up GeoIP timeout follow-up (#213)
Remove dead null checks, document CLOAKBROWSER_GEOIP_TIMEOUT_SECONDS
env var, credit contributor.

Fix review findings:
- Use timeout-bounded resolve_proxy_exit_ip in _resolve_webrtc_args
- Add missing timeout handler on tunneled HTTPS request in JS
- Reject nan/inf in Python timeout parsing (parity with JS)
- Recompute deadline after CONNECT succeeds in JS proxy tunnel
2026-05-11 21:15:36 +02:00
CloakHQ 0d41a4f023 refactor(js): extract HumanActionOptions type, fix frame check/uncheck error handling, align SOCKS5 log level
- Extract HumanActionOptions type alias to replace ~40 inline copies
- Frame check/uncheck: let isChecked errors propagate instead of silently clicking non-checkbox elements
- SOCKS5 credential log: console.debug → console.info (parity with Python logger.info)
- Add contributors to README
2026-05-11 00:23:31 +02:00
CloakHQ 13b1b98b68 fix(js): bump playwright-core minimum to >=1.53.0 (#200)
playwright-core <=1.52.0 injects __pwInitScripts into window, which
deviceandbrowserinfo.com detects as isPlaywright:true. Fixed in 1.53.0.
2026-05-07 17:31:07 +02:00
CloakHQ 0d6ce76b1d release: v0.3.27 — per-call human_config, humanize timeout fix, scrollIntoViewIfNeeded 2026-05-06 18:32:41 +02:00
CloakHQ f01902025a fix: align humanize timeout default with Playwright's 30s auto-retry (#172)
The humanize layer hardcoded timeout=2000ms for element lookups, causing
locator.click() and page.click() to fail instantly instead of retrying
for 30s like standard Playwright. Aligned all defaults to 30000ms across
Python sync/async, JS Playwright, and JS Puppeteer paths. Bumped the
outer retry sleep from 200ms to 500ms for DOM mutation settle time.
2026-05-01 20:48:06 +02:00
CloakHQ 2df8c7e2d1 fix(js): correct issue references #137 → #172 in humanize comments 2026-04-28 20:37:09 +02:00
CloakHQ ee346a6a57 release: v0.3.26 — Windows x64 upgraded to Chromium 146, SOCKS5 credential encoding, Lambda integration 2026-04-28 05:38:06 +02:00
CloakHQ 3e699f554c fix(docker): add emoji and extended font packages to resolve Kasada/Akamai canvas blocks (#179)
Dockerfile: add fonts-noto-color-emoji, fonts-freefont-ttf, fonts-unifont,
fonts-ipafont-gothic, fonts-wqy-zenhei, fonts-tlwg-loma-otf.
README: separate anti-bot font fix (apt packages) from CreepJS font
enumeration (Windows fonts + --fingerprint-fonts-dir).
2026-04-28 04:11:19 +02:00
CloakHQ 6b8d8b6378 docs: add Font Setup on Linux section to README (#179) 2026-04-28 00:23:08 +02:00
CloakHQ 0ccdc71e47 docs: add @AlexTech314 to contributors, add Deployment Integrations section (#177) 2026-04-27 17:23:24 +02:00
CloakHQ a9a0ba13ba fix(proxy): auto URL-encode SOCKS5 credentials in string URLs (#157)
Chromium's --proxy-server parser truncates passwords at '=' and other
special chars, causing SOCKS5 auth to silently fail and fall back to
direct connection. The dict path already encoded creds; now the string
path does too. Idempotent: pre-encoded input stays encoded.
2026-04-25 23:01:16 +02:00
CloakHQ b04ad6ec2a docs: credit @eofreternal for humanConfig type fix (#151) 2026-04-16 23:12:57 +02:00
CloakHQ 4459f66593 release: v0.3.25 — Chromium 146.0.7680.177.3, launch_context_async, contextOptions 2026-04-16 22:24:36 +02:00
CloakHQ ce8b92ba4f feat: add launch_context_async() + JS contextOptions escape hatch (#141)
Python: add async counterpart to launch_context(). Forwards all kwargs to
browser.new_context() — enables storage_state, permissions, extra_http_headers,
etc. without needing a persistent profile folder.

JS: launchContext() and launchPersistentContext() silently dropped unknown
options. New contextOptions field in LaunchContextOptions is spread into
newContext() to forward arbitrary Playwright context options (e.g.
storageState, permissions, geolocation).
2026-04-16 21:30:40 +02:00
CloakHQ 4e1027847e fix: bump CHROMIUM_VERSION display constant to .2 (#157) 2026-04-15 18:20:01 +02:00
CloakHQ 935beef980 docs: add recommended anti-bot config and SOCKS5 tips to troubleshooting
Based on recurring GitHub issue patterns (#117, #78, #130, #131).
2026-04-10 23:47:42 +02:00
CloakHQ c6d3469e4c release: v0.3.24 — SOCKS5 proxy support, arm64 146 upgrade, ElementHandle humanize 2026-04-10 22:42:29 +02:00
CloakHQ cb0b87873e feat: native SOCKS5 proxy support in proxy= parameter
Route SOCKS5/SOCKS5h proxies via --proxy-server Chrome arg instead of
Playwright's proxy dict (which rejects SOCKS5 with credentials).
Handles string URLs, Playwright dicts, IPv6, bypass lists.

SOCKS5 geoip exit IP resolution uses socks-proxy-agent (optional peer
dep). Falls back to DNS if not installed.
2026-04-10 22:20:16 +02:00
CloakHQ be9a98db67 fix(test): correct cloakserve passthrough test for --fingerprint parsing 2026-04-10 21:40:20 +02:00