@fanboynz/network-scanner 1.0.85 → 1.0.87

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.
@@ -5,6 +5,89 @@
5
5
 
6
6
  const { formatLogMessage, messageColors } = require('./colorize');
7
7
 
8
+ /**
9
+ * Quick browser responsiveness test for use during page setup
10
+ * Designed to catch browser degradation between operations
11
+ * @param {import('puppeteer').Browser} browserInstance - Puppeteer browser instance
12
+ * @param {number} timeout - Timeout in milliseconds (default: 3000)
13
+ * @returns {Promise<boolean>} True if browser responds quickly, false otherwise
14
+ */
15
+ async function isQuicklyResponsive(browserInstance, timeout = 3000) {
16
+ try {
17
+ await Promise.race([
18
+ browserInstance.version(), // Quick responsiveness test
19
+ new Promise((_, reject) =>
20
+ setTimeout(() => reject(new Error('Quick responsiveness timeout')), timeout)
21
+ )
22
+ ]);
23
+ return true;
24
+ } catch (error) {
25
+ return false;
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Tests if browser can handle network operations (like Network.enable)
31
+ * Creates a test page and attempts basic network setup
32
+ * @param {import('puppeteer').Browser} browserInstance - Puppeteer browser instance
33
+ * @param {number} timeout - Timeout in milliseconds (default: 10000)
34
+ * @returns {Promise<object>} Network capability test result
35
+ */
36
+ async function testNetworkCapability(browserInstance, timeout = 10000) {
37
+ const result = {
38
+ capable: false,
39
+ error: null,
40
+ responseTime: 0
41
+ };
42
+
43
+ const startTime = Date.now();
44
+ let testPage = null;
45
+
46
+ try {
47
+ // Create test page
48
+ testPage = await Promise.race([
49
+ browserInstance.newPage(),
50
+ new Promise((_, reject) =>
51
+ setTimeout(() => reject(new Error('Test page creation timeout')), timeout)
52
+ )
53
+ ]);
54
+
55
+ // Test network operations (the critical operation that's failing)
56
+ await Promise.race([
57
+ testPage.setRequestInterception(true),
58
+ new Promise((_, reject) =>
59
+ setTimeout(() => reject(new Error('Network.enable test timeout')), timeout)
60
+ )
61
+ ]);
62
+
63
+ // Turn off interception and close
64
+ await testPage.setRequestInterception(false);
65
+ result.capable = true;
66
+ result.responseTime = Date.now() - startTime;
67
+
68
+ } catch (error) {
69
+ result.error = error.message;
70
+ result.responseTime = Date.now() - startTime;
71
+
72
+ // Classify the error type
73
+ if (error.message.includes('Network.enable') ||
74
+ error.message.includes('timed out') ||
75
+ error.message.includes('Protocol error')) {
76
+ result.error = `Network capability test failed: ${error.message}`;
77
+ }
78
+ } finally {
79
+ if (testPage && !testPage.isClosed()) {
80
+ try {
81
+ await testPage.close();
82
+ } catch (closeErr) {
83
+ /* ignore cleanup errors */
84
+ }
85
+ }
86
+ }
87
+
88
+ return result;
89
+ }
90
+
8
91
  /**
9
92
  * Checks if browser instance is still responsive
10
93
  * @param {import('puppeteer').Browser} browserInstance - Puppeteer browser instance
@@ -18,7 +101,8 @@ async function checkBrowserHealth(browserInstance, timeout = 8000) {
18
101
  error: null,
19
102
  responseTime: 0,
20
103
  recommendations: [],
21
- criticalError: false
104
+ criticalError: false,
105
+ networkCapable: false
22
106
  };
23
107
 
24
108
  const startTime = Date.now();
@@ -82,13 +166,25 @@ async function checkBrowserHealth(browserInstance, timeout = 8000) {
82
166
  return healthResult;
83
167
  }
84
168
 
85
- // Test 5: Check response time performance
169
+ // Test 5: Network capability test (critical for Network.enable issues)
170
+ const networkTest = await testNetworkCapability(browserInstance, Math.min(timeout, 5000));
171
+ healthResult.networkCapable = networkTest.capable;
172
+
173
+ if (!networkTest.capable) {
174
+ healthResult.recommendations.push(`Network operations failing: ${networkTest.error}`);
175
+ if (networkTest.error && networkTest.error.includes('Network.enable')) {
176
+ healthResult.criticalError = true;
177
+ }
178
+ }
179
+
180
+ // Test 6: Check response time performance
86
181
  if (healthResult.responseTime > 5000) {
87
182
  healthResult.recommendations.push('Slow browser response - consider restart');
88
183
  }
89
184
 
90
- // If all tests pass
91
- healthResult.healthy = true;
185
+ // If all tests pass (including network capability)
186
+ healthResult.healthy = networkTest.capable; // Network capability is now critical for health
187
+
92
188
 
93
189
  } catch (error) {
94
190
  healthResult.error = error.message;
@@ -195,7 +291,11 @@ function isCriticalProtocolError(error) {
195
291
  'Browser process exited',
196
292
  'Navigation timeout of',
197
293
  'Page crashed',
198
- 'Renderer process crashed'
294
+ 'Renderer process crashed',
295
+ // Network-specific critical errors
296
+ 'Network.enable timed out',
297
+ 'Network.disable timed out',
298
+ 'Network service not available'
199
299
  ];
200
300
 
201
301
  return criticalErrors.some(criticalError =>
@@ -413,14 +513,25 @@ async function monitorBrowserHealth(browserInstance, context = {}, options = {})
413
513
 
414
514
  /**
415
515
  * Simple health check function for quick integration
516
+ * Enhanced version that includes network capability testing
416
517
  * @param {import('puppeteer').Browser} browserInstance - Puppeteer browser instance
518
+ * @param {boolean} includeNetworkTest - Whether to test network capabilities (default: true)
417
519
  * @returns {Promise<boolean>} True if browser is healthy, false otherwise
418
520
  */
419
- async function isBrowserHealthy(browserInstance) {
521
+ async function isBrowserHealthy(browserInstance, includeNetworkTest = true) {
420
522
  try {
421
- const health = await checkBrowserHealth(browserInstance, 5000); // Faster timeout
523
+ // Quick responsiveness test first (fastest check)
524
+ const quickCheck = await isQuicklyResponsive(browserInstance, 2500);
525
+ if (!quickCheck) return false;
526
+
527
+ // More comprehensive health check if quick test passes
528
+ const health = await checkBrowserHealth(browserInstance, includeNetworkTest ? 8000 : 5000);
422
529
  const connectivity = await testBrowserConnectivity(browserInstance, 3000);
423
- return health.healthy && connectivity.connected && connectivity.cdpResponsive;
530
+
531
+ const baseHealth = health.healthy && connectivity.connected && connectivity.cdpResponsive;
532
+
533
+ // Include network capability in health assessment if requested
534
+ return includeNetworkTest ? (baseHealth && health.networkCapable) : baseHealth;
424
535
  } catch (error) {
425
536
  return false;
426
537
  }
@@ -430,6 +541,8 @@ module.exports = {
430
541
  checkBrowserHealth,
431
542
  checkBrowserMemory,
432
543
  testBrowserConnectivity,
544
+ testNetworkCapability,
545
+ isQuicklyResponsive,
433
546
  performHealthAssessment,
434
547
  monitorBrowserHealth,
435
548
  isBrowserHealthy,
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.4.1 - Bump timeout values
3
4
  * Version: 2.4.0 - Fix possible endless loops with retry logic and loop detection
4
5
  * Version: 2.3.1 - Colorize CF
5
6
  * Version: 2.3.0 - Support CF iframe challenges, and better error handling
@@ -26,9 +27,9 @@ const TIMEOUTS = {
26
27
  PAGE_EVALUATION_SAFE: 10000, // Safe page evaluation with extra buffer
27
28
  PHISHING_CLICK: 3000, // Timeout for clicking phishing continue button
28
29
  PHISHING_NAVIGATION: 8000, // Wait for navigation after phishing bypass
29
- JS_CHALLENGE_BUFFER: 18000, // JS challenge with safety buffer
30
- TURNSTILE_COMPLETION: 12000, // Turnstile completion check
31
- TURNSTILE_COMPLETION_BUFFER: 15000, // Turnstile completion with buffer
30
+ JS_CHALLENGE_BUFFER: 30000, // JS challenge with safety buffer
31
+ TURNSTILE_COMPLETION: 20000, // Turnstile completion check
32
+ TURNSTILE_COMPLETION_BUFFER: 25000, // Turnstile completion with buffer
32
33
  CLICK_TIMEOUT: 5000, // Standard click operation timeout
33
34
  CLICK_TIMEOUT_BUFFER: 1000, // Click timeout safety buffer
34
35
  NAVIGATION_TIMEOUT: 15000, // Standard navigation timeout
@@ -52,9 +53,9 @@ const FAST_TIMEOUTS = {
52
53
  ELEMENT_INTERACTION_DELAY: 250, // Fast element interactions
53
54
  SELECTOR_WAIT: 1500, // Fast selector waits
54
55
  TURNSTILE_OPERATION: 6000, // Fast Turnstile operations
55
- JS_CHALLENGE: 12000, // Fast JS challenge completion
56
- CHALLENGE_SOLVING: 15000, // Fast overall challenge solving
57
- CHALLENGE_COMPLETION: 3000 // Fast completion check
56
+ JS_CHALLENGE: 22000, // Fast JS challenge completion
57
+ CHALLENGE_SOLVING: 30000, // Fast overall challenge solving
58
+ CHALLENGE_COMPLETION: 8000 // Fast completion check
58
59
  };
59
60
 
60
61
  /**
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v1.0.85 ===
1
+ // === Network scanner script (nwss.js) v1.0.87 ===
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
@@ -120,10 +120,10 @@ function detectPuppeteerVersion() {
120
120
  // Enhanced redirect handling
121
121
  const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/redirect');
122
122
  // Ensure web browser is working correctly
123
- const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
123
+ const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive } = require('./lib/browserhealth');
124
124
 
125
125
  // --- Script Configuration & Constants ---
126
- const VERSION = '1.0.85'; // Script version
126
+ const VERSION = '1.0.87'; // Script version
127
127
 
128
128
  // get startTime
129
129
  const startTime = Date.now();
@@ -1483,6 +1483,22 @@ function setupFrameHandling(page, forceDebug) {
1483
1483
  if (!page || page.isClosed()) {
1484
1484
  throw new Error('Failed to create valid page instance');
1485
1485
  }
1486
+
1487
+ // Additional health check after page creation but before critical setup
1488
+ const stillHealthy = await isQuicklyResponsive(browserInstance, 3000);
1489
+
1490
+ if (!stillHealthy) {
1491
+ if (forceDebug) {
1492
+ console.log(formatLogMessage('debug', `Browser unresponsive during page setup for ${currentUrl} - triggering restart`));
1493
+ }
1494
+ return {
1495
+ url: currentUrl,
1496
+ rules: [],
1497
+ success: false,
1498
+ needsImmediateRestart: true,
1499
+ error: 'Browser became unresponsive during page setup - restart required'
1500
+ };
1501
+ }
1486
1502
 
1487
1503
  // Set aggressive timeouts for problematic operations
1488
1504
  // Optimized timeouts for Puppeteer 23.x responsiveness
@@ -1572,6 +1588,22 @@ function setupFrameHandling(page, forceDebug) {
1572
1588
  console.log(formatLogMessage('debug', `[evalOnDoc] Site-specific Fetch/XHR interception enabled for: ${currentUrl}`));
1573
1589
  }
1574
1590
  }
1591
+ // Quick browser health check before script injection
1592
+ let browserResponsive = false;
1593
+ try {
1594
+ await Promise.race([
1595
+ browserInstance.version(), // Quick responsiveness test
1596
+ new Promise((_, reject) =>
1597
+ setTimeout(() => reject(new Error('Browser health check timeout')), 5000)
1598
+ )
1599
+ ]);
1600
+ browserResponsive = true;
1601
+ } catch (healthErr) {
1602
+ console.warn(formatLogMessage('warn', `[evalOnDoc] Browser unresponsive for ${currentUrl}: ${healthErr.message} - skipping script injection`));
1603
+ browserResponsive = false;
1604
+ }
1605
+
1606
+ if (browserResponsive) {
1575
1607
  try {
1576
1608
  await page.evaluateOnNewDocument(() => {
1577
1609
  // Prevent infinite reload loops
@@ -1636,7 +1668,16 @@ function setupFrameHandling(page, forceDebug) {
1636
1668
  };
1637
1669
  });
1638
1670
  } catch (evalErr) {
1639
- console.warn(formatLogMessage('warn', `[evalOnDoc] Failed to set up Fetch/XHR interception for ${currentUrl}: ${evalErr.message}`));
1671
+ if (evalErr.message.includes('timed out') || evalErr.message.includes('ProtocolError')) {
1672
+ console.warn(formatLogMessage('warn', `[evalOnDoc] Script injection protocol timeout for ${currentUrl} - continuing without XHR/Fetch interception`));
1673
+ } else {
1674
+ console.warn(formatLogMessage('warn', `[evalOnDoc] Failed to set up Fetch/XHR interception for ${currentUrl}: ${evalErr.message}`));
1675
+ }
1676
+ }
1677
+ } else {
1678
+ if (forceDebug) {
1679
+ console.log(formatLogMessage('debug', `[evalOnDoc] Continuing ${currentUrl} without XHR/Fetch interception due to browser health`));
1680
+ }
1640
1681
  }
1641
1682
  }
1642
1683
  // --- END: evaluateOnNewDocument for Fetch/XHR Interception ---
@@ -1683,7 +1724,34 @@ function setupFrameHandling(page, forceDebug) {
1683
1724
  }
1684
1725
  // --- End of Per-Page CDP Setup ---
1685
1726
 
1686
- await page.setRequestInterception(true);
1727
+ // Protected request interception setup with timeout
1728
+ try {
1729
+ // Test if network operations are responsive before enabling request interception
1730
+ await Promise.race([
1731
+ page.setRequestInterception(true),
1732
+ new Promise((_, reject) =>
1733
+ setTimeout(() => reject(new Error('Network.enable timeout')), 10000)
1734
+ )
1735
+ ]);
1736
+
1737
+ if (forceDebug) {
1738
+ console.log(formatLogMessage('debug', `Request interception enabled successfully for ${currentUrl}`));
1739
+ }
1740
+ } catch (networkErr) {
1741
+ if (networkErr.message.includes('timed out') ||
1742
+ networkErr.message.includes('Network.enable') ||
1743
+ networkErr.message.includes('timeout')) {
1744
+ console.warn(formatLogMessage('warn', `Network setup failed for ${currentUrl}: ${networkErr.message} - triggering browser restart`));
1745
+ return {
1746
+ url: currentUrl,
1747
+ rules: [],
1748
+ success: false,
1749
+ needsImmediateRestart: true,
1750
+ error: 'Network.enable timeout - browser restart required'
1751
+ };
1752
+ }
1753
+ throw networkErr; // Re-throw other errors
1754
+ }
1687
1755
 
1688
1756
  // Set up frame handling to suppress invalid URL errors
1689
1757
  setupFrameHandling(page, forceDebug);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "1.0.85",
3
+ "version": "1.0.87",
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": {