jumpy-lion 0.0.41 → 0.0.43
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/dist/browser-controller.d.ts.map +1 -1
- package/dist/browser-controller.js +102 -16
- package/dist/browser-controller.js.map +1 -1
- package/dist/browser-plugin.d.ts +20 -1
- package/dist/browser-plugin.d.ts.map +1 -1
- package/dist/browser-plugin.js +21 -1
- package/dist/browser-plugin.js.map +1 -1
- package/dist/browser-process/browser.d.ts +22 -1
- package/dist/browser-process/browser.d.ts.map +1 -1
- package/dist/browser-process/browser.js +77 -5
- package/dist/browser-process/browser.js.map +1 -1
- package/dist/browser-profiles/chrome/default.d.ts +116 -0
- package/dist/browser-profiles/chrome/default.d.ts.map +1 -1
- package/dist/browser-profiles/chrome/default.js +118 -1
- package/dist/browser-profiles/chrome/default.js.map +1 -1
- package/dist/browser-profiles/chrome/populate-profile.d.ts +76 -0
- package/dist/browser-profiles/chrome/populate-profile.d.ts.map +1 -0
- package/dist/browser-profiles/chrome/populate-profile.js +300 -0
- package/dist/browser-profiles/chrome/populate-profile.js.map +1 -0
- package/dist/browser-profiles/index.d.ts +1 -0
- package/dist/browser-profiles/index.d.ts.map +1 -1
- package/dist/browser-profiles/index.js +2 -0
- package/dist/browser-profiles/index.js.map +1 -1
- package/dist/crawler.d.ts +32 -1
- package/dist/crawler.d.ts.map +1 -1
- package/dist/crawler.js +7 -0
- package/dist/crawler.js.map +1 -1
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts +87 -0
- package/dist/fingerprinting/custom-fingerprint-injector.d.ts.map +1 -0
- package/dist/fingerprinting/custom-fingerprint-injector.js +342 -0
- package/dist/fingerprinting/custom-fingerprint-injector.js.map +1 -0
- package/dist/fingerprinting/fingerprint-injector.d.ts +40 -2
- package/dist/fingerprinting/fingerprint-injector.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-injector.js +452 -44
- package/dist/fingerprinting/fingerprint-injector.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/audio-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/canvas-protection.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts +14 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js +776 -0
- package/dist/fingerprinting/fingerprint-overrides/cdp-detection-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/client-rect-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts +14 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js +643 -0
- package/dist/fingerprinting/fingerprint-overrides/datadome-bypass.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/font-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts +17 -1
- package/dist/fingerprinting/fingerprint-overrides/index.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js +21 -1
- package/dist/fingerprinting/fingerprint-overrides/index.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts +45 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js +291 -0
- package/dist/fingerprinting/fingerprint-overrides/keyboard-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js +153 -90
- package/dist/fingerprinting/fingerprint-overrides/locale-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js +4 -5
- package/dist/fingerprinting/fingerprint-overrides/mouse-humanization.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/performance-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js +413 -70
- package/dist/fingerprinting/fingerprint-overrides/platform-consistency.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js +355 -0
- package/dist/fingerprinting/fingerprint-overrides/prototype-integrity.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts +12 -3
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js +261 -71
- package/dist/fingerprinting/fingerprint-overrides/runtime-enable-bypass.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts +55 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js +380 -0
- package/dist/fingerprinting/fingerprint-overrides/scroll-humanization.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts +8 -0
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js +756 -71
- package/dist/fingerprinting/fingerprint-overrides/stealth-script.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js +368 -0
- package/dist/fingerprinting/fingerprint-overrides/storage-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts +13 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js +438 -0
- package/dist/fingerprinting/fingerprint-overrides/timing-consistency.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts +7 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js +158 -58
- package/dist/fingerprinting/fingerprint-overrides/ua-ch.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/utils.d.ts +12 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.d.ts.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.js +517 -0
- package/dist/fingerprinting/fingerprint-overrides/utils.js.map +1 -0
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js +51 -10
- package/dist/fingerprinting/fingerprint-overrides/webgl-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/webgpu-spoofing.js.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.d.ts.map +1 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js +11 -1
- package/dist/fingerprinting/fingerprint-overrides/webrtc-spoofing.js.map +1 -1
- package/dist/page.d.ts +12 -0
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +35 -3
- package/dist/page.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/dist/fingerprinting/canvas-fingerprint.d.ts +0 -4
- package/dist/fingerprinting/canvas-fingerprint.d.ts.map +0 -1
- package/dist/fingerprinting/canvas-fingerprint.js +0 -60
- package/dist/fingerprinting/canvas-fingerprint.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fingerprint-injector.d.ts","sourceRoot":"","sources":["../../src/fingerprinting/fingerprint-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAGH,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"fingerprint-injector.d.ts","sourceRoot":"","sources":["../../src/fingerprinting/fingerprint-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6DG;AAGH,OAAO,KAAK,EAAE,6BAA6B,EAAE,MAAM,uBAAuB,CAAC;AAG3E,OAAO,KAAK,OAAO,MAAM,YAAY,CAAC;AAkCtC,UAAU,QAAQ;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,OAAO,CAAC;CACnB;AAED;;;GAGG;AACH,UAAU,mBAAmB;IACzB,2FAA2F;IAC3F,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6EAA6E;IAC7E,MAAM,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,UAAU,aAAa;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iDAAiD;IACjD,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;IAEjD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB,2BAA2B,CAAC,EAAE,OAAO,CAAC;IAEtC,sBAAsB,CAAC,EAAE,OAAO,CAAC;IAEjC,mEAAmE;IACnE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,sEAAsE;IACtE,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sEAAsE;IACtE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qEAAqE;IACrE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;;OAIG;IACH,YAAY,CAAC,EAAE,mBAAmB,CAAC;CACtC;AAMD,qBAAa,sBAAsB;IAC/B,OAAO,CAAC,IAAI,CAAU;gBAEV,IAAI,EAAE,OAAO;IAIzB;;;;;;;OAOG;IACH,MAAM,CAAC,2BAA2B,IAAI,aAAa;IAmCnD;;;OAGG;IACH,MAAM,CAAC,mBAAmB,IAAI,aAAa;WAyB9B,iBAAiB,CAC1B,IAAI,EAAE,OAAO,EACb,WAAW,EAAE,6BAA6B,EAC1C,OAAO,CAAC,EAAE,aAAa,GACxB,OAAO,CAAC,IAAI,CAAC;YAKF,WAAW;YAyDX,mBAAmB;YAInB,iBAAiB;YAcjB,mBAAmB;YAMnB,wBAAwB;IAKtC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAwHzB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA2CjB,YAAY,CACrB,6BAA6B,EAAE,6BAA6B,EAC5D,OAAO,CAAC,EAAE,aAAa,GACxB,OAAO,CAAC,IAAI,CAAC;CA4UnB"}
|
|
@@ -61,46 +61,59 @@
|
|
|
61
61
|
* ```
|
|
62
62
|
*/
|
|
63
63
|
import { log } from 'crawlee';
|
|
64
|
-
import { FingerprintInjector } from 'fingerprint-injector';
|
|
65
64
|
import { gotScraping } from 'got-scraping';
|
|
66
|
-
import {
|
|
65
|
+
import { createCustomFingerprintInjection } from './custom-fingerprint-injector.js';
|
|
66
|
+
import { createStealthScript, createWebGLSpoofingScript, createAudioFingerprintSpoofingScript, createAdvancedCanvasProtectionScript, createClientRectSpoofingScript, createWebRTCSpoofingScript, createWebGPUSpoofingScript, createPlatformConsistencyScript, setupMouseMovementHumanization, createRuntimeEnableBypassScript, createFontSpoofingScript, createPerformanceSpoofingScript, createLocaleSpoofingScript, createUAClientHintsSpoofingScript,
|
|
67
|
+
// Stealth utilities (must be injected first)
|
|
68
|
+
createStealthUtilsScript,
|
|
69
|
+
// Prototype integrity (must be injected early)
|
|
70
|
+
createPrototypeIntegrityScript,
|
|
71
|
+
// 2024-2025 New modules
|
|
72
|
+
createCDPDetectionBypassScript, createStorageConsistencyScript, createTimingConsistencyScript, createKeyboardHumanizationScript, createScrollHumanizationScript, createDataDomeBypassScript, setupKeyboardHumanization, setupScrollHumanization, } from './fingerprint-overrides/index.js';
|
|
67
73
|
export class CdpFingerprintInjector {
|
|
68
74
|
constructor(page) {
|
|
69
|
-
Object.defineProperty(this, "injector", {
|
|
70
|
-
enumerable: true,
|
|
71
|
-
configurable: true,
|
|
72
|
-
writable: true,
|
|
73
|
-
value: void 0
|
|
74
|
-
});
|
|
75
75
|
Object.defineProperty(this, "page", {
|
|
76
76
|
enumerable: true,
|
|
77
77
|
configurable: true,
|
|
78
78
|
writable: true,
|
|
79
79
|
value: void 0
|
|
80
80
|
});
|
|
81
|
-
this.injector = new FingerprintInjector();
|
|
82
81
|
this.page = page;
|
|
83
82
|
}
|
|
84
83
|
/**
|
|
85
84
|
* Get recommended settings for Apify platform
|
|
86
85
|
* These settings are optimized for running headful Chrome on Apify (Linux)
|
|
87
|
-
* but spoofed to appear as Windows for better anti-bot evasion
|
|
86
|
+
* but spoofed to appear as Windows for better anti-bot evasion.
|
|
87
|
+
*
|
|
88
|
+
* Note: Humanization is disabled by default for performance.
|
|
89
|
+
* Use getDataDomeSettings() or enable humanization manually for anti-bot sites.
|
|
88
90
|
*/
|
|
89
91
|
static getApifyRecommendedSettings() {
|
|
90
92
|
return {
|
|
93
|
+
debug: true, // Enable debug logging by default
|
|
91
94
|
enableAdvancedStealth: true,
|
|
92
95
|
bypassRuntimeEnable: true,
|
|
93
96
|
platform: 'Win32', // Spoof as Windows instead of Linux for better evasion
|
|
94
97
|
spoofWebGL: true,
|
|
95
98
|
spoofAudioContext: true,
|
|
96
99
|
spoofClientRects: true,
|
|
97
|
-
humanizeInteractions: true,
|
|
98
100
|
detectTimezone: true, // Auto-detect timezone from proxy
|
|
99
101
|
// New advanced spoofing options for 2025
|
|
100
102
|
spoofFonts: true,
|
|
101
103
|
spoofPerformance: true,
|
|
102
104
|
spoofLocale: true,
|
|
103
105
|
useFingerprintDefaults: true, // Use fingerprint-generator Windows values
|
|
106
|
+
// 2024-2025 DataDome bypass options
|
|
107
|
+
bypassCDPDetection: true,
|
|
108
|
+
spoofStorage: true,
|
|
109
|
+
spoofTiming: true,
|
|
110
|
+
enableDataDomeBypass: false, // Enable only when needed
|
|
111
|
+
// Humanization disabled by default for performance
|
|
112
|
+
humanization: {
|
|
113
|
+
mouse: false,
|
|
114
|
+
keyboard: false,
|
|
115
|
+
scroll: false,
|
|
116
|
+
},
|
|
104
117
|
viewport: {
|
|
105
118
|
width: 1920,
|
|
106
119
|
height: 1080,
|
|
@@ -109,20 +122,85 @@ export class CdpFingerprintInjector {
|
|
|
109
122
|
},
|
|
110
123
|
};
|
|
111
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* Get settings specifically optimized for DataDome-protected sites.
|
|
127
|
+
* Enables all humanization features for maximum anti-bot evasion.
|
|
128
|
+
*/
|
|
129
|
+
static getDataDomeSettings() {
|
|
130
|
+
return {
|
|
131
|
+
...this.getApifyRecommendedSettings(),
|
|
132
|
+
debug: true, // Enable debug logging by default
|
|
133
|
+
// DataDome-specific optimizations
|
|
134
|
+
enableDataDomeBypass: true,
|
|
135
|
+
bypassCDPDetection: true,
|
|
136
|
+
spoofStorage: true,
|
|
137
|
+
spoofTiming: true,
|
|
138
|
+
// Enable all humanization for DataDome bypass
|
|
139
|
+
humanization: {
|
|
140
|
+
mouse: true,
|
|
141
|
+
keyboard: true,
|
|
142
|
+
scroll: true,
|
|
143
|
+
},
|
|
144
|
+
// Ensure all fingerprint attributes are consistent
|
|
145
|
+
spoofWebGL: true,
|
|
146
|
+
spoofAudioContext: true,
|
|
147
|
+
spoofClientRects: true,
|
|
148
|
+
spoofFonts: true,
|
|
149
|
+
spoofPerformance: true,
|
|
150
|
+
spoofLocale: true,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
112
153
|
static async injectFingerprint(page, fingerprint, options) {
|
|
113
154
|
const handler = new CdpFingerprintInjector(page);
|
|
114
155
|
return handler.attachToPage(fingerprint, options);
|
|
115
156
|
}
|
|
116
|
-
async setViewport(viewport) {
|
|
117
|
-
|
|
157
|
+
async setViewport(viewport, fingerprint) {
|
|
158
|
+
// IMPORTANT: In headful mode, don't override viewport - it creates weird compressed layouts
|
|
159
|
+
// The browser window already has natural dimensions from the OS
|
|
160
|
+
// Only override viewport in headless mode where window size needs to be set
|
|
161
|
+
// Check if we're in headless mode
|
|
162
|
+
// In headful mode, we skip viewport override to avoid layout issues
|
|
163
|
+
const isHeadless = process.env.APIFY_HEADLESS === '1' ||
|
|
164
|
+
process.env.CRAWLEE_HEADLESS === '1' ||
|
|
165
|
+
process.env.HEADLESS === 'true';
|
|
166
|
+
if (!isHeadless) {
|
|
167
|
+
log.info('⚠️ Headful mode detected - SKIPPING viewport override to preserve natural window behavior');
|
|
168
|
+
log.info('✅ Browser will use OS window dimensions - scrolling will work naturally');
|
|
169
|
+
return; // Skip viewport override in headful mode
|
|
170
|
+
}
|
|
171
|
+
// Only apply viewport override in headless mode
|
|
172
|
+
log.info('Headless mode detected - applying viewport override');
|
|
173
|
+
let defaultViewport = {
|
|
118
174
|
width: 1920,
|
|
119
175
|
height: 1080,
|
|
120
176
|
deviceScaleFactor: 1,
|
|
121
177
|
mobile: false,
|
|
122
178
|
};
|
|
179
|
+
// Extract from fingerprint if available
|
|
180
|
+
if (fingerprint?.screen) {
|
|
181
|
+
// IMPORTANT: Set viewport height SMALLER than screen height to allow scrolling
|
|
182
|
+
// Reserve 150px for browser chrome, URL bar, and overflow space
|
|
183
|
+
const screenHeight = fingerprint.screen.height || 1080;
|
|
184
|
+
const viewportHeight = screenHeight - 150;
|
|
185
|
+
defaultViewport = {
|
|
186
|
+
width: fingerprint.screen.width || 1920,
|
|
187
|
+
height: viewportHeight,
|
|
188
|
+
deviceScaleFactor: fingerprint.screen.devicePixelRatio || 1,
|
|
189
|
+
mobile: false,
|
|
190
|
+
};
|
|
191
|
+
log.info('Viewport configured for scrolling', {
|
|
192
|
+
screenHeight,
|
|
193
|
+
viewportHeight,
|
|
194
|
+
reservedSpace: 150,
|
|
195
|
+
width: defaultViewport.width,
|
|
196
|
+
deviceScaleFactor: defaultViewport.deviceScaleFactor,
|
|
197
|
+
});
|
|
198
|
+
}
|
|
123
199
|
const finalViewport = Object.assign(defaultViewport, viewport);
|
|
124
|
-
|
|
200
|
+
log.info('Final viewport settings (headless mode)', finalViewport);
|
|
201
|
+
// CDP call to override device metrics (headless mode only)
|
|
125
202
|
await this.page.client.Emulation.setDeviceMetricsOverride(finalViewport);
|
|
203
|
+
log.info('setDeviceMetricsOverride completed (headless mode)');
|
|
126
204
|
}
|
|
127
205
|
async setExtraHTTPHeaders(headers) {
|
|
128
206
|
await this.page.client.Network.setExtraHTTPHeaders({ headers });
|
|
@@ -150,18 +228,140 @@ export class CdpFingerprintInjector {
|
|
|
150
228
|
const stealthScript = createStealthScript();
|
|
151
229
|
await this.page.client.Page.addScriptToEvaluateOnNewDocument({ source: stealthScript });
|
|
152
230
|
}
|
|
231
|
+
/**
|
|
232
|
+
* Create a debug script that logs fingerprint override status to the console
|
|
233
|
+
*/
|
|
234
|
+
createDebugScript(options) {
|
|
235
|
+
return `
|
|
236
|
+
(() => {
|
|
237
|
+
// CDP Fingerprint Override Debug Logs
|
|
238
|
+
const DEBUG_PREFIX = '[CDP-FP-DEBUG]';
|
|
239
|
+
|
|
240
|
+
console.log(DEBUG_PREFIX, '=== Fingerprint Override Status ===');
|
|
241
|
+
console.log(DEBUG_PREFIX, 'Timestamp:', new Date().toISOString());
|
|
242
|
+
|
|
243
|
+
// Check navigator properties
|
|
244
|
+
console.log(DEBUG_PREFIX, 'Navigator Checks:');
|
|
245
|
+
console.log(DEBUG_PREFIX, ' - platform:', navigator.platform);
|
|
246
|
+
console.log(DEBUG_PREFIX, ' - userAgent:', navigator.userAgent.substring(0, 80) + '...');
|
|
247
|
+
console.log(DEBUG_PREFIX, ' - webdriver:', navigator.webdriver);
|
|
248
|
+
console.log(DEBUG_PREFIX, ' - hardwareConcurrency:', navigator.hardwareConcurrency);
|
|
249
|
+
console.log(DEBUG_PREFIX, ' - deviceMemory:', navigator.deviceMemory);
|
|
250
|
+
console.log(DEBUG_PREFIX, ' - language:', navigator.language);
|
|
251
|
+
console.log(DEBUG_PREFIX, ' - languages:', navigator.languages);
|
|
252
|
+
console.log(DEBUG_PREFIX, ' - maxTouchPoints:', navigator.maxTouchPoints);
|
|
253
|
+
console.log(DEBUG_PREFIX, ' - pdfViewerEnabled:', navigator.pdfViewerEnabled);
|
|
254
|
+
console.log(DEBUG_PREFIX, ' - plugins.length:', navigator.plugins?.length);
|
|
255
|
+
|
|
256
|
+
// Check screen properties
|
|
257
|
+
console.log(DEBUG_PREFIX, 'Screen Checks:');
|
|
258
|
+
console.log(DEBUG_PREFIX, ' - colorDepth:', screen.colorDepth);
|
|
259
|
+
console.log(DEBUG_PREFIX, ' - pixelDepth:', screen.pixelDepth);
|
|
260
|
+
console.log(DEBUG_PREFIX, ' - availWidth:', screen.availWidth);
|
|
261
|
+
console.log(DEBUG_PREFIX, ' - availHeight:', screen.availHeight);
|
|
262
|
+
console.log(DEBUG_PREFIX, ' - devicePixelRatio:', window.devicePixelRatio);
|
|
263
|
+
|
|
264
|
+
// Check window properties
|
|
265
|
+
console.log(DEBUG_PREFIX, 'Window Checks:');
|
|
266
|
+
console.log(DEBUG_PREFIX, ' - outerWidth:', window.outerWidth);
|
|
267
|
+
console.log(DEBUG_PREFIX, ' - outerHeight:', window.outerHeight);
|
|
268
|
+
console.log(DEBUG_PREFIX, ' - screenX:', window.screenX);
|
|
269
|
+
console.log(DEBUG_PREFIX, ' - screenY:', window.screenY);
|
|
270
|
+
|
|
271
|
+
// Check chrome object
|
|
272
|
+
console.log(DEBUG_PREFIX, 'Chrome Object:');
|
|
273
|
+
console.log(DEBUG_PREFIX, ' - chrome exists:', typeof window.chrome !== 'undefined');
|
|
274
|
+
console.log(DEBUG_PREFIX, ' - chrome.runtime exists:', typeof window.chrome?.runtime !== 'undefined');
|
|
275
|
+
|
|
276
|
+
// Check WebGL
|
|
277
|
+
try {
|
|
278
|
+
const canvas = document.createElement('canvas');
|
|
279
|
+
const gl = canvas.getContext('webgl') || canvas.getContext('experimental-webgl');
|
|
280
|
+
if (gl) {
|
|
281
|
+
const debugInfo = gl.getExtension('WEBGL_debug_renderer_info');
|
|
282
|
+
if (debugInfo) {
|
|
283
|
+
console.log(DEBUG_PREFIX, 'WebGL Checks:');
|
|
284
|
+
console.log(DEBUG_PREFIX, ' - vendor:', gl.getParameter(debugInfo.UNMASKED_VENDOR_WEBGL));
|
|
285
|
+
console.log(DEBUG_PREFIX, ' - renderer:', gl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL));
|
|
286
|
+
} else {
|
|
287
|
+
console.log(DEBUG_PREFIX, 'WebGL debug extension not available');
|
|
288
|
+
}
|
|
289
|
+
} else {
|
|
290
|
+
console.log(DEBUG_PREFIX, 'WebGL context not available');
|
|
291
|
+
}
|
|
292
|
+
} catch (e) {
|
|
293
|
+
console.log(DEBUG_PREFIX, 'WebGL check failed:', e.message);
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// Check automation markers
|
|
297
|
+
console.log(DEBUG_PREFIX, 'Automation Marker Checks:');
|
|
298
|
+
console.log(DEBUG_PREFIX, ' - $cdc_ properties:', Object.keys(window).filter(k => k.startsWith('$cdc_') || k.startsWith('cdc_')).length === 0 ? 'CLEAN' : 'DETECTED');
|
|
299
|
+
console.log(DEBUG_PREFIX, ' - webdriver properties:', Object.keys(window).filter(k => k.toLowerCase().includes('webdriver')).length === 0 ? 'CLEAN' : 'DETECTED');
|
|
300
|
+
|
|
301
|
+
// Check permissions API
|
|
302
|
+
if (navigator.permissions) {
|
|
303
|
+
navigator.permissions.query({ name: 'notifications' }).then(result => {
|
|
304
|
+
console.log(DEBUG_PREFIX, 'Permissions:');
|
|
305
|
+
console.log(DEBUG_PREFIX, ' - notifications:', result.state);
|
|
306
|
+
}).catch(e => {
|
|
307
|
+
console.log(DEBUG_PREFIX, 'Permissions check failed:', e.message);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Check storage estimate
|
|
312
|
+
if (navigator.storage && navigator.storage.estimate) {
|
|
313
|
+
navigator.storage.estimate().then(estimate => {
|
|
314
|
+
console.log(DEBUG_PREFIX, 'Storage:');
|
|
315
|
+
console.log(DEBUG_PREFIX, ' - quota:', Math.round(estimate.quota / 1024 / 1024 / 1024) + ' GB');
|
|
316
|
+
console.log(DEBUG_PREFIX, ' - usage:', Math.round(estimate.usage / 1024) + ' KB');
|
|
317
|
+
}).catch(e => {
|
|
318
|
+
console.log(DEBUG_PREFIX, 'Storage check failed:', e.message);
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
// Log applied options
|
|
323
|
+
console.log(DEBUG_PREFIX, 'Applied Options:');
|
|
324
|
+
console.log(DEBUG_PREFIX, ' - platform:', '${options.platform || "auto"}');
|
|
325
|
+
console.log(DEBUG_PREFIX, ' - enableAdvancedStealth:', ${options.enableAdvancedStealth !== false});
|
|
326
|
+
console.log(DEBUG_PREFIX, ' - bypassCDPDetection:', ${options.bypassCDPDetection !== false});
|
|
327
|
+
console.log(DEBUG_PREFIX, ' - spoofStorage:', ${options.spoofStorage !== false});
|
|
328
|
+
console.log(DEBUG_PREFIX, ' - spoofTiming:', ${options.spoofTiming !== false});
|
|
329
|
+
console.log(DEBUG_PREFIX, ' - enableDataDomeBypass:', ${options.enableDataDomeBypass || false});
|
|
330
|
+
console.log(DEBUG_PREFIX, ' - humanization.mouse:', ${options.humanization?.mouse || false});
|
|
331
|
+
console.log(DEBUG_PREFIX, ' - humanization.keyboard:', ${options.humanization?.keyboard || false});
|
|
332
|
+
console.log(DEBUG_PREFIX, ' - humanization.scroll:', ${options.humanization?.scroll || false});
|
|
333
|
+
|
|
334
|
+
console.log(DEBUG_PREFIX, '=== End Fingerprint Override Status ===');
|
|
335
|
+
|
|
336
|
+
// Store debug info globally for later inspection
|
|
337
|
+
window.__CDP_FINGERPRINT_DEBUG__ = {
|
|
338
|
+
timestamp: new Date().toISOString(),
|
|
339
|
+
platform: navigator.platform,
|
|
340
|
+
webdriver: navigator.webdriver,
|
|
341
|
+
deviceMemory: navigator.deviceMemory,
|
|
342
|
+
hardwareConcurrency: navigator.hardwareConcurrency,
|
|
343
|
+
appliedOptions: {
|
|
344
|
+
platform: '${options.platform || "auto"}',
|
|
345
|
+
enableAdvancedStealth: ${options.enableAdvancedStealth !== false},
|
|
346
|
+
bypassCDPDetection: ${options.bypassCDPDetection !== false},
|
|
347
|
+
enableDataDomeBypass: ${options.enableDataDomeBypass || false},
|
|
348
|
+
}
|
|
349
|
+
};
|
|
350
|
+
})();
|
|
351
|
+
`;
|
|
352
|
+
}
|
|
153
353
|
/**
|
|
154
354
|
* Extract relevant data from fingerprint for overrides
|
|
155
355
|
*/
|
|
156
356
|
extractFingerprintData(fingerprint) {
|
|
157
357
|
const webglConfig = {};
|
|
158
358
|
const platformConfig = {};
|
|
159
|
-
// Extract WebGL data if available
|
|
160
|
-
if (fingerprint.
|
|
161
|
-
webglConfig.vendor = fingerprint.
|
|
162
|
-
webglConfig.renderer = fingerprint.
|
|
163
|
-
webglConfig.vendorUnmasked = fingerprint.
|
|
164
|
-
webglConfig.rendererUnmasked = fingerprint.
|
|
359
|
+
// Extract WebGL data from videoCard if available
|
|
360
|
+
if (fingerprint.videoCard) {
|
|
361
|
+
webglConfig.vendor = fingerprint.videoCard.vendor;
|
|
362
|
+
webglConfig.renderer = fingerprint.videoCard.renderer;
|
|
363
|
+
webglConfig.vendorUnmasked = fingerprint.videoCard.vendor;
|
|
364
|
+
webglConfig.rendererUnmasked = fingerprint.videoCard.renderer;
|
|
165
365
|
}
|
|
166
366
|
// Extract platform data if available
|
|
167
367
|
if (fingerprint.navigator) {
|
|
@@ -174,6 +374,12 @@ export class CdpFingerprintInjector {
|
|
|
174
374
|
platformConfig.language = fingerprint.navigator.language;
|
|
175
375
|
platformConfig.languages = fingerprint.navigator.languages;
|
|
176
376
|
platformConfig.oscpu = fingerprint.navigator.oscpu;
|
|
377
|
+
// Extract userAgent and related properties from generated fingerprint
|
|
378
|
+
platformConfig.userAgent = fingerprint.navigator.userAgent;
|
|
379
|
+
platformConfig.appVersion = fingerprint.navigator.appVersion;
|
|
380
|
+
platformConfig.appName = fingerprint.navigator.appName;
|
|
381
|
+
platformConfig.appCodeName = fingerprint.navigator.appCodeName;
|
|
382
|
+
platformConfig.product = fingerprint.navigator.product;
|
|
177
383
|
}
|
|
178
384
|
if (fingerprint.screen) {
|
|
179
385
|
platformConfig.devicePixelRatio = fingerprint.screen.devicePixelRatio;
|
|
@@ -191,21 +397,37 @@ export class CdpFingerprintInjector {
|
|
|
191
397
|
if (timezone) {
|
|
192
398
|
await this.setTimezoneOverride(timezone);
|
|
193
399
|
}
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
400
|
+
// NOTE: Page.enable() is required for addScriptToEvaluateOnNewDocument to work
|
|
401
|
+
// We enable it lazily just before script injection to minimize detection surface
|
|
402
|
+
await this.page.ensurePageEnabled();
|
|
403
|
+
// Filter headers to only include those that can be injected via CDP
|
|
404
|
+
const filteredHeaders = {};
|
|
405
|
+
const allowedHeaders = ['accept', 'accept-encoding', 'accept-language', 'user-agent', 'referer', 'sec-ch-ua', 'sec-ch-ua-mobile', 'sec-ch-ua-platform'];
|
|
406
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
407
|
+
if (allowedHeaders.includes(key.toLowerCase()) && typeof value === 'string') {
|
|
408
|
+
filteredHeaders[key] = value;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
// Create custom fingerprint injection scripts
|
|
412
|
+
log.info('Creating custom fingerprint injection scripts');
|
|
413
|
+
const customFingerprintScripts = createCustomFingerprintInjection(fingerprint, {
|
|
414
|
+
debug: options?.debug !== false,
|
|
415
|
+
throwOnError: true
|
|
416
|
+
});
|
|
417
|
+
// Prepare all scripts to inject - stealth utils and runtime bypass MUST be first
|
|
418
|
+
// These scripts set up protections BEFORE page JavaScript runs
|
|
419
|
+
const scriptsToInject = [
|
|
420
|
+
createStealthUtilsScript(), // Must be first - provides guards and toString spoofing
|
|
421
|
+
createPrototypeIntegrityScript(), // Second - provides native-like property descriptor masking
|
|
422
|
+
createRuntimeEnableBypassScript(), // Third - protects against CDP detection via Error stack analysis
|
|
423
|
+
...customFingerprintScripts, // Custom fingerprint injection replacing fingerprint-injector
|
|
424
|
+
];
|
|
205
425
|
// Always inject base stealth protections
|
|
206
426
|
await this.injectStealthProtections();
|
|
207
427
|
// Extract fingerprint data if we should use it
|
|
208
|
-
|
|
428
|
+
// When useFingerprintDefaults is true (or undefined), use hardcoded defaults
|
|
429
|
+
// When useFingerprintDefaults is false, use the generated fingerprint data
|
|
430
|
+
const shouldUseFingerprintData = options?.useFingerprintDefaults === false;
|
|
209
431
|
const { webglConfig, platformConfig } = shouldUseFingerprintData
|
|
210
432
|
? this.extractFingerprintData(fingerprint)
|
|
211
433
|
: { webglConfig: undefined, platformConfig: undefined };
|
|
@@ -243,34 +465,220 @@ export class CdpFingerprintInjector {
|
|
|
243
465
|
if (options?.spoofLocale !== false) {
|
|
244
466
|
scriptsToInject.push(createLocaleSpoofingScript());
|
|
245
467
|
}
|
|
468
|
+
// 2024-2025 New protections
|
|
469
|
+
// CDP Detection Bypass
|
|
470
|
+
if (options?.bypassCDPDetection !== false) {
|
|
471
|
+
scriptsToInject.push(createCDPDetectionBypassScript());
|
|
472
|
+
}
|
|
473
|
+
// Storage consistency
|
|
474
|
+
if (options?.spoofStorage !== false) {
|
|
475
|
+
scriptsToInject.push(createStorageConsistencyScript());
|
|
476
|
+
}
|
|
477
|
+
// Timing consistency
|
|
478
|
+
if (options?.spoofTiming !== false) {
|
|
479
|
+
scriptsToInject.push(createTimingConsistencyScript());
|
|
480
|
+
}
|
|
481
|
+
// DataDome-specific bypass
|
|
482
|
+
if (options?.enableDataDomeBypass) {
|
|
483
|
+
scriptsToInject.push(createDataDomeBypassScript());
|
|
484
|
+
}
|
|
485
|
+
// Keyboard humanization (browser context) - disabled by default
|
|
486
|
+
if (options?.humanization?.keyboard) {
|
|
487
|
+
scriptsToInject.push(createKeyboardHumanizationScript());
|
|
488
|
+
}
|
|
489
|
+
// Scroll humanization (browser context) - disabled by default
|
|
490
|
+
if (options?.humanization?.scroll) {
|
|
491
|
+
scriptsToInject.push(createScrollHumanizationScript());
|
|
492
|
+
}
|
|
246
493
|
}
|
|
247
494
|
// Apply platform consistency script
|
|
248
495
|
if (options?.platform) {
|
|
249
496
|
scriptsToInject.push(createPlatformConsistencyScript(options.platform, shouldUseFingerprintData ? platformConfig : undefined));
|
|
250
497
|
}
|
|
251
|
-
//
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
498
|
+
// CRITICAL: Clean scripts to remove CDP detection patterns
|
|
499
|
+
// Remove sourceURL comments that reveal CDP injection
|
|
500
|
+
const cleanScript = (script) => {
|
|
501
|
+
return script
|
|
502
|
+
// Remove sourceURL patterns that reveal CDP injection
|
|
503
|
+
.replace(/\/\/# sourceURL=[^\n]*/g, '')
|
|
504
|
+
.replace(/\/\/@ sourceURL=[^\n]*/g, '')
|
|
505
|
+
// Remove sourceMappingURL patterns
|
|
506
|
+
.replace(/\/\/# sourceMappingURL=[^\n]*/g, '')
|
|
507
|
+
// Remove puppeteer/playwright markers
|
|
508
|
+
.replace(/__puppeteer_evaluation_script__/g, 'anonymous')
|
|
509
|
+
.replace(/__playwright_evaluation_script__/g, 'anonymous')
|
|
510
|
+
// Remove CDP-specific comments
|
|
511
|
+
.replace(/\/\*\s*__CDP_[A-Z_]+__\s*\*\//g, '');
|
|
512
|
+
};
|
|
513
|
+
// BUNDLE ALL SCRIPTS INTO ONE to minimize CDP interactions
|
|
514
|
+
// Each addScriptToEvaluateOnNewDocument call is a detection opportunity
|
|
515
|
+
log.info(`Bundling ${scriptsToInject.length} fingerprint scripts into single injection`);
|
|
516
|
+
const bundledScript = scriptsToInject
|
|
517
|
+
.map(script => cleanScript(script))
|
|
518
|
+
.join('\n\n// --- Next Module ---\n\n');
|
|
519
|
+
// Validate bundled script for syntax errors
|
|
520
|
+
try {
|
|
521
|
+
new Function(bundledScript);
|
|
522
|
+
log.info('✓ Bundled script passed syntax validation');
|
|
523
|
+
}
|
|
524
|
+
catch (error) {
|
|
525
|
+
log.error('✗ Bundled script has syntax error:', { error });
|
|
526
|
+
// Fall back to individual script validation to find the culprit
|
|
527
|
+
scriptsToInject.forEach((script, index) => {
|
|
528
|
+
try {
|
|
529
|
+
new Function(script);
|
|
530
|
+
}
|
|
531
|
+
catch (e) {
|
|
532
|
+
const scriptPreview = script.substring(0, 300);
|
|
533
|
+
log.error(`✗ Error in script ${index + 1}:`, { error: e, scriptPreview });
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
throw new Error(`Bundled script has syntax error: ${error}`);
|
|
537
|
+
}
|
|
538
|
+
// Inject SINGLE bundled script - reduces CDP detection surface
|
|
539
|
+
try {
|
|
540
|
+
log.info('Injecting single bundled fingerprint script (minimizes CDP detection)');
|
|
541
|
+
await Promise.all([
|
|
542
|
+
this.setViewport(options?.viewport, fingerprint),
|
|
543
|
+
this.setExtraHTTPHeaders(filteredHeaders),
|
|
544
|
+
// Single script injection instead of many - reduces CDP detection surface
|
|
545
|
+
(async () => {
|
|
546
|
+
try {
|
|
547
|
+
await this.page.client.Page.addScriptToEvaluateOnNewDocument({
|
|
548
|
+
source: bundledScript
|
|
549
|
+
});
|
|
550
|
+
log.info('✓ Bundled script injected successfully');
|
|
551
|
+
}
|
|
552
|
+
catch (error) {
|
|
553
|
+
const scriptPreview = bundledScript.substring(0, 200).split('\n')[0];
|
|
554
|
+
log.error('✗ Failed to inject bundled script:', {
|
|
555
|
+
error,
|
|
556
|
+
scriptPreview,
|
|
557
|
+
});
|
|
558
|
+
throw error; // Rethrow to fail the entire injection
|
|
559
|
+
}
|
|
560
|
+
})(),
|
|
561
|
+
]);
|
|
562
|
+
log.info('✓ Fingerprint injection complete (single bundled script)');
|
|
563
|
+
}
|
|
564
|
+
catch (error) {
|
|
565
|
+
log.error('✗ Failed to inject fingerprint scripts:', { error });
|
|
566
|
+
throw error; // Rethrow to make injection failures visible
|
|
567
|
+
}
|
|
568
|
+
// Setup mouse movement humanization if requested (disabled by default)
|
|
569
|
+
// Support both legacy humanizeInteractions and new humanization.mouse
|
|
570
|
+
const enableMouseHumanization = options?.humanization?.mouse || options?.humanizeInteractions;
|
|
571
|
+
if (enableMouseHumanization) {
|
|
259
572
|
await setupMouseMovementHumanization(this.page.client);
|
|
260
573
|
}
|
|
261
|
-
//
|
|
262
|
-
|
|
263
|
-
|
|
574
|
+
// NOTE: setupRuntimeEnableBypass REMOVED - it uses Runtime.evaluate which is itself a detection vector!
|
|
575
|
+
// The bypass script is now included in the bundled stealth scripts injected via addScriptToEvaluateOnNewDocument
|
|
576
|
+
// This runs BEFORE page JavaScript, avoiding Runtime domain activation
|
|
577
|
+
// 2024-2025: CDP-level keyboard humanization (disabled by default)
|
|
578
|
+
if (options?.humanization?.keyboard) {
|
|
579
|
+
await setupKeyboardHumanization(this.page.client);
|
|
580
|
+
}
|
|
581
|
+
// 2024-2025: CDP-level scroll humanization (disabled by default)
|
|
582
|
+
if (options?.humanization?.scroll) {
|
|
583
|
+
await setupScrollHumanization(this.page.client);
|
|
584
|
+
}
|
|
585
|
+
// Inject debug script for browser console verification (always inject for debugging)
|
|
586
|
+
if (options?.debug !== false) {
|
|
587
|
+
const debugScript = this.createDebugScript(options || {});
|
|
588
|
+
await this.page.client.Page.addScriptToEvaluateOnNewDocument({ source: debugScript });
|
|
264
589
|
}
|
|
265
590
|
log.info('Enhanced fingerprint attached with settings:', {
|
|
266
591
|
proxy: options?.proxyUrl,
|
|
267
592
|
timezone,
|
|
268
593
|
advancedStealth: options?.enableAdvancedStealth !== false,
|
|
269
|
-
humanizeInteractions: options?.humanizeInteractions,
|
|
270
594
|
bypassRuntimeEnable: options?.bypassRuntimeEnable,
|
|
271
595
|
platform: options?.platform,
|
|
272
596
|
useFingerprintDefaults: options?.useFingerprintDefaults,
|
|
597
|
+
// 2024-2025 new options
|
|
598
|
+
bypassCDPDetection: options?.bypassCDPDetection !== false,
|
|
599
|
+
spoofStorage: options?.spoofStorage !== false,
|
|
600
|
+
spoofTiming: options?.spoofTiming !== false,
|
|
601
|
+
enableDataDomeBypass: options?.enableDataDomeBypass,
|
|
602
|
+
// Humanization options
|
|
603
|
+
humanization: {
|
|
604
|
+
mouse: enableMouseHumanization || false,
|
|
605
|
+
keyboard: options?.humanization?.keyboard || false,
|
|
606
|
+
scroll: options?.humanization?.scroll || false,
|
|
607
|
+
},
|
|
608
|
+
// Viewport info
|
|
609
|
+
viewport: options?.viewport,
|
|
610
|
+
fingerprintScreen: fingerprint?.screen ? {
|
|
611
|
+
width: fingerprint.screen.width,
|
|
612
|
+
height: fingerprint.screen.height,
|
|
613
|
+
devicePixelRatio: fingerprint.screen.devicePixelRatio,
|
|
614
|
+
} : undefined,
|
|
273
615
|
});
|
|
616
|
+
// Add a debug script to log viewport info in the browser console
|
|
617
|
+
const viewportDebugScript = `
|
|
618
|
+
(() => {
|
|
619
|
+
console.log('[VIEWPORT-DEBUG] Initial window dimensions:', {
|
|
620
|
+
innerWidth: window.innerWidth,
|
|
621
|
+
innerHeight: window.innerHeight,
|
|
622
|
+
outerWidth: window.outerWidth,
|
|
623
|
+
outerHeight: window.outerHeight,
|
|
624
|
+
screenWidth: screen.width,
|
|
625
|
+
screenHeight: screen.height,
|
|
626
|
+
availWidth: screen.availWidth,
|
|
627
|
+
availHeight: screen.availHeight,
|
|
628
|
+
devicePixelRatio: window.devicePixelRatio,
|
|
629
|
+
scrollY: window.scrollY,
|
|
630
|
+
scrollHeight: document.documentElement?.scrollHeight || 'N/A',
|
|
631
|
+
clientHeight: document.documentElement?.clientHeight || 'N/A'
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
// Check consistency
|
|
635
|
+
const inconsistencies = [];
|
|
636
|
+
if (window.innerWidth !== screen.width && Math.abs(window.innerWidth - screen.width) > 50) {
|
|
637
|
+
inconsistencies.push(\`innerWidth (\${window.innerWidth}) != screen.width (\${screen.width})\`);
|
|
638
|
+
}
|
|
639
|
+
if (window.innerHeight !== screen.height && Math.abs(window.innerHeight - screen.height) > 100) {
|
|
640
|
+
inconsistencies.push(\`innerHeight (\${window.innerHeight}) != screen.height (\${screen.height})\`);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (inconsistencies.length > 0) {
|
|
644
|
+
console.warn('[VIEWPORT-DEBUG] ⚠️ INCONSISTENCIES DETECTED:', inconsistencies);
|
|
645
|
+
} else {
|
|
646
|
+
console.log('[VIEWPORT-DEBUG] ✅ Dimensions appear consistent');
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
// Test scrolling after DOM is ready
|
|
650
|
+
const checkScroll = () => {
|
|
651
|
+
if (document.documentElement) {
|
|
652
|
+
const scrollHeight = document.documentElement.scrollHeight;
|
|
653
|
+
const clientHeight = document.documentElement.clientHeight;
|
|
654
|
+
const canScroll = scrollHeight > clientHeight;
|
|
655
|
+
|
|
656
|
+
console.log('[VIEWPORT-DEBUG] After load:', {
|
|
657
|
+
scrollHeight,
|
|
658
|
+
clientHeight,
|
|
659
|
+
canScroll,
|
|
660
|
+
overflow: scrollHeight - clientHeight,
|
|
661
|
+
bodyHeight: document.body?.scrollHeight,
|
|
662
|
+
innerHeight: window.innerHeight,
|
|
663
|
+
screenHeight: screen.height
|
|
664
|
+
});
|
|
665
|
+
|
|
666
|
+
if (canScroll) {
|
|
667
|
+
console.log('[VIEWPORT-DEBUG] ✅ SCROLLING ENABLED - Page has', scrollHeight - clientHeight, 'px overflow');
|
|
668
|
+
} else {
|
|
669
|
+
console.log('[VIEWPORT-DEBUG] ⚠️ NO OVERFLOW - Cannot scroll (scrollHeight === clientHeight)');
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
};
|
|
673
|
+
|
|
674
|
+
if (document.readyState === 'loading') {
|
|
675
|
+
document.addEventListener('DOMContentLoaded', checkScroll);
|
|
676
|
+
} else {
|
|
677
|
+
setTimeout(checkScroll, 1000);
|
|
678
|
+
}
|
|
679
|
+
})();
|
|
680
|
+
`;
|
|
681
|
+
await this.page.client.Page.addScriptToEvaluateOnNewDocument({ source: viewportDebugScript });
|
|
274
682
|
}
|
|
275
683
|
}
|
|
276
684
|
//# sourceMappingURL=fingerprint-injector.js.map
|