@fanboynz/network-scanner 2.0.3 → 2.0.4
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/lib/cloudflare.js +31 -30
- package/nwss.js +2 -2
- package/package.json +1 -1
package/lib/cloudflare.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cloudflare bypass and challenge handling module - Optimized with smart detection and adaptive timeouts
|
|
3
|
+
* Version: 2.6.1 - timeoutId is not defined & race condition fix
|
|
3
4
|
* Version: 2.6.0 - Memory leak fixes and timeout cleanup
|
|
4
5
|
* Version: 2.5.0 - Fix Frame Lifecycle issue, Timing and Race condition
|
|
5
6
|
* Version: 2.4.1 - Bump timeout values
|
|
@@ -17,7 +18,7 @@ const { formatLogMessage } = require('./colorize');
|
|
|
17
18
|
/**
|
|
18
19
|
* Module version information
|
|
19
20
|
*/
|
|
20
|
-
const CLOUDFLARE_MODULE_VERSION = '2.6.
|
|
21
|
+
const CLOUDFLARE_MODULE_VERSION = '2.6.1';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Timeout constants for various operations (in milliseconds)
|
|
@@ -319,21 +320,23 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
|
|
|
319
320
|
let lastError = null;
|
|
320
321
|
|
|
321
322
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
323
|
+
let timeoutId = null;
|
|
324
|
+
|
|
322
325
|
try {
|
|
323
|
-
// Validate page
|
|
326
|
+
// Validate page state before evaluation
|
|
324
327
|
if (page.isClosed()) {
|
|
325
328
|
throw new Error('Page is closed');
|
|
326
329
|
}
|
|
327
330
|
|
|
328
|
-
// Check if main frame is still attached
|
|
329
|
-
const mainFrame = page.mainFrame();
|
|
330
|
-
if (mainFrame.isDetached()) {
|
|
331
|
-
throw new Error('Main frame is detached');
|
|
332
|
-
}
|
|
333
331
|
|
|
334
|
-
let timeoutId = null;
|
|
335
332
|
const result = await Promise.race([
|
|
336
|
-
page.evaluate(
|
|
333
|
+
page.evaluate(() => {
|
|
334
|
+
// Validate execution context inside evaluation to prevent race
|
|
335
|
+
if (typeof window === 'undefined' || !document) {
|
|
336
|
+
throw new Error('Execution context invalid');
|
|
337
|
+
}
|
|
338
|
+
return (func)();
|
|
339
|
+
}),
|
|
337
340
|
new Promise((_, reject) => {
|
|
338
341
|
timeoutId = setTimeout(() => reject(new Error('Page evaluation timeout')), timeout);
|
|
339
342
|
})
|
|
@@ -342,7 +345,6 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
|
|
|
342
345
|
// Clear timeout if evaluation completed first
|
|
343
346
|
if (timeoutId) {
|
|
344
347
|
clearTimeout(timeoutId);
|
|
345
|
-
timeoutId = null;
|
|
346
348
|
}
|
|
347
349
|
|
|
348
350
|
if (forceDebug && attempt > 1) {
|
|
@@ -354,7 +356,6 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
|
|
|
354
356
|
// Ensure timeout is cleared on any error
|
|
355
357
|
if (timeoutId) {
|
|
356
358
|
clearTimeout(timeoutId);
|
|
357
|
-
timeoutId = null;
|
|
358
359
|
}
|
|
359
360
|
|
|
360
361
|
lastError = error;
|
|
@@ -427,8 +428,7 @@ async function safeClick(page, selector, timeout = TIMEOUTS.CLICK_TIMEOUT) {
|
|
|
427
428
|
return await Promise.race([
|
|
428
429
|
page.click(selector, { timeout: timeout }),
|
|
429
430
|
new Promise((_, reject) => {
|
|
430
|
-
|
|
431
|
-
// Timer will be cleared when promise resolves/rejects
|
|
431
|
+
setTimeout(() => reject(new Error('Click timeout')), timeout + TIMEOUTS.CLICK_TIMEOUT_BUFFER);
|
|
432
432
|
})
|
|
433
433
|
]);
|
|
434
434
|
} catch (error) {
|
|
@@ -444,8 +444,7 @@ async function safeWaitForNavigation(page, timeout = TIMEOUTS.NAVIGATION_TIMEOUT
|
|
|
444
444
|
return await Promise.race([
|
|
445
445
|
page.waitForNavigation({ waitUntil: 'domcontentloaded', timeout: timeout }),
|
|
446
446
|
new Promise((_, reject) => {
|
|
447
|
-
|
|
448
|
-
// Timer will be cleared when promise resolves/rejects
|
|
447
|
+
setTimeout(() => reject(new Error('Navigation timeout')), timeout + TIMEOUTS.NAVIGATION_TIMEOUT_BUFFER);
|
|
449
448
|
})
|
|
450
449
|
]);
|
|
451
450
|
} catch (error) {
|
|
@@ -963,13 +962,14 @@ async function attemptChallengeSolveWithTimeout(page, currentUrl, challengeInfo,
|
|
|
963
962
|
const result = {
|
|
964
963
|
success: false,
|
|
965
964
|
error: null,
|
|
966
|
-
method: null
|
|
967
|
-
_timeoutId: null
|
|
965
|
+
method: null
|
|
968
966
|
};
|
|
967
|
+
|
|
968
|
+
let timeoutId = null;
|
|
969
969
|
|
|
970
970
|
try {
|
|
971
971
|
const timeoutPromise = new Promise((_, reject) => {
|
|
972
|
-
|
|
972
|
+
timeoutId = setTimeout(() => reject(new Error('Challenge solving timeout')), FAST_TIMEOUTS.CHALLENGE_SOLVING);
|
|
973
973
|
});
|
|
974
974
|
// Reduced timeout for challenge solving
|
|
975
975
|
const finalResult = await Promise.race([
|
|
@@ -977,15 +977,15 @@ async function attemptChallengeSolveWithTimeout(page, currentUrl, challengeInfo,
|
|
|
977
977
|
timeoutPromise
|
|
978
978
|
]);
|
|
979
979
|
// Clear timeout if operation completed first
|
|
980
|
-
if (
|
|
981
|
-
clearTimeout(
|
|
980
|
+
if (timeoutId) {
|
|
981
|
+
clearTimeout(timeoutId);
|
|
982
982
|
}
|
|
983
983
|
return finalResult;
|
|
984
984
|
|
|
985
985
|
} catch (error) {
|
|
986
986
|
// Clear timeout on error
|
|
987
|
-
if (
|
|
988
|
-
clearTimeout(
|
|
987
|
+
if (timeoutId) {
|
|
988
|
+
clearTimeout(timeoutId);
|
|
989
989
|
}
|
|
990
990
|
result.error = `Challenge solving timed out: ${error.message}`;
|
|
991
991
|
if (forceDebug) console.log(formatLogMessage('cloudflare', `Challenge solving timeout for ${currentUrl}`));
|
|
@@ -1205,15 +1205,16 @@ async function handleEmbeddedIframeChallenge(page, forceDebug = false) {
|
|
|
1205
1205
|
async function waitForJSChallengeCompletion(page, forceDebug = false) {
|
|
1206
1206
|
const result = {
|
|
1207
1207
|
success: false,
|
|
1208
|
-
error: null
|
|
1209
|
-
_timeoutId: null
|
|
1208
|
+
error: null
|
|
1210
1209
|
};
|
|
1211
1210
|
|
|
1211
|
+
let timeoutId = null;
|
|
1212
|
+
|
|
1212
1213
|
try {
|
|
1213
1214
|
if (forceDebug) console.log(formatLogMessage('cloudflare', `Waiting for JS challenge completion`));
|
|
1214
1215
|
|
|
1215
1216
|
const timeoutPromise = new Promise((_, reject) => {
|
|
1216
|
-
|
|
1217
|
+
timeoutId = setTimeout(() => reject(new Error('JS challenge timeout')), TIMEOUTS.JS_CHALLENGE_BUFFER);
|
|
1217
1218
|
});
|
|
1218
1219
|
|
|
1219
1220
|
// Reduced timeout for JS challenge completion
|
|
@@ -1231,16 +1232,16 @@ async function waitForJSChallengeCompletion(page, forceDebug = false) {
|
|
|
1231
1232
|
]);
|
|
1232
1233
|
|
|
1233
1234
|
// Clear timeout if completion detected first
|
|
1234
|
-
if (
|
|
1235
|
-
clearTimeout(
|
|
1235
|
+
if (timeoutId) {
|
|
1236
|
+
clearTimeout(timeoutId);
|
|
1236
1237
|
}
|
|
1237
1238
|
|
|
1238
1239
|
result.success = true;
|
|
1239
1240
|
if (forceDebug) console.log(formatLogMessage('cloudflare', `JS challenge completed automatically`));
|
|
1240
1241
|
} catch (error) {
|
|
1241
1242
|
// Clear timeout on error
|
|
1242
|
-
if (
|
|
1243
|
-
clearTimeout(
|
|
1243
|
+
if (timeoutId) {
|
|
1244
|
+
clearTimeout(timeoutId);
|
|
1244
1245
|
}
|
|
1245
1246
|
|
|
1246
1247
|
result.error = `JS challenge timeout: ${error.message}`;
|
|
@@ -1844,4 +1845,4 @@ module.exports = {
|
|
|
1844
1845
|
detectChallengeLoop,
|
|
1845
1846
|
// Memory management
|
|
1846
1847
|
cleanup
|
|
1847
|
-
};
|
|
1848
|
+
};
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v2.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v2.0.4 ===
|
|
2
2
|
|
|
3
3
|
// puppeteer for browser automation, fs for file system operations, psl for domain parsing.
|
|
4
4
|
// const pLimit = require('p-limit'); // Will be dynamically imported
|
|
@@ -127,7 +127,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
127
127
|
const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage } = require('./lib/browserhealth');
|
|
128
128
|
|
|
129
129
|
// --- Script Configuration & Constants ---
|
|
130
|
-
const VERSION = '2.0.
|
|
130
|
+
const VERSION = '2.0.4'; // Script version
|
|
131
131
|
|
|
132
132
|
// get startTime
|
|
133
133
|
const startTime = Date.now();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.4",
|
|
4
4
|
"description": "A Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features include fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, and multiple output formats.",
|
|
5
5
|
"main": "nwss.js",
|
|
6
6
|
"scripts": {
|