clearcote 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -5
- package/dist/download.d.ts +8 -0
- package/dist/download.d.ts.map +1 -1
- package/dist/download.js +203 -30
- package/dist/download.js.map +1 -1
- package/dist/humanize.d.ts +18 -0
- package/dist/humanize.d.ts.map +1 -0
- package/dist/humanize.js +150 -0
- package/dist/humanize.js.map +1 -0
- package/dist/index.d.ts +5 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -8
- package/dist/index.js.map +1 -1
- package/dist/release.d.ts +7 -0
- package/dist/release.d.ts.map +1 -1
- package/dist/release.js +11 -4
- package/dist/release.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -48,19 +48,21 @@ const browser = await launch({
|
|
|
48
48
|
fingerprint: "user-7423",
|
|
49
49
|
proxy: { server: "http://host:8080", username: "u", password: "p" }, // standard Playwright option
|
|
50
50
|
timezone: "America/New_York",
|
|
51
|
-
webrtcIp: "203.0.113.10", // make WebRTC report the proxy egress IP
|
|
51
|
+
webrtcIp: "203.0.113.10", // make WebRTC report the proxy egress IP, not your host's
|
|
52
52
|
});
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
**WebRTC won't leak your real IP.** The engine *fabricates* the WebRTC server-reflexive (`srflx`) candidate at `webrtcIp` and sends **no real STUN** from your host — so WebRTC reports the proxy IP and your real IP never leaks at the packet level. A plain candidate "relabel" doesn't stop the leak (the real STUN packet still goes out from your host); Clearcote sends none. Raw host candidates are suppressed, and the candidate set stays coherent (not empty/disabled).
|
|
56
|
+
|
|
55
57
|
### Auto geo-match (`geoip`)
|
|
56
58
|
|
|
57
|
-
Set `geoip: true` and Clearcote resolves the **proxy's exit IP** (looked up *through* the proxy) and auto-fills any unset `timezone`, `acceptLanguage`, and `
|
|
59
|
+
Set `geoip: true` and Clearcote resolves the **proxy's exit IP** (looked up *through* the proxy) and auto-fills any unset `timezone`, `acceptLanguage`, `location`, **and `webrtcIp`** so the whole identity — clock, language, geo, and WebRTC IP — matches the proxy's region:
|
|
58
60
|
|
|
59
61
|
```ts
|
|
60
62
|
const browser = await launch({
|
|
61
63
|
fingerprint: "user-7423",
|
|
62
64
|
proxy: { server: "http://host:8080", username: "u", password: "p" },
|
|
63
|
-
geoip: true, // timezone
|
|
65
|
+
geoip: true, // timezone, languages, location, AND WebRTC IP all auto-set to the proxy's geo
|
|
64
66
|
});
|
|
65
67
|
```
|
|
66
68
|
|
|
@@ -97,9 +99,9 @@ All optional. Anything not listed here is passed straight through to Playwright
|
|
|
97
99
|
| `location` | `--fingerprint-location` | `"lat,lng"` (only when geo permission is granted). |
|
|
98
100
|
| `timezone` | `--timezone` | IANA timezone, e.g. `America/New_York`. |
|
|
99
101
|
| `acceptLanguage` | `--accept-lang` | `navigator.languages` + `Accept-Language` header, e.g. `en-US,en`. |
|
|
100
|
-
| `webrtcIp` | `--webrtc-ip` | WebRTC
|
|
102
|
+
| `webrtcIp` | `--webrtc-ip` | WebRTC IP to report. The engine **fabricates** the `srflx` candidate at this IP and sends **no real STUN** from the host, so the real IP never leaks (not merely relabeled). |
|
|
101
103
|
| `disableGpuFingerprint` | `--disable-gpu-fingerprint` | Turn off GPU/WebGL spoofing. |
|
|
102
|
-
| `geoip` | _(directive)_ | `true` → resolve the proxy's exit-IP geo and auto-fill timezone/acceptLanguage/location
|
|
104
|
+
| `geoip` | _(directive)_ | `true` → resolve the proxy's exit-IP geo and auto-fill timezone/acceptLanguage/location/**webrtcIp**. |
|
|
103
105
|
|
|
104
106
|
## API
|
|
105
107
|
|
|
@@ -128,6 +130,32 @@ A SHA-256 mismatch is a hard error — the SDK refuses to run an unverified bina
|
|
|
128
130
|
independently confirm the published checksums and GPG signatures on the
|
|
129
131
|
[release page](https://github.com/clearcotelabs/clearcote-browser/releases).
|
|
130
132
|
|
|
133
|
+
### Stay on the latest build (`autoUpdate`)
|
|
134
|
+
|
|
135
|
+
By default the SDK installs the **exact browser build pinned into this package** — reproducible,
|
|
136
|
+
and the baked-in SHA-256 is the trust anchor. To follow new browser releases **without upgrading
|
|
137
|
+
the package every time**, opt in:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const browser = await launch({ fingerprint: "seed-123", autoUpdate: true });
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
or set the environment variable globally:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
CLEARCOTE_AUTO_UPDATE=1
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
With `autoUpdate`, the SDK resolves the **newest GitHub release**, downloads its zip, and verifies
|
|
150
|
+
it against that release's published `SHA256SUMS.txt`. When a **`gpg`** binary is available it
|
|
151
|
+
additionally imports the release's public key, confirms its fingerprint equals the pinned
|
|
152
|
+
`CA96F185 F96A693A EDB3AC1F CB00D851 B7A86B0F`, and verifies the signed checksum — so an
|
|
153
|
+
auto-resolved build is cryptographically authenticated, not just downloaded. If GitHub is
|
|
154
|
+
unreachable it falls back to the pinned release; if the latest release *is* the pinned one, the
|
|
155
|
+
audited baked-in hashes are used. Each build is cached per tag, so this only downloads when a new
|
|
156
|
+
version actually ships. (For locked-down/reproducible deployments, leave `autoUpdate` off and bump
|
|
157
|
+
the package deliberately.)
|
|
158
|
+
|
|
131
159
|
## License
|
|
132
160
|
|
|
133
161
|
BSD-3-Clause. See [LICENSE](../../LICENSE).
|
package/dist/download.d.ts
CHANGED
|
@@ -3,6 +3,14 @@ export interface DownloadOptions {
|
|
|
3
3
|
cacheDir?: string;
|
|
4
4
|
/** Suppress progress logging. */
|
|
5
5
|
quiet?: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Opt in to resolving and downloading the LATEST GitHub release instead of the version pinned
|
|
8
|
+
* into this SDK, so you don't have to upgrade the package for every browser build. Verified
|
|
9
|
+
* against the release's own SHA256SUMS.txt (+ GPG signature when `gpg` is installed). Falls back
|
|
10
|
+
* to the pinned release if GitHub can't be reached. Default: false.
|
|
11
|
+
* Also enabled by setting the env var `CLEARCOTE_AUTO_UPDATE=1`.
|
|
12
|
+
*/
|
|
13
|
+
autoUpdate?: boolean;
|
|
6
14
|
}
|
|
7
15
|
/**
|
|
8
16
|
* Ensure the Clearcote binary is present and verified; return the path to chrome.exe.
|
package/dist/download.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"download.d.ts","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,eAAe;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAkQD;;;GAGG;AACH,wBAAsB,YAAY,CAAC,IAAI,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAsB9E"}
|
package/dist/download.js
CHANGED
|
@@ -1,20 +1,36 @@
|
|
|
1
1
|
// Resolve the Clearcote browser binary: use an explicit path / env override if given, otherwise
|
|
2
|
-
// download
|
|
3
|
-
//
|
|
4
|
-
//
|
|
2
|
+
// download a release, verify it, extract it to a per-version cache, and return chrome.exe.
|
|
3
|
+
//
|
|
4
|
+
// Two modes:
|
|
5
|
+
// • pinned (default) — download the exact release baked into this SDK and verify its zip +
|
|
6
|
+
// chrome.exe against the SHA-256 hashes shipped in release.ts. The hash
|
|
7
|
+
// IS the trust anchor: you audit it once, in the package you installed.
|
|
8
|
+
// • autoUpdate (opt-in) — resolve the NEWEST GitHub release at runtime, verify the zip against
|
|
9
|
+
// that release's published SHA256SUMS.txt, and — when a `gpg` binary is
|
|
10
|
+
// available — verify SHA256SUMS.txt.asc against the pinned signing-key
|
|
11
|
+
// fingerprint. Lets you stay current without bumping the SDK. Falls back
|
|
12
|
+
// to the pinned release if GitHub is unreachable.
|
|
13
|
+
// A hash mismatch (either mode) is always a hard failure and the partial download is deleted.
|
|
14
|
+
import { spawnSync } from "node:child_process";
|
|
5
15
|
import { createHash } from "node:crypto";
|
|
6
|
-
import { createReadStream, createWriteStream, existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { createReadStream, createWriteStream, existsSync, mkdirSync, mkdtempSync, readdirSync, writeFileSync } from "node:fs";
|
|
7
17
|
import { rm } from "node:fs/promises";
|
|
8
18
|
import os from "node:os";
|
|
9
19
|
import path from "node:path";
|
|
10
20
|
import { Readable } from "node:stream";
|
|
11
21
|
import { pipeline } from "node:stream/promises";
|
|
12
22
|
import extract from "extract-zip";
|
|
13
|
-
import { RELEASE } from "./release.js";
|
|
23
|
+
import { RELEASE, REPO, SIGNING_KEY_FPR } from "./release.js";
|
|
14
24
|
function log(quiet, msg) {
|
|
15
25
|
if (!quiet)
|
|
16
26
|
process.stderr.write(`[clearcote] ${msg}\n`);
|
|
17
27
|
}
|
|
28
|
+
function autoUpdateRequested(opt) {
|
|
29
|
+
if (opt !== undefined)
|
|
30
|
+
return opt;
|
|
31
|
+
const env = process.env.CLEARCOTE_AUTO_UPDATE;
|
|
32
|
+
return env === "1" || env === "true";
|
|
33
|
+
}
|
|
18
34
|
function defaultCacheRoot() {
|
|
19
35
|
if (process.env.CLEARCOTE_CACHE)
|
|
20
36
|
return process.env.CLEARCOTE_CACHE;
|
|
@@ -56,18 +72,18 @@ function sha256File(file) {
|
|
|
56
72
|
.on("end", () => resolve(hash.digest("hex")));
|
|
57
73
|
});
|
|
58
74
|
}
|
|
59
|
-
async function downloadTo(url, dest, quiet) {
|
|
75
|
+
async function downloadTo(url, dest, expectedSize, quiet) {
|
|
60
76
|
const res = await fetch(url, { redirect: "follow" });
|
|
61
77
|
if (!res.ok || !res.body) {
|
|
62
78
|
throw new Error(`Clearcote download failed: HTTP ${res.status} ${res.statusText} for ${url}`);
|
|
63
79
|
}
|
|
64
|
-
const total = Number(res.headers.get("content-length")) ||
|
|
80
|
+
const total = Number(res.headers.get("content-length")) || expectedSize;
|
|
65
81
|
let seen = 0;
|
|
66
82
|
let lastPct = -1;
|
|
67
83
|
const progress = new TransformStream({
|
|
68
84
|
transform(chunk, controller) {
|
|
69
85
|
seen += chunk.byteLength;
|
|
70
|
-
const pct = Math.floor((seen / total) * 100);
|
|
86
|
+
const pct = total ? Math.floor((seen / total) * 100) : 0;
|
|
71
87
|
if (!quiet && pct !== lastPct && pct % 5 === 0) {
|
|
72
88
|
lastPct = pct;
|
|
73
89
|
process.stderr.write(`\r[clearcote] downloading ${pct}% (${(seen / 1e6).toFixed(0)}/${(total / 1e6).toFixed(0)} MB)`);
|
|
@@ -79,44 +95,201 @@ async function downloadTo(url, dest, quiet) {
|
|
|
79
95
|
if (!quiet)
|
|
80
96
|
process.stderr.write("\n");
|
|
81
97
|
}
|
|
98
|
+
async function fetchText(url) {
|
|
99
|
+
const res = await fetch(url, { redirect: "follow", headers: { "User-Agent": "clearcote-sdk" } });
|
|
100
|
+
if (!res.ok)
|
|
101
|
+
throw new Error(`HTTP ${res.status} for ${url}`);
|
|
102
|
+
return res.text();
|
|
103
|
+
}
|
|
104
|
+
async function fetchToFile(url, dest) {
|
|
105
|
+
writeFileSync(dest, await fetchText(url));
|
|
106
|
+
}
|
|
107
|
+
/** Pull the zip + chrome.exe hashes out of a SHA256SUMS.txt body. */
|
|
108
|
+
function parseSums(text, zipName) {
|
|
109
|
+
const out = {};
|
|
110
|
+
for (const raw of text.split(/\r?\n/)) {
|
|
111
|
+
const m = raw.trim().match(/^([0-9a-fA-F]{64})\s+[*]?(.+)$/);
|
|
112
|
+
if (!m)
|
|
113
|
+
continue;
|
|
114
|
+
const base = m[2].split(/[\\/]/).pop();
|
|
115
|
+
if (base === zipName)
|
|
116
|
+
out.zip = m[1].toLowerCase();
|
|
117
|
+
else if (base === "chrome.exe")
|
|
118
|
+
out.exe = m[1].toLowerCase();
|
|
119
|
+
}
|
|
120
|
+
return out;
|
|
121
|
+
}
|
|
122
|
+
/** Resolve the newest non-draft GitHub release with a windows-x64 zip + SHA256SUMS.txt. */
|
|
123
|
+
async function resolveLatest(quiet) {
|
|
124
|
+
let list;
|
|
125
|
+
try {
|
|
126
|
+
const res = await fetch(`https://api.github.com/repos/${REPO}/releases?per_page=30`, {
|
|
127
|
+
redirect: "follow",
|
|
128
|
+
headers: { "User-Agent": "clearcote-sdk", Accept: "application/vnd.github+json" },
|
|
129
|
+
});
|
|
130
|
+
if (!res.ok)
|
|
131
|
+
throw new Error(`GitHub API HTTP ${res.status}`);
|
|
132
|
+
list = (await res.json());
|
|
133
|
+
}
|
|
134
|
+
catch (e) {
|
|
135
|
+
log(quiet, `auto-update: couldn't reach GitHub (${e.message}); using pinned ${RELEASE.tag}`);
|
|
136
|
+
return null;
|
|
137
|
+
}
|
|
138
|
+
const releases = list
|
|
139
|
+
.filter((r) => r && !r.draft)
|
|
140
|
+
.sort((a, b) => String(b.published_at || "").localeCompare(String(a.published_at || "")));
|
|
141
|
+
for (const r of releases) {
|
|
142
|
+
const assets = r.assets || [];
|
|
143
|
+
const zip = assets.find((a) => /^clearcote-.*-windows-x64\.zip$/.test(a.name));
|
|
144
|
+
const sums = assets.find((a) => a.name === "SHA256SUMS.txt");
|
|
145
|
+
if (!zip || !sums)
|
|
146
|
+
continue;
|
|
147
|
+
let parsed;
|
|
148
|
+
try {
|
|
149
|
+
parsed = parseSums(await fetchText(sums.browser_download_url), zip.name);
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
if (!parsed.zip)
|
|
155
|
+
continue;
|
|
156
|
+
const m = zip.name.match(/^clearcote-(.+)-windows-x64\.zip$/);
|
|
157
|
+
return {
|
|
158
|
+
tag: r.tag_name,
|
|
159
|
+
version: m ? m[1] : r.tag_name,
|
|
160
|
+
asset: zip.name,
|
|
161
|
+
url: zip.browser_download_url,
|
|
162
|
+
sha256: parsed.zip,
|
|
163
|
+
exeSha256: parsed.exe || "",
|
|
164
|
+
size: zip.size || 0,
|
|
165
|
+
os: "win32",
|
|
166
|
+
unpinned: true,
|
|
167
|
+
ascUrl: assets.find((a) => a.name === "SHA256SUMS.txt.asc")?.browser_download_url,
|
|
168
|
+
keyUrl: assets.find((a) => a.name === "clearcote-signing-key.asc")?.browser_download_url,
|
|
169
|
+
};
|
|
170
|
+
}
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
function hasGpg() {
|
|
174
|
+
try {
|
|
175
|
+
return spawnSync("gpg", ["--version"], { stdio: "ignore" }).status === 0;
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
82
181
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
182
|
+
* Best-effort GPG check for an auto-resolved release: import the published key into a throwaway
|
|
183
|
+
* keyring, confirm its fingerprint equals the pinned one, then verify SHA256SUMS.txt.asc.
|
|
184
|
+
* Returns "ok" | "skipped" (no gpg / no signature) | "failed". A "failed" result is treated as a
|
|
185
|
+
* hard error by the caller; "skipped" proceeds (integrity is still guaranteed by the SHA-256 check).
|
|
85
186
|
*/
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
187
|
+
async function gpgVerifyAsync(rel, sumsBody, tmp, quiet) {
|
|
188
|
+
if (!rel.ascUrl || !rel.keyUrl)
|
|
189
|
+
return "skipped";
|
|
190
|
+
if (!hasGpg()) {
|
|
191
|
+
log(quiet, "auto-update: gpg not found — skipping signature check (zip is still SHA-256-verified)");
|
|
192
|
+
return "skipped";
|
|
193
|
+
}
|
|
194
|
+
const home = mkdtempSync(path.join(tmp, "ccgpg-"));
|
|
195
|
+
const keyPath = path.join(home, "key.asc");
|
|
196
|
+
const sumsPath = path.join(home, "SHA256SUMS.txt");
|
|
197
|
+
const ascPath = path.join(home, "SHA256SUMS.txt.asc");
|
|
198
|
+
const gpg = (args) => spawnSync("gpg", ["--homedir", home, "--batch", ...args], { encoding: "utf8" });
|
|
199
|
+
try {
|
|
200
|
+
writeFileSync(sumsPath, sumsBody);
|
|
201
|
+
await fetchToFile(rel.keyUrl, keyPath);
|
|
202
|
+
await fetchToFile(rel.ascUrl, ascPath);
|
|
203
|
+
if (gpg(["--import", keyPath]).status !== 0)
|
|
204
|
+
return "failed";
|
|
205
|
+
const shown = gpg(["--with-colons", "--fingerprint"]);
|
|
206
|
+
const fprs = (shown.stdout || "")
|
|
207
|
+
.split(/\r?\n/)
|
|
208
|
+
.filter((l) => l.startsWith("fpr:"))
|
|
209
|
+
.map((l) => l.split(":")[9]);
|
|
210
|
+
if (!fprs.includes(SIGNING_KEY_FPR)) {
|
|
211
|
+
log(quiet, `auto-update: signing key fingerprint mismatch (expected ${SIGNING_KEY_FPR})`);
|
|
212
|
+
return "failed";
|
|
213
|
+
}
|
|
214
|
+
const verified = gpg(["--verify", ascPath, sumsPath]);
|
|
215
|
+
return verified.status === 0 ? "ok" : "failed";
|
|
216
|
+
}
|
|
217
|
+
catch {
|
|
218
|
+
return "failed";
|
|
94
219
|
}
|
|
220
|
+
finally {
|
|
221
|
+
await rm(home, { recursive: true, force: true });
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Download + verify a resolved release into `base`, returning the extracted chrome.exe path. */
|
|
225
|
+
async function fetchAndVerify(rel, base, opts) {
|
|
226
|
+
const browserDir = path.join(base, "browser");
|
|
95
227
|
mkdirSync(base, { recursive: true });
|
|
96
|
-
const zipPath = path.join(base,
|
|
97
|
-
log(opts.quiet, `fetching Clearcote ${
|
|
98
|
-
await downloadTo(
|
|
228
|
+
const zipPath = path.join(base, rel.asset);
|
|
229
|
+
log(opts.quiet, `fetching Clearcote ${rel.version} (${rel.tag}${rel.unpinned ? ", latest" : ""}, ~${(rel.size / 1e6).toFixed(0)} MB)`);
|
|
230
|
+
await downloadTo(rel.url, zipPath, rel.size, opts.quiet);
|
|
99
231
|
log(opts.quiet, "verifying SHA-256");
|
|
100
232
|
const got = await sha256File(zipPath);
|
|
101
|
-
if (got.toLowerCase() !==
|
|
233
|
+
if (got.toLowerCase() !== rel.sha256.toLowerCase()) {
|
|
102
234
|
await rm(zipPath, { force: true });
|
|
103
|
-
throw new Error(`Clearcote archive SHA-256 mismatch — refusing to use it.\n expected ${
|
|
235
|
+
throw new Error(`Clearcote archive SHA-256 mismatch — refusing to use it.\n expected ${rel.sha256}\n got ${got}`);
|
|
236
|
+
}
|
|
237
|
+
// For an auto-resolved (un-pinned) release, also confirm authenticity via the signed checksum file.
|
|
238
|
+
if (rel.unpinned && rel.ascUrl) {
|
|
239
|
+
const sumsBody = await fetchText(`https://github.com/${REPO}/releases/download/${rel.tag}/SHA256SUMS.txt`).catch(() => "");
|
|
240
|
+
if (sumsBody) {
|
|
241
|
+
const verdict = await gpgVerifyAsync(rel, sumsBody, base, opts.quiet);
|
|
242
|
+
if (verdict === "failed") {
|
|
243
|
+
await rm(zipPath, { force: true });
|
|
244
|
+
throw new Error(`Clearcote ${rel.tag}: GPG signature verification FAILED against the pinned key ${SIGNING_KEY_FPR} — refusing to use it.`);
|
|
245
|
+
}
|
|
246
|
+
if (verdict === "ok")
|
|
247
|
+
log(opts.quiet, `auto-update: GPG signature OK (key ${SIGNING_KEY_FPR})`);
|
|
248
|
+
}
|
|
104
249
|
}
|
|
105
250
|
log(opts.quiet, "extracting");
|
|
106
251
|
await rm(browserDir, { recursive: true, force: true });
|
|
107
252
|
await extract(zipPath, { dir: browserDir });
|
|
108
253
|
const exe = findFile(browserDir, "chrome.exe");
|
|
109
|
-
if (!exe)
|
|
254
|
+
if (!exe)
|
|
110
255
|
throw new Error("Clearcote archive verified but chrome.exe was not found inside it.");
|
|
256
|
+
if (rel.exeSha256) {
|
|
257
|
+
const exeHash = await sha256File(exe);
|
|
258
|
+
if (exeHash.toLowerCase() !== rel.exeSha256.toLowerCase()) {
|
|
259
|
+
throw new Error(`Clearcote chrome.exe SHA-256 mismatch — refusing to use it.\n expected ${rel.exeSha256}\n got ${exeHash}`);
|
|
260
|
+
}
|
|
111
261
|
}
|
|
112
|
-
|
|
113
|
-
const exeHash = await sha256File(exe);
|
|
114
|
-
if (exeHash.toLowerCase() !== RELEASE.exeSha256.toLowerCase()) {
|
|
115
|
-
throw new Error(`Clearcote chrome.exe SHA-256 mismatch — refusing to use it.\n expected ${RELEASE.exeSha256}\n got ${exeHash}`);
|
|
116
|
-
}
|
|
117
|
-
writeFileSync(marker, `${RELEASE.sha256}\n`);
|
|
262
|
+
writeFileSync(path.join(base, ".verified"), `${rel.sha256}\n`);
|
|
118
263
|
await rm(zipPath, { force: true }); // reclaim ~250 MB; keep only the extracted tree
|
|
119
264
|
log(opts.quiet, `ready: ${exe}`);
|
|
120
265
|
return exe;
|
|
121
266
|
}
|
|
267
|
+
/**
|
|
268
|
+
* Ensure the Clearcote binary is present and verified; return the path to chrome.exe.
|
|
269
|
+
* Cached per release tag, so subsequent calls are instant.
|
|
270
|
+
*/
|
|
271
|
+
export async function ensureBinary(opts = {}) {
|
|
272
|
+
const cacheRoot = opts.cacheDir || defaultCacheRoot();
|
|
273
|
+
let rel;
|
|
274
|
+
if (autoUpdateRequested(opts.autoUpdate)) {
|
|
275
|
+
const latest = await resolveLatest(opts.quiet);
|
|
276
|
+
if (latest && latest.tag === RELEASE.tag) {
|
|
277
|
+
// newest release IS the pinned one — prefer the baked-in hashes (the audited trust anchor).
|
|
278
|
+
rel = { ...RELEASE, unpinned: false };
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
rel = latest ?? { ...RELEASE, unpinned: false };
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
else {
|
|
285
|
+
rel = { ...RELEASE, unpinned: false };
|
|
286
|
+
}
|
|
287
|
+
const base = path.join(cacheRoot, rel.tag);
|
|
288
|
+
if (existsSync(path.join(base, ".verified"))) {
|
|
289
|
+
const cached = findFile(path.join(base, "browser"), "chrome.exe");
|
|
290
|
+
if (cached)
|
|
291
|
+
return cached;
|
|
292
|
+
}
|
|
293
|
+
return fetchAndVerify(rel, base, opts);
|
|
294
|
+
}
|
|
122
295
|
//# sourceMappingURL=download.js.map
|
package/dist/download.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"download.js","sourceRoot":"","sources":["../src/download.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Browser, BrowserContext, Page } from "playwright-core";
|
|
2
|
+
export interface HumanizeOptions {
|
|
3
|
+
/** Route clicks/moves/scroll through the engine's humanized (bezier, trusted) input. */
|
|
4
|
+
humanize?: boolean;
|
|
5
|
+
/** Show a red cursor dot that tracks the motion (visualization). */
|
|
6
|
+
showCursor?: boolean;
|
|
7
|
+
}
|
|
8
|
+
/** Overlay: a red dot that follows real mousemove events. Idempotent IIFE so it works both as
|
|
9
|
+
* an addInitScript source string AND when passed to page.evaluate (Node treats a bare arrow
|
|
10
|
+
* string as an uncalled expression — an IIFE actually runs). */
|
|
11
|
+
export declare const CURSOR_OVERLAY = "(() => {\n if (window.__clearcoteCursor) return; window.__clearcoteCursor = 1;\n const make = () => {\n if (document.getElementById('__clearcote_cursor')) return;\n const d = document.createElement('div'); d.id = '__clearcote_cursor';\n d.style.cssText = 'position:fixed;left:0;top:0;width:20px;height:20px;margin:-10px 0 0 -10px;' +\n 'border-radius:50%;border:2px solid #ff3b3b;background:rgba(255,59,59,.22);' +\n 'box-shadow:0 0 10px rgba(255,59,59,.6);pointer-events:none;z-index:2147483647';\n (document.body || document.documentElement).appendChild(d);\n };\n if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', make); else make();\n document.addEventListener('mousemove', (e) => {\n const d = document.getElementById('__clearcote_cursor');\n if (d) { d.style.left = e.clientX + 'px'; d.style.top = e.clientY + 'px'; }\n }, true);\n})();";
|
|
12
|
+
/** Wrap a single page's input methods + (optionally) inject the cursor overlay. */
|
|
13
|
+
export declare function attachHumanize(browser: Browser, page: Page, opts: HumanizeOptions): Promise<void>;
|
|
14
|
+
/** Install humanize/showCursor on a browser: wraps newPage/newContext so every page is covered. */
|
|
15
|
+
export declare function installHumanize(browser: Browser, opts: HumanizeOptions): void;
|
|
16
|
+
/** Install humanize/showCursor on a single context (used for launchPersistentContext). */
|
|
17
|
+
export declare function installHumanizeOnContext(context: BrowserContext, opts: HumanizeOptions, browser?: Browser | null): void;
|
|
18
|
+
//# sourceMappingURL=humanize.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"humanize.d.ts","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAc,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAEjF,MAAM,WAAW,eAAe;IAC9B,wFAAwF;IACxF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;gEAEgE;AAChE,eAAO,MAAM,cAAc,o5BAerB,CAAC;AAUP,mFAAmF;AACnF,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA0EvG;AAED,mGAAmG;AACnG,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,eAAe,GAAG,IAAI,CAc7E;AAED,0FAA0F;AAC1F,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACvE,IAAI,CAQN"}
|
package/dist/humanize.js
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
// Humanized input + cursor visualization.
|
|
2
|
+
//
|
|
3
|
+
// `humanize: true` — routes page.click/hover/mouse.move/mouse.click through the engine's
|
|
4
|
+
// `Browser.humanizedClick` CDP command (real trusted WebMouseEvent along a cubic-bezier path,
|
|
5
|
+
// isTrusted===true, navigator.webdriver stays false), and eases mouse.wheel SDK-side.
|
|
6
|
+
// `showCursor: true` — injects a red cursor dot that follows the real mousemove events the engine
|
|
7
|
+
// fires, so you can watch the motion (cross-platform; no native overlay needed).
|
|
8
|
+
//
|
|
9
|
+
// Requires a Clearcote binary that exposes Browser.humanizedClick (the humanized-input engine
|
|
10
|
+
// build). On an older binary the command is absent; humanize falls back to native Playwright input.
|
|
11
|
+
/** Overlay: a red dot that follows real mousemove events. Idempotent IIFE so it works both as
|
|
12
|
+
* an addInitScript source string AND when passed to page.evaluate (Node treats a bare arrow
|
|
13
|
+
* string as an uncalled expression — an IIFE actually runs). */
|
|
14
|
+
export const CURSOR_OVERLAY = `(() => {
|
|
15
|
+
if (window.__clearcoteCursor) return; window.__clearcoteCursor = 1;
|
|
16
|
+
const make = () => {
|
|
17
|
+
if (document.getElementById('__clearcote_cursor')) return;
|
|
18
|
+
const d = document.createElement('div'); d.id = '__clearcote_cursor';
|
|
19
|
+
d.style.cssText = 'position:fixed;left:0;top:0;width:20px;height:20px;margin:-10px 0 0 -10px;' +
|
|
20
|
+
'border-radius:50%;border:2px solid #ff3b3b;background:rgba(255,59,59,.22);' +
|
|
21
|
+
'box-shadow:0 0 10px rgba(255,59,59,.6);pointer-events:none;z-index:2147483647';
|
|
22
|
+
(document.body || document.documentElement).appendChild(d);
|
|
23
|
+
};
|
|
24
|
+
if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', make); else make();
|
|
25
|
+
document.addEventListener('mousemove', (e) => {
|
|
26
|
+
const d = document.getElementById('__clearcote_cursor');
|
|
27
|
+
if (d) { d.style.left = e.clientX + 'px'; d.style.top = e.clientY + 'px'; }
|
|
28
|
+
}, true);
|
|
29
|
+
})();`;
|
|
30
|
+
const rand = (a, b) => a + Math.random() * (b - a);
|
|
31
|
+
async function pageTargetId(page) {
|
|
32
|
+
const s = await page.context().newCDPSession(page);
|
|
33
|
+
const info = await s.send("Target.getTargetInfo");
|
|
34
|
+
return info.targetInfo.targetId;
|
|
35
|
+
}
|
|
36
|
+
/** Wrap a single page's input methods + (optionally) inject the cursor overlay. */
|
|
37
|
+
export async function attachHumanize(browser, page, opts) {
|
|
38
|
+
if (opts.showCursor) {
|
|
39
|
+
const inject = () => page.evaluate(CURSOR_OVERLAY).catch(() => { });
|
|
40
|
+
inject();
|
|
41
|
+
page.on("load", () => { inject(); });
|
|
42
|
+
page.on("framenavigated", (f) => { if (f === page.mainFrame())
|
|
43
|
+
inject(); });
|
|
44
|
+
}
|
|
45
|
+
if (!opts.humanize)
|
|
46
|
+
return;
|
|
47
|
+
let bsession = null;
|
|
48
|
+
let tid = null;
|
|
49
|
+
let supported = true;
|
|
50
|
+
const humanizedMove = async (x, y, noClick, duration) => {
|
|
51
|
+
if (!supported)
|
|
52
|
+
return false;
|
|
53
|
+
try {
|
|
54
|
+
bsession ??= await browser.newBrowserCDPSession();
|
|
55
|
+
tid ??= await pageTargetId(page);
|
|
56
|
+
await bsession.send("Browser.humanizedClick", {
|
|
57
|
+
targetId: tid, x: Math.round(x), y: Math.round(y),
|
|
58
|
+
duration: duration ?? rand(0.45, 0.95), noClick,
|
|
59
|
+
});
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
catch (e) {
|
|
63
|
+
// older binary without the command -> stop trying, fall back to native input
|
|
64
|
+
supported = false;
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
const mouse = page.mouse;
|
|
69
|
+
const nativeMove = mouse.move.bind(mouse);
|
|
70
|
+
const nativeClick = mouse.click.bind(mouse);
|
|
71
|
+
const nativeWheel = mouse.wheel.bind(mouse);
|
|
72
|
+
mouse.move = async (x, y, options) => {
|
|
73
|
+
if (!(await humanizedMove(x, y, true)))
|
|
74
|
+
return nativeMove(x, y, options);
|
|
75
|
+
};
|
|
76
|
+
mouse.click = async (x, y, options) => {
|
|
77
|
+
if (!(await humanizedMove(x, y, false)))
|
|
78
|
+
return nativeClick(x, y, options);
|
|
79
|
+
};
|
|
80
|
+
// scroll easing (engine humanizedClick doesn't cover wheel): break into eased chunks
|
|
81
|
+
mouse.wheel = async (dx, dy) => {
|
|
82
|
+
const steps = Math.max(5, Math.min(20, Math.round((Math.abs(dx) + Math.abs(dy)) / 80)));
|
|
83
|
+
const ease = (u) => u * u * (3 - 2 * u);
|
|
84
|
+
let px = 0, py = 0;
|
|
85
|
+
for (let i = 1; i <= steps; i++) {
|
|
86
|
+
const f = ease(i / steps);
|
|
87
|
+
const nx = Math.round(dx * f), ny = Math.round(dy * f);
|
|
88
|
+
await nativeWheel(nx - px, ny - py);
|
|
89
|
+
px = nx;
|
|
90
|
+
py = ny;
|
|
91
|
+
await page.waitForTimeout(rand(12, 45));
|
|
92
|
+
}
|
|
93
|
+
if (px !== dx || py !== dy)
|
|
94
|
+
await nativeWheel(dx - px, dy - py);
|
|
95
|
+
};
|
|
96
|
+
const wrapTargeted = (name, noClick) => {
|
|
97
|
+
const orig = page[name].bind(page);
|
|
98
|
+
page[name] = async (selector, options = {}) => {
|
|
99
|
+
try {
|
|
100
|
+
const loc = page.locator(selector).first();
|
|
101
|
+
await loc.scrollIntoViewIfNeeded({ timeout: options.timeout ?? 30000 });
|
|
102
|
+
const box = await loc.boundingBox();
|
|
103
|
+
if (!box)
|
|
104
|
+
return orig(selector, options);
|
|
105
|
+
const x = box.x + box.width * rand(0.3, 0.7);
|
|
106
|
+
const y = box.y + box.height * rand(0.3, 0.7);
|
|
107
|
+
if (await humanizedMove(x, y, noClick))
|
|
108
|
+
return;
|
|
109
|
+
return orig(selector, options);
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return orig(selector, options);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
};
|
|
116
|
+
wrapTargeted("click", false);
|
|
117
|
+
wrapTargeted("hover", true);
|
|
118
|
+
}
|
|
119
|
+
/** Install humanize/showCursor on a browser: wraps newPage/newContext so every page is covered. */
|
|
120
|
+
export function installHumanize(browser, opts) {
|
|
121
|
+
if (!opts.humanize && !opts.showCursor)
|
|
122
|
+
return;
|
|
123
|
+
const origNewPage = browser.newPage.bind(browser);
|
|
124
|
+
browser.newPage = async (options) => {
|
|
125
|
+
const page = await origNewPage(options);
|
|
126
|
+
await attachHumanize(browser, page, opts);
|
|
127
|
+
return page;
|
|
128
|
+
};
|
|
129
|
+
const origNewContext = browser.newContext.bind(browser);
|
|
130
|
+
browser.newContext = async (options) => {
|
|
131
|
+
const ctx = await origNewContext(options);
|
|
132
|
+
installHumanizeOnContext(ctx, opts, browser);
|
|
133
|
+
return ctx;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
/** Install humanize/showCursor on a single context (used for launchPersistentContext). */
|
|
137
|
+
export function installHumanizeOnContext(context, opts, browser) {
|
|
138
|
+
if (!opts.humanize && !opts.showCursor)
|
|
139
|
+
return;
|
|
140
|
+
const b = browser ?? context.browser();
|
|
141
|
+
if (opts.showCursor) {
|
|
142
|
+
context.addInitScript(CURSOR_OVERLAY).catch(() => { });
|
|
143
|
+
}
|
|
144
|
+
if (b) {
|
|
145
|
+
context.on("page", (p) => { attachHumanize(b, p, opts).catch(() => { }); });
|
|
146
|
+
for (const p of context.pages())
|
|
147
|
+
attachHumanize(b, p, opts).catch(() => { });
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=humanize.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"humanize.js","sourceRoot":"","sources":["../src/humanize.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import type { Browser, BrowserContext, BrowserContextOptions, LaunchOptions as PlaywrightLaunchOptions } from "playwright-core";
|
|
2
2
|
import { type DownloadOptions } from "./download.js";
|
|
3
3
|
import { type FingerprintOptions } from "./fingerprint.js";
|
|
4
|
+
import { type HumanizeOptions } from "./humanize.js";
|
|
4
5
|
export type { FingerprintOptions } from "./fingerprint.js";
|
|
5
6
|
export type { DownloadOptions } from "./download.js";
|
|
6
7
|
export { resolveGeo, type Geo } from "./geoip.js";
|
|
8
|
+
export type { HumanizeOptions } from "./humanize.js";
|
|
7
9
|
export { RELEASE } from "./release.js";
|
|
8
10
|
/** When true (and a proxy is set), resolve the proxy's exit-IP geo and auto-fill any unset
|
|
9
11
|
* `timezone` + `acceptLanguage` (+ `location`) so they match the proxy region. */
|
|
10
12
|
interface GeoipOption {
|
|
11
13
|
geoip?: boolean;
|
|
12
14
|
}
|
|
13
|
-
/** Options for {@link launch}: Playwright launch options + Clearcote fingerprint options. */
|
|
14
|
-
export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption {
|
|
15
|
+
/** Options for {@link launch}: Playwright launch options + Clearcote fingerprint + download options. */
|
|
16
|
+
export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption, HumanizeOptions, DownloadOptions {
|
|
15
17
|
}
|
|
16
18
|
/** Options for {@link launchPersistentContext}. */
|
|
17
|
-
export interface PersistentContextOptions extends PlaywrightLaunchOptions, BrowserContextOptions, FingerprintOptions, GeoipOption {
|
|
19
|
+
export interface PersistentContextOptions extends PlaywrightLaunchOptions, BrowserContextOptions, FingerprintOptions, GeoipOption, HumanizeOptions, DownloadOptions {
|
|
18
20
|
}
|
|
19
21
|
/**
|
|
20
22
|
* Resolve the Clearcote chrome.exe path, downloading + verifying it if needed.
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,aAAa,IAAI,uBAAuB,EACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAA4C,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EACV,OAAO,EACP,cAAc,EACd,qBAAqB,EACrB,aAAa,IAAI,uBAAuB,EACzC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAgB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AACnE,OAAO,EAA4C,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAErG,OAAO,EAA6C,KAAK,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhG,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,KAAK,GAAG,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC;kFACkF;AAClF,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,wGAAwG;AACxG,MAAM,WAAW,aAAc,SAAQ,uBAAuB,EAAE,kBAAkB,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe;CAAG;AAEpI,mDAAmD;AACnD,MAAM,WAAW,wBACf,SAAQ,uBAAuB,EAC7B,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,eAAe;CAAG;AAwBtB;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAoB,GAC1D,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,iGAAiG;AACjG,wBAAsB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAED,yEAAyE;AACzE,wBAAsB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAa1E;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,WAAW,EAAE,MAAM,EACnB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,cAAc,CAAC,CAazB;;;;;;;;AAED,wBAAsF"}
|
package/dist/index.js
CHANGED
|
@@ -13,10 +13,11 @@ import { chromium } from "playwright-core";
|
|
|
13
13
|
import { ensureBinary } from "./download.js";
|
|
14
14
|
import { fingerprintArgs, splitFingerprintOptions } from "./fingerprint.js";
|
|
15
15
|
import { resolveGeo } from "./geoip.js";
|
|
16
|
+
import { installHumanize, installHumanizeOnContext } from "./humanize.js";
|
|
16
17
|
import { RELEASE } from "./release.js";
|
|
17
18
|
export { resolveGeo } from "./geoip.js";
|
|
18
19
|
export { RELEASE } from "./release.js";
|
|
19
|
-
/** Fill unset timezone/acceptLanguage/location on `fp` from the proxy's exit-IP geo. */
|
|
20
|
+
/** Fill unset timezone/acceptLanguage/location/webrtcIp on `fp` from the proxy's exit-IP geo. */
|
|
20
21
|
async function applyGeoip(fp, proxy) {
|
|
21
22
|
const geo = await resolveGeo(proxy);
|
|
22
23
|
if (!geo)
|
|
@@ -27,6 +28,10 @@ async function applyGeoip(fp, proxy) {
|
|
|
27
28
|
fp.acceptLanguage = geo.acceptLanguage;
|
|
28
29
|
if (geo.location && fp.location == null)
|
|
29
30
|
fp.location = geo.location;
|
|
31
|
+
// make WebRTC report the proxy egress IP too, coherent with HTTP egress (engine fabricates
|
|
32
|
+
// the srflx candidate at this IP; no real STUN leaves the host).
|
|
33
|
+
if (geo.ip && fp.webrtcIp == null)
|
|
34
|
+
fp.webrtcIp = geo.ip;
|
|
30
35
|
}
|
|
31
36
|
function ensureRunnableHere(exe) {
|
|
32
37
|
if (process.platform !== "win32") {
|
|
@@ -44,7 +49,7 @@ export async function executablePath(options = {}) {
|
|
|
44
49
|
return options.executablePath;
|
|
45
50
|
if (process.env.CLEARCOTE_BINARY)
|
|
46
51
|
return process.env.CLEARCOTE_BINARY;
|
|
47
|
-
return ensureBinary({ cacheDir: options.cacheDir, quiet: options.quiet });
|
|
52
|
+
return ensureBinary({ cacheDir: options.cacheDir, quiet: options.quiet, autoUpdate: options.autoUpdate });
|
|
48
53
|
}
|
|
49
54
|
/** Pre-fetch + verify the Clearcote binary without launching it. Returns the chrome.exe path. */
|
|
50
55
|
export async function download(options = {}) {
|
|
@@ -52,34 +57,38 @@ export async function download(options = {}) {
|
|
|
52
57
|
}
|
|
53
58
|
/** Launch Clearcote and return a standard Playwright {@link Browser}. */
|
|
54
59
|
export async function launch(options = {}) {
|
|
55
|
-
const { executablePath: exeOption, args, geoip, ...rest } = options;
|
|
60
|
+
const { executablePath: exeOption, args, geoip, humanize, showCursor, autoUpdate, cacheDir, quiet, ...rest } = options;
|
|
56
61
|
const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
|
|
57
62
|
if (geoip)
|
|
58
63
|
await applyGeoip(fingerprint, pwOptions.proxy);
|
|
59
|
-
const exe = await executablePath({ executablePath: exeOption });
|
|
64
|
+
const exe = await executablePath({ executablePath: exeOption, autoUpdate, cacheDir, quiet });
|
|
60
65
|
ensureRunnableHere(exe);
|
|
61
|
-
|
|
66
|
+
const browser = await chromium.launch({
|
|
62
67
|
...pwOptions,
|
|
63
68
|
executablePath: exe,
|
|
64
69
|
args: [...fingerprintArgs(fingerprint), ...(args ?? [])],
|
|
65
70
|
});
|
|
71
|
+
installHumanize(browser, { humanize, showCursor });
|
|
72
|
+
return browser;
|
|
66
73
|
}
|
|
67
74
|
/**
|
|
68
75
|
* Launch Clearcote with a persistent profile directory and return a Playwright
|
|
69
76
|
* {@link BrowserContext} (cookies, storage, etc. persist in `userDataDir`).
|
|
70
77
|
*/
|
|
71
78
|
export async function launchPersistentContext(userDataDir, options = {}) {
|
|
72
|
-
const { executablePath: exeOption, args, geoip, ...rest } = options;
|
|
79
|
+
const { executablePath: exeOption, args, geoip, humanize, showCursor, autoUpdate, cacheDir, quiet, ...rest } = options;
|
|
73
80
|
const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
|
|
74
81
|
if (geoip)
|
|
75
82
|
await applyGeoip(fingerprint, pwOptions.proxy);
|
|
76
|
-
const exe = await executablePath({ executablePath: exeOption });
|
|
83
|
+
const exe = await executablePath({ executablePath: exeOption, autoUpdate, cacheDir, quiet });
|
|
77
84
|
ensureRunnableHere(exe);
|
|
78
|
-
|
|
85
|
+
const context = await chromium.launchPersistentContext(userDataDir, {
|
|
79
86
|
...pwOptions,
|
|
80
87
|
executablePath: exe,
|
|
81
88
|
args: [...fingerprintArgs(fingerprint), ...(args ?? [])],
|
|
82
89
|
});
|
|
90
|
+
installHumanizeOnContext(context, { humanize, showCursor });
|
|
91
|
+
return context;
|
|
83
92
|
}
|
|
84
93
|
export default { launch, launchPersistentContext, executablePath, download, RELEASE };
|
|
85
94
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,EAAE;AACF,wCAAwC;AACxC,oFAAoF;AACpF,0CAA0C;AAC1C,iEAAiE;AACjE,EAAE;AACF,4FAA4F;AAC5F,gGAAgG;AAChG,gGAAgG;AAChG,sBAAsB;AAEtB,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAO3C,OAAO,EAAE,YAAY,EAAwB,MAAM,eAAe,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,uBAAuB,EAA2B,MAAM,kBAAkB,CAAC;AACrG,OAAO,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAIvC,OAAO,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/release.d.ts
CHANGED
|
@@ -17,4 +17,11 @@ export interface ReleaseInfo {
|
|
|
17
17
|
os: NodeJS.Platform;
|
|
18
18
|
}
|
|
19
19
|
export declare const RELEASE: ReleaseInfo;
|
|
20
|
+
/** GitHub repo (owner/name) the releases come from — used by the opt-in auto-update resolver. */
|
|
21
|
+
export declare const REPO = "clearcotelabs/clearcote-browser";
|
|
22
|
+
/** Clearcote's release-signing key fingerprint, pinned out-of-band. This NEVER changes between
|
|
23
|
+
* releases, so it is the durable trust anchor for `autoUpdate`: when a `gpg` binary is available,
|
|
24
|
+
* an auto-resolved (un-pinned) release's `SHA256SUMS.txt.asc` is verified against THIS fingerprint
|
|
25
|
+
* before the binary is trusted. (Pinned mode trusts the baked-in sha256 instead.) */
|
|
26
|
+
export declare const SIGNING_KEY_FPR = "CA96F185F96A693AEDB3AC1FCB00D851B7A86B0F";
|
|
20
27
|
//# sourceMappingURL=release.d.ts.map
|
package/dist/release.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,EAAE,WASrB,CAAC"}
|
|
1
|
+
{"version":3,"file":"release.d.ts","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;IACZ,gFAAgF;IAChF,MAAM,EAAE,MAAM,CAAC;IACf,2FAA2F;IAC3F,SAAS,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,EAAE,EAAE,MAAM,CAAC,QAAQ,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,EAAE,WASrB,CAAC;AAEF,iGAAiG;AACjG,eAAO,MAAM,IAAI,oCAAoC,CAAC;AAEtD;;;qFAGqF;AACrF,eAAO,MAAM,eAAe,6CAA6C,CAAC"}
|
package/dist/release.js
CHANGED
|
@@ -4,13 +4,20 @@
|
|
|
4
4
|
// this package, the hash check guarantees you run exactly the published, signed binary.
|
|
5
5
|
// Published checksums + GPG signatures live on the release page.
|
|
6
6
|
export const RELEASE = {
|
|
7
|
-
tag: "v0.1.0-pre.
|
|
7
|
+
tag: "v0.1.0-pre.5",
|
|
8
8
|
version: "149.0.7827.114",
|
|
9
9
|
asset: "clearcote-149.0.7827.114-windows-x64.zip",
|
|
10
|
-
url: "https://github.com/clearcotelabs/clearcote-browser/releases/download/v0.1.0-pre.
|
|
11
|
-
sha256: "
|
|
10
|
+
url: "https://github.com/clearcotelabs/clearcote-browser/releases/download/v0.1.0-pre.5/clearcote-149.0.7827.114-windows-x64.zip",
|
|
11
|
+
sha256: "21b6c520f2866ead759c19aa02ac30570aee3ebb41f5196518c27604a693c7e6",
|
|
12
12
|
exeSha256: "5743595256c89c6874804bf3315acce592fc7f1883760c8d380c010151a73b23",
|
|
13
|
-
size:
|
|
13
|
+
size: 242548712,
|
|
14
14
|
os: "win32",
|
|
15
15
|
};
|
|
16
|
+
/** GitHub repo (owner/name) the releases come from — used by the opt-in auto-update resolver. */
|
|
17
|
+
export const REPO = "clearcotelabs/clearcote-browser";
|
|
18
|
+
/** Clearcote's release-signing key fingerprint, pinned out-of-band. This NEVER changes between
|
|
19
|
+
* releases, so it is the durable trust anchor for `autoUpdate`: when a `gpg` binary is available,
|
|
20
|
+
* an auto-resolved (un-pinned) release's `SHA256SUMS.txt.asc` is verified against THIS fingerprint
|
|
21
|
+
* before the binary is trusted. (Pinned mode trusts the baked-in sha256 instead.) */
|
|
22
|
+
export const SIGNING_KEY_FPR = "CA96F185F96A693AEDB3AC1FCB00D851B7A86B0F";
|
|
16
23
|
//# sourceMappingURL=release.js.map
|
package/dist/release.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wFAAwF;AACxF,2FAA2F;AAC3F,wFAAwF;AACxF,iEAAiE;AAqBjE,MAAM,CAAC,MAAM,OAAO,GAAgB;IAClC,GAAG,EAAE,cAAc;IACnB,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,0CAA0C;IACjD,GAAG,EAAE,4HAA4H;IACjI,MAAM,EAAE,kEAAkE;IAC1E,SAAS,EAAE,kEAAkE;IAC7E,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,OAAO;CACZ,CAAC"}
|
|
1
|
+
{"version":3,"file":"release.js","sourceRoot":"","sources":["../src/release.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,wFAAwF;AACxF,2FAA2F;AAC3F,wFAAwF;AACxF,iEAAiE;AAqBjE,MAAM,CAAC,MAAM,OAAO,GAAgB;IAClC,GAAG,EAAE,cAAc;IACnB,OAAO,EAAE,gBAAgB;IACzB,KAAK,EAAE,0CAA0C;IACjD,GAAG,EAAE,4HAA4H;IACjI,MAAM,EAAE,kEAAkE;IAC1E,SAAS,EAAE,kEAAkE;IAC7E,IAAI,EAAE,SAAS;IACf,EAAE,EAAE,OAAO;CACZ,CAAC;AAEF,iGAAiG;AACjG,MAAM,CAAC,MAAM,IAAI,GAAG,iCAAiC,CAAC;AAEtD;;;qFAGqF;AACrF,MAAM,CAAC,MAAM,eAAe,GAAG,0CAA0C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clearcote",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Playwright drop-in for the Clearcote anti-fingerprint Chromium build. launch() returns a standard Playwright Browser backed by the verified Clearcote binary, which is auto-downloaded and SHA-256 checked.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|