@fanboynz/network-scanner 1.0.99 → 2.0.2

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 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.5.0 - Fix Frame Lifecycle issue, Timing and Race condition
3
4
  * Version: 2.4.1 - Bump timeout values
4
5
  * Version: 2.4.0 - Fix possible endless loops with retry logic and loop detection
5
6
  * Version: 2.3.1 - Colorize CF
@@ -15,7 +16,7 @@ const { formatLogMessage } = require('./colorize');
15
16
  /**
16
17
  * Module version information
17
18
  */
18
- const CLOUDFLARE_MODULE_VERSION = '2.4.0';
19
+ const CLOUDFLARE_MODULE_VERSION = '2.5.0';
19
20
 
20
21
  /**
21
22
  * Timeout constants for various operations (in milliseconds)
@@ -67,6 +68,7 @@ const ERROR_TYPES = {
67
68
  ELEMENT_NOT_FOUND: 'element_not_found',
68
69
  EVALUATION_FAILED: 'evaluation_failed',
69
70
  NAVIGATION_FAILED: 'navigation_failed',
71
+ DETACHED_FRAME: 'detached_frame',
70
72
  UNKNOWN: 'unknown'
71
73
  };
72
74
 
@@ -118,7 +120,7 @@ const RETRY_CONFIG = {
118
120
  baseDelay: 1000,
119
121
  maxDelay: 8000,
120
122
  backoffMultiplier: 2,
121
- retryableErrors: [ERROR_TYPES.NETWORK, ERROR_TYPES.TIMEOUT, ERROR_TYPES.ELEMENT_NOT_FOUND]
123
+ retryableErrors: [ERROR_TYPES.NETWORK, ERROR_TYPES.TIMEOUT, ERROR_TYPES.ELEMENT_NOT_FOUND, ERROR_TYPES.DETACHED_FRAME]
122
124
  };
123
125
 
124
126
  /**
@@ -260,6 +262,10 @@ async function waitForTimeout(page, timeout) {
260
262
  */
261
263
  function categorizeError(error) {
262
264
  const errorMessage = error.message || '';
265
+
266
+ if (errorMessage.includes('detached Frame') || errorMessage.includes('Attempted to use detached')) {
267
+ return ERROR_TYPES.DETACHED_FRAME;
268
+ }
263
269
 
264
270
  if (errorMessage.includes('timeout') || errorMessage.includes('Timeout')) {
265
271
  return ERROR_TYPES.TIMEOUT;
@@ -297,6 +303,17 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
297
303
 
298
304
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
299
305
  try {
306
+ // Validate page/frame state before evaluation
307
+ if (page.isClosed()) {
308
+ throw new Error('Page is closed');
309
+ }
310
+
311
+ // Check if main frame is still attached
312
+ const mainFrame = page.mainFrame();
313
+ if (mainFrame.isDetached()) {
314
+ throw new Error('Main frame is detached');
315
+ }
316
+
300
317
  const result = await Promise.race([
301
318
  page.evaluate(func),
302
319
  new Promise((_, reject) =>
@@ -316,6 +333,16 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
316
333
  if (forceDebug) {
317
334
  console.warn(formatLogMessage('cloudflare', `Page evaluation failed (attempt ${attempt}/${maxRetries}): ${error.message} [${errorType}]`));
318
335
  }
336
+
337
+ // Handle detached frame errors specifically
338
+ if (errorType === ERROR_TYPES.DETACHED_FRAME) {
339
+ if (forceDebug) {
340
+ console.warn(formatLogMessage('cloudflare', `Detached frame detected on attempt ${attempt}/${maxRetries} - using longer delay`));
341
+ }
342
+ // For detached frames, wait longer and don't retry as aggressively
343
+ await new Promise(resolve => setTimeout(resolve, 2000)); // Longer delay
344
+ continue;
345
+ }
319
346
 
320
347
  // Don't retry if error type is not retryable or if it's the last attempt
321
348
  if (!RETRY_CONFIG.retryableErrors.includes(errorType) || attempt === maxRetries) {
@@ -336,6 +363,20 @@ async function safePageEvaluate(page, func, timeout = TIMEOUTS.PAGE_EVALUATION_S
336
363
  }
337
364
  }
338
365
 
366
+ // If all retries failed due to detached frames, return safe defaults
367
+ if (lastError?.message.includes('detached Frame') || lastError?.message.includes('Attempted to use detached')) {
368
+ return {
369
+ isChallengePresent: false,
370
+ isPhishingWarning: false,
371
+ isTurnstile: false,
372
+ isJSChallenge: false,
373
+ isChallengeCompleted: false,
374
+ error: 'Frame detached - skipping evaluation',
375
+ errorType: ERROR_TYPES.DETACHED_FRAME,
376
+ attempts: maxRetries
377
+ };
378
+ }
379
+
339
380
  return {
340
381
  isChallengePresent: false,
341
382
  isPhishingWarning: false,
@@ -1209,7 +1250,6 @@ async function handleTurnstileChallenge(page, forceDebug = false) {
1209
1250
 
1210
1251
  const checkboxSelectors = [
1211
1252
  'input[type="checkbox"].ctp-checkbox',
1212
- 'input[type="checkbox"]',
1213
1253
  '.ctp-checkbox-label',
1214
1254
  '.ctp-checkbox'
1215
1255
  ];
package/lib/output.js CHANGED
@@ -80,7 +80,7 @@ function extractDomainFromRule(rule) {
80
80
  } else if (rule.startsWith('{ +block } .')) {
81
81
  // Privoxy format: { +block } .domain.com
82
82
  return rule.substring(12);
83
- } else if (rule.match(/^\(\^\|\\?\.\)/)) {
83
+ } else if (rule.match(/^\(\^\|\\\.\)/)) {
84
84
  // Pi-hole regex format: (^|\.)domain\.com$
85
85
  return rule.replace(/^\(\^\|\\?\.\)/, '').replace(/\\\./g, '.').replace(/\$$/, '');
86
86
  }
@@ -660,4 +660,4 @@ module.exports = {
660
660
  mapResourceTypeToAdblockModifier,
661
661
  matchesIgnoreDomain,
662
662
  extractDomainFromRule
663
- };
663
+ };
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v1.0.99 ===
1
+ // === Network scanner script (nwss.js) v2.0.2 ===
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 = '1.0.99'; // Script version
130
+ const VERSION = '2.0.2'; // 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": "1.0.99",
3
+ "version": "2.0.2",
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": {
@@ -13,7 +13,7 @@
13
13
  "lru-cache": "^10.4.3",
14
14
  "p-limit": "^4.0.0",
15
15
  "psl": "^1.15.0",
16
- "puppeteer": ">=20.0.0 <23.0.0"
16
+ "puppeteer": ">=20.0.0"
17
17
  },
18
18
  "overrides": {
19
19
  "tar-fs": "3.1.0",