@fanboynz/network-scanner 2.0.25 → 2.0.26

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 CHANGED
@@ -223,7 +223,7 @@ When a page redirects to a new domain, first-party/third-party detection is base
223
223
  | `whois_timeout_multiplier` | Number | `1.5` | Timeout increase multiplier per retry |
224
224
  | `whois_use_fallback` | Boolean | `true` | Add TLD-specific fallback servers |
225
225
  | `whois_retry_on_timeout` | Boolean | `true` | Retry on timeout errors |
226
- | `whois_retry_on_error` | Boolean | `false` | Retry on connection/other errors |
226
+ | `whois_retry_on_error` | Boolean | `true` | Retry on connection/other errors |
227
227
  | `dig` | Array | - | Check dig output for ALL specified terms (AND logic) |
228
228
  | `dig-or` | Array | - | Check dig output for ANY specified term (OR logic) |
229
229
  | `dig_subdomain` | Boolean | `false` | Use subdomain for dig lookup instead of root domain |
@@ -59,7 +59,7 @@ const PRECOMPILED_MOCKS = Object.freeze({
59
59
  postMessage: () => {},
60
60
  disconnect: () => {}
61
61
  }),
62
- getManifest: () => Object.freeze({ name: "Chrome", version: "140.0.0.0" }),
62
+ getManifest: () => Object.freeze({ name: "Chrome", version: "141.0.0.0" }),
63
63
  getURL: (path) => `chrome-extension://invalid/${path}`,
64
64
  id: undefined
65
65
  }),
@@ -91,9 +91,9 @@ const BUILT_IN_PROPERTIES = new Set([
91
91
  // User agent collections with latest versions
92
92
  const USER_AGENT_COLLECTIONS = {
93
93
  chrome: [
94
- "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
95
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
96
- "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36"
94
+ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
95
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36",
96
+ "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"
97
97
  ],
98
98
  firefox: [
99
99
  "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:143.0) Gecko/20100101 Firefox/143.0",
@@ -535,7 +535,7 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
535
535
  onMessage: { addListener: () => {}, removeListener: () => {} },
536
536
  sendMessage: () => {},
537
537
  connect: () => ({ onMessage: { addListener: () => {}, removeListener: () => {} }, postMessage: () => {}, disconnect: () => {} }),
538
- getManifest: () => ({ name: "Chrome", version: "140.0.0.0" }),
538
+ getManifest: () => ({ name: "Chrome", version: "141.0.0.0" }),
539
539
  getURL: (path) => `chrome-extension://invalid/${path}`,
540
540
  id: undefined
541
541
  },
package/nwss.js CHANGED
@@ -1,4 +1,4 @@
1
- // === Network scanner script (nwss.js) v2.0.25 ===
1
+ // === Network scanner script (nwss.js) v2.0.26 ===
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
@@ -56,7 +56,7 @@ function fastTimeout(ms) {
56
56
  }
57
57
 
58
58
  // --- Configuration Constants ---
59
- const TIMEOUTS = {
59
+ const TIMEOUTS = Object.freeze({
60
60
  DEFAULT_PAGE: 35000, // Standard page load timeout (35s)
61
61
  DEFAULT_NAVIGATION: 25000, // Navigation operation timeout
62
62
  DEFAULT_NAVIGATION_REDUCED: 20000, // Reduced timeout for faster failures
@@ -71,21 +71,32 @@ const TIMEOUTS = {
71
71
  CURL_HANDLER_DELAY: 3000, // Wait for async curl operations
72
72
  PROTOCOL_TIMEOUT: 180000, // Chrome DevTools Protocol timeout
73
73
  REDIRECT_JS_TIMEOUT: 5000 // JavaScript redirect detection timeout
74
- };
74
+ });
75
75
 
76
- const CACHE_LIMITS = {
76
+ const CACHE_LIMITS = Object.freeze({
77
77
  DISK_CACHE_SIZE: 52428800, // 50MB
78
78
  MEDIA_CACHE_SIZE: 52428800, // 50MB
79
79
  DEFAULT_CACHE_PATH: '.cache',
80
80
  DEFAULT_MAX_SIZE: 5000
81
- };
81
+ });
82
82
 
83
- const CONCURRENCY_LIMITS = {
83
+ const CONCURRENCY_LIMITS = Object.freeze({
84
84
  MIN: 1,
85
85
  MAX: 50,
86
86
  DEFAULT: 6,
87
87
  HIGH_CONCURRENCY_THRESHOLD: 12 // Auto-enable aggressive caching above this
88
- };
88
+ });
89
+
90
+ // V8 Optimization: Use Map for user agent lookups instead of object
91
+ const USER_AGENTS = Object.freeze(new Map([
92
+ ['chrome', "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
93
+ ['chrome_mac', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
94
+ ['chrome_linux', "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36"],
95
+ ['firefox', "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/143.0"],
96
+ ['firefox_mac', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/143.0"],
97
+ ['firefox_linux', "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/143.0"],
98
+ ['safari', "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15"]
99
+ ]));
89
100
 
90
101
  const REALTIME_CLEANUP_THRESHOLD = 8; // Default pages to keep for realtime cleanup
91
102
 
@@ -132,7 +143,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
132
143
  const { monitorBrowserHealth, isBrowserHealthy, isQuicklyResponsive, performGroupWindowCleanup, performRealtimeWindowCleanup, trackPageForRealtime, updatePageUsage, cleanupPageBeforeReload } = require('./lib/browserhealth');
133
144
 
134
145
  // --- Script Configuration & Constants ---
135
- const VERSION = '2.0.25'; // Script version
146
+ const VERSION = '2.0.26'; // Script version
136
147
 
137
148
  // get startTime
138
149
  const startTime = Date.now();
@@ -1211,6 +1222,9 @@ function setupFrameHandling(page, forceDebug) {
1211
1222
  '/usr/bin/chromium',
1212
1223
  '/snap/bin/chromium'
1213
1224
  ];
1225
+ // V8 Optimization: Freeze the Chrome paths array since it's constant
1226
+ Object.freeze(systemChromePaths);
1227
+
1214
1228
 
1215
1229
  let executablePath = null;
1216
1230
  for (const chromePath of systemChromePaths) {
@@ -1387,12 +1401,28 @@ function setupFrameHandling(page, forceDebug) {
1387
1401
  * @returns {Promise<object>} A promise that resolves to an object containing scan results.
1388
1402
  */
1389
1403
  async function processUrl(currentUrl, siteConfig, browserInstance) {
1390
- const allowFirstParty = siteConfig.firstParty === true || siteConfig.firstParty === 1;
1391
- const allowThirdParty = siteConfig.thirdParty === undefined || siteConfig.thirdParty === true || siteConfig.thirdParty === 1;
1392
- const perSiteSubDomains = siteConfig.subDomains === 1 ? true : subDomainsMode;
1393
- const siteLocalhostIP = siteConfig.localhost || null;
1394
- const cloudflarePhishBypass = siteConfig.cloudflare_phish === true;
1395
- const cloudflareBypass = siteConfig.cloudflare_bypass === true;
1404
+ // V8 Optimization: Single destructuring to avoid multiple property lookups
1405
+ const {
1406
+ firstParty,
1407
+ thirdParty,
1408
+ subDomains,
1409
+ localhost,
1410
+ cloudflare_phish,
1411
+ cloudflare_bypass,
1412
+ flowproxy_detection,
1413
+ privoxy,
1414
+ pihole,
1415
+ even_blocked,
1416
+ comments,
1417
+ bypass_cache
1418
+ } = siteConfig;
1419
+
1420
+ const allowFirstParty = firstParty === true || firstParty === 1;
1421
+ const allowThirdParty = thirdParty === undefined || thirdParty === true || thirdParty === 1;
1422
+ const perSiteSubDomains = subDomains === 1 ? true : subDomainsMode;
1423
+ const siteLocalhostIP = localhost || null;
1424
+ const cloudflarePhishBypass = cloudflare_phish === true;
1425
+ const cloudflareBypass = cloudflare_bypass === true;
1396
1426
  // Add redirect and same-page loop protection
1397
1427
  const MAX_REDIRECT_DEPTH = siteConfig.max_redirects || 10;
1398
1428
  const redirectHistory = new Set();
@@ -1401,14 +1431,14 @@ function setupFrameHandling(page, forceDebug) {
1401
1431
  const MAX_SAME_PAGE_LOADS = 3;
1402
1432
  let currentPageUrl = currentUrl;
1403
1433
 
1404
- const sitePrivoxy = siteConfig.privoxy === true;
1405
- const sitePihole = siteConfig.pihole === true;
1406
- const flowproxyDetection = siteConfig.flowproxy_detection === true;
1434
+ const sitePrivoxy = privoxy === true;
1435
+ const sitePihole = pihole === true;
1436
+ const flowproxyDetection = flowproxy_detection === true;
1407
1437
 
1408
- const evenBlocked = siteConfig.even_blocked === true;
1438
+ const evenBlocked = even_blocked === true;
1409
1439
  // Log site-level comments if debug mode is enabled
1410
- if (forceDebug && siteConfig.comments) {
1411
- const siteComments = Array.isArray(siteConfig.comments) ? siteConfig.comments : [siteConfig.comments];
1440
+ if (forceDebug && comments) {
1441
+ const siteComments = Array.isArray(comments) ? comments : [comments];
1412
1442
  console.log(formatLogMessage('debug', `Site comments for ${currentUrl}: ${siteComments.length} item(s)`));
1413
1443
  siteComments.forEach((comment, idx) =>
1414
1444
  console.log(formatLogMessage('debug', ` Site comment ${idx + 1}: ${comment}`))
@@ -1416,11 +1446,11 @@ function setupFrameHandling(page, forceDebug) {
1416
1446
  }
1417
1447
 
1418
1448
  // Log bypass_cache setting if enabled
1419
- if (forceDebug && siteConfig.bypass_cache === true) {
1449
+ if (forceDebug && bypass_cache === true) {
1420
1450
  console.log(formatLogMessage('debug', `Cache bypass enabled for all URLs in site: ${currentUrl}`));
1421
1451
  }
1422
1452
 
1423
- if (siteConfig.firstParty === 0 && siteConfig.thirdParty === 0) {
1453
+ if (firstParty === 0 && thirdParty === 0) {
1424
1454
  console.warn(`⚠ Skipping ${currentUrl} because both firstParty and thirdParty are disabled.`);
1425
1455
  return { url: currentUrl, rules: [], success: false, skipped: true };
1426
1456
  }
@@ -1475,14 +1505,14 @@ function setupFrameHandling(page, forceDebug) {
1475
1505
  let finalUrlAfterRedirect = null;
1476
1506
 
1477
1507
  // Enhanced error types for Puppeteer 23.x compatibility
1478
- const CRITICAL_BROWSER_ERRORS = [
1508
+ const CRITICAL_BROWSER_ERRORS = Object.freeze([
1479
1509
  'Protocol error',
1480
1510
  'Target closed',
1481
1511
  'Browser has been closed',
1482
1512
  'Browser protocol broken',
1483
1513
  'Browser process exited',
1484
1514
  'Browser disconnected'
1485
- ];
1515
+ ]);
1486
1516
 
1487
1517
  try {
1488
1518
 
@@ -1907,29 +1937,30 @@ function setupFrameHandling(page, forceDebug) {
1907
1937
 
1908
1938
  // Client Hints protection for Chrome user agents
1909
1939
  if (siteConfig.userAgent && siteConfig.userAgent.toLowerCase().includes('chrome')) {
1940
+ const userAgentKey = siteConfig.userAgent.toLowerCase();
1910
1941
  let platform = 'Windows';
1911
1942
  let platformVersion = '15.0.0';
1912
1943
  let arch = 'x86';
1913
1944
 
1914
- if (siteConfig.userAgent.toLowerCase() === 'chrome_mac') {
1945
+ if (userAgentKey === 'chrome_mac') {
1915
1946
  platform = 'macOS';
1916
- platformVersion = '13.5.0';
1947
+ platformVersion = '13.5.0';
1917
1948
  arch = 'arm';
1918
- } else if (siteConfig.userAgent.toLowerCase() === 'chrome_linux') {
1949
+ } else if (userAgentKey === 'chrome_linux') {
1919
1950
  platform = 'Linux';
1920
1951
  platformVersion = '6.5.0';
1921
1952
  arch = 'x86';
1922
1953
  }
1923
-
1954
+
1924
1955
  await page.setExtraHTTPHeaders({
1925
- 'Sec-CH-UA': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="140"',
1956
+ 'Sec-CH-UA': '"Chromium";v="141", "Not=A?Brand";v="24", "Google Chrome";v="141"',
1926
1957
  'Sec-CH-UA-Platform': `"${platform}"`,
1927
1958
  'Sec-CH-UA-Platform-Version': `"${platformVersion}"`,
1928
1959
  'Sec-CH-UA-Mobile': '?0',
1929
1960
  'Sec-CH-UA-Arch': `"${arch}"`,
1930
1961
  'Sec-CH-UA-Bitness': '"64"',
1931
- 'Sec-CH-UA-Full-Version': '"140.0.7339.208"',
1932
- 'Sec-CH-UA-Full-Version-List': '"Chromium";v="140.0.7339.208", "Not=A?Brand";v="24.0.0.0", "Google Chrome";v="140.0.7339.208"'
1962
+ 'Sec-CH-UA-Full-Version': '"141.0.7390.55"',
1963
+ 'Sec-CH-UA-Full-Version-List': '"Chromium";v="141.0.7390.55", "Not=A?Brand";v="24.0.0.0", "Google Chrome";v="141.0.7390.55"'
1933
1964
  });
1934
1965
  }
1935
1966
  } catch (fingerprintErr) {
@@ -1959,16 +1990,7 @@ function setupFrameHandling(page, forceDebug) {
1959
1990
  // Get user agent for curl if needed
1960
1991
  let curlUserAgent = '';
1961
1992
  if (useCurl && siteConfig.userAgent) {
1962
- const userAgents = {
1963
- chrome: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
1964
- chrome_mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
1965
- chrome_linux: "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/140.0.0.0 Safari/537.36",
1966
- firefox: "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:142.0) Gecko/20100101 Firefox/143.0",
1967
- firefox_mac: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/143.0",
1968
- firefox_linux: "Mozilla/5.0 (X11; Linux x86_64; rv:142.0) Gecko/20100101 Firefox/143.0",
1969
- safari: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.6 Safari/605.1.15"
1970
- };
1971
- curlUserAgent = userAgents[siteConfig.userAgent.toLowerCase()] || '';
1993
+ curlUserAgent = USER_AGENTS.get(siteConfig.userAgent.toLowerCase()) || '';
1972
1994
  }
1973
1995
 
1974
1996
  if (useCurl && forceDebug) {
@@ -3487,20 +3509,29 @@ function setupFrameHandling(page, forceDebug) {
3487
3509
  // Temporarily store the pLimit function
3488
3510
  const originalLimit = limit;
3489
3511
 
3490
- // Create a flat list of all URL tasks with their site configs for true concurrency
3491
- const allTasks = [];
3512
+ // V8 Optimization: Calculate total URLs first to pre-allocate array
3513
+ let totalUrls = 0;
3492
3514
  for (const site of sites) {
3493
3515
  const urlsToProcess = Array.isArray(site.url) ? site.url : [site.url];
3494
- urlsToProcess.forEach(url => {
3495
- allTasks.push({
3516
+ totalUrls += urlsToProcess.length;
3517
+ }
3518
+
3519
+ // Pre-allocate array with exact size to prevent multiple reallocations
3520
+ const allTasks = new Array(totalUrls);
3521
+ let taskIndex = 0;
3522
+
3523
+ // Populate the pre-allocated array
3524
+ for (const site of sites) {
3525
+ const urlsToProcess = Array.isArray(site.url) ? site.url : [site.url];
3526
+ for (const url of urlsToProcess) {
3527
+ allTasks[taskIndex++] = {
3496
3528
  url,
3497
3529
  config: { ...site, _originalUrl: url }, // Preserve original URL for CDP domain checking
3498
- taskId: allTasks.length // For tracking
3499
- });
3500
- });
3530
+ taskId: taskIndex - 1 // For tracking
3531
+ };
3532
+ }
3501
3533
  }
3502
-
3503
- const totalUrls = allTasks.length;
3534
+
3504
3535
 
3505
3536
  let results = [];
3506
3537
  let processedUrlCount = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fanboynz/network-scanner",
3
- "version": "2.0.25",
3
+ "version": "2.0.26",
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": {