clearcote 0.2.0 → 0.3.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 +7 -5
- 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 +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +14 -5
- package/dist/index.js.map +1 -1
- package/dist/release.js +4 -4
- 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
|
|
|
@@ -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,9 +1,11 @@
|
|
|
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. */
|
|
@@ -11,10 +13,10 @@ interface GeoipOption {
|
|
|
11
13
|
geoip?: boolean;
|
|
12
14
|
}
|
|
13
15
|
/** Options for {@link launch}: Playwright launch options + Clearcote fingerprint options. */
|
|
14
|
-
export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption {
|
|
16
|
+
export interface LaunchOptions extends PlaywrightLaunchOptions, FingerprintOptions, GeoipOption, HumanizeOptions {
|
|
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 {
|
|
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,6FAA6F;AAC7F,MAAM,WAAW,aAAc,SAAQ,uBAAuB,EAAE,kBAAkB,EAAE,WAAW,EAAE,eAAe;CAAG;AAEnH,mDAAmD;AACnD,MAAM,WAAW,wBACf,SAAQ,uBAAuB,EAC7B,qBAAqB,EACrB,kBAAkB,EAClB,WAAW,EACX,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") {
|
|
@@ -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, ...rest } = options;
|
|
56
61
|
const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
|
|
57
62
|
if (geoip)
|
|
58
63
|
await applyGeoip(fingerprint, pwOptions.proxy);
|
|
59
64
|
const exe = await executablePath({ executablePath: exeOption });
|
|
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, ...rest } = options;
|
|
73
80
|
const { fingerprint, rest: pwOptions } = splitFingerprintOptions(rest);
|
|
74
81
|
if (geoip)
|
|
75
82
|
await applyGeoip(fingerprint, pwOptions.proxy);
|
|
76
83
|
const exe = await executablePath({ executablePath: exeOption });
|
|
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.js
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
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
16
|
//# sourceMappingURL=release.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clearcote",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.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",
|