@fanboynz/network-scanner 1.0.67 → 1.0.69
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/post-processing.js +607 -0
- package/nwss.js +144 -51
- package/package.json +1 -1
- package/regex-tool/index.html +713 -0
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v1.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v1.0.69 ===
|
|
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
|
|
@@ -27,6 +27,8 @@ const { createNetToolsHandler, createEnhancedDryRunCallback, validateWhoisAvaila
|
|
|
27
27
|
const { loadComparisonRules, filterUniqueRules } = require('./lib/compare');
|
|
28
28
|
// CDP functionality
|
|
29
29
|
const { createCDPSession } = require('./lib/cdp');
|
|
30
|
+
// Post-processing cleanup
|
|
31
|
+
const { processResults } = require('./lib/post-processing');
|
|
30
32
|
// Colorize various text when used
|
|
31
33
|
const { colorize, colors, messageColors, tags, formatLogMessage } = require('./lib/colorize');
|
|
32
34
|
// Enhanced mouse interaction and page simulation
|
|
@@ -42,6 +44,37 @@ function fastTimeout(ms) {
|
|
|
42
44
|
return new Promise(resolve => setTimeout(resolve, ms));
|
|
43
45
|
}
|
|
44
46
|
|
|
47
|
+
// --- Configuration Constants ---
|
|
48
|
+
const TIMEOUTS = {
|
|
49
|
+
DEFAULT_PAGE: 30000,
|
|
50
|
+
DEFAULT_NAVIGATION: 25000,
|
|
51
|
+
DEFAULT_NAVIGATION_REDUCED: 20000, // Reduced timeout for faster failures
|
|
52
|
+
DEFAULT_PAGE_REDUCED: 15000, // Reduced page timeout
|
|
53
|
+
FRAME_LOAD_WAIT: 2000,
|
|
54
|
+
NETWORK_IDLE: 2000,
|
|
55
|
+
NETWORK_IDLE_MAX: 10000,
|
|
56
|
+
FAST_SITE_THRESHOLD: 15000,
|
|
57
|
+
EMERGENCY_RESTART_DELAY: 2000,
|
|
58
|
+
BROWSER_STABILIZE_DELAY: 1000,
|
|
59
|
+
CURL_HANDLER_DELAY: 3000,
|
|
60
|
+
PROTOCOL_TIMEOUT: 60000,
|
|
61
|
+
REDIRECT_JS_TIMEOUT: 5000
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
const CACHE_LIMITS = {
|
|
65
|
+
DISK_CACHE_SIZE: 52428800, // 50MB
|
|
66
|
+
MEDIA_CACHE_SIZE: 52428800, // 50MB
|
|
67
|
+
DEFAULT_CACHE_PATH: '.cache',
|
|
68
|
+
DEFAULT_MAX_SIZE: 5000
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const CONCURRENCY_LIMITS = {
|
|
72
|
+
MIN: 1,
|
|
73
|
+
MAX: 50,
|
|
74
|
+
DEFAULT: 6,
|
|
75
|
+
HIGH_CONCURRENCY_THRESHOLD: 12 // Auto-enable aggressive caching above this
|
|
76
|
+
};
|
|
77
|
+
|
|
45
78
|
/**
|
|
46
79
|
* Detects the installed Puppeteer version dynamically
|
|
47
80
|
* @returns {Object} Version info and compatibility settings
|
|
@@ -85,7 +118,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
85
118
|
const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
|
|
86
119
|
|
|
87
120
|
// --- Script Configuration & Constants ---
|
|
88
|
-
const VERSION = '1.0.
|
|
121
|
+
const VERSION = '1.0.69'; // Script version
|
|
89
122
|
|
|
90
123
|
// get startTime
|
|
91
124
|
const startTime = Date.now();
|
|
@@ -276,7 +309,7 @@ if (clearCache && !dryRunMode) {
|
|
|
276
309
|
clearPersistentCache({
|
|
277
310
|
silent: silentMode,
|
|
278
311
|
forceDebug,
|
|
279
|
-
cachePath:
|
|
312
|
+
cachePath: CACHE_LIMITS.DEFAULT_CACHE_PATH // Default path, will be updated after config loads if needed
|
|
280
313
|
});
|
|
281
314
|
}
|
|
282
315
|
|
|
@@ -566,24 +599,24 @@ const {
|
|
|
566
599
|
const MAX_CONCURRENT_SITES = (() => {
|
|
567
600
|
// Check command line argument first
|
|
568
601
|
if (maxConcurrentSites !== null) {
|
|
569
|
-
if (maxConcurrentSites
|
|
602
|
+
if (maxConcurrentSites >= CONCURRENCY_LIMITS.MIN && maxConcurrentSites <= CONCURRENCY_LIMITS.MAX) {
|
|
570
603
|
if (forceDebug) console.log(formatLogMessage('debug', `Using command line max_concurrent_sites: ${maxConcurrentSites}`));
|
|
571
604
|
return maxConcurrentSites;
|
|
572
605
|
} else {
|
|
573
|
-
console.warn(`⚠ Invalid --max-concurrent value: ${maxConcurrentSites}. Must be
|
|
606
|
+
console.warn(`⚠ Invalid --max-concurrent value: ${maxConcurrentSites}. Must be ${CONCURRENCY_LIMITS.MIN}-${CONCURRENCY_LIMITS.MAX}. Using config/default value.`);
|
|
574
607
|
}
|
|
575
608
|
}
|
|
576
609
|
|
|
577
610
|
// Check config.json value
|
|
578
|
-
if (typeof max_concurrent_sites === 'number' && max_concurrent_sites
|
|
611
|
+
if (typeof max_concurrent_sites === 'number' && max_concurrent_sites >= CONCURRENCY_LIMITS.MIN && max_concurrent_sites <= CONCURRENCY_LIMITS.MAX) {
|
|
579
612
|
if (forceDebug) console.log(formatLogMessage('debug', `Using config max_concurrent_sites: ${max_concurrent_sites}`));
|
|
580
613
|
return max_concurrent_sites;
|
|
581
|
-
} else if (max_concurrent_sites !==
|
|
582
|
-
console.warn(`⚠ Invalid config max_concurrent_sites value: ${max_concurrent_sites}. Using default:
|
|
614
|
+
} else if (max_concurrent_sites !== CONCURRENCY_LIMITS.DEFAULT) {
|
|
615
|
+
console.warn(`⚠ Invalid config max_concurrent_sites value: ${max_concurrent_sites}. Using default: ${CONCURRENCY_LIMITS.DEFAULT}`);
|
|
583
616
|
}
|
|
584
617
|
|
|
585
618
|
// Use default
|
|
586
|
-
return
|
|
619
|
+
return CONCURRENCY_LIMITS.DEFAULT;
|
|
587
620
|
})();
|
|
588
621
|
|
|
589
622
|
const RESOURCE_CLEANUP_INTERVAL = (() => {
|
|
@@ -619,7 +652,7 @@ if (clearCache && dryRunMode) {
|
|
|
619
652
|
}
|
|
620
653
|
|
|
621
654
|
// Also clear for custom cache paths in normal mode if not already cleared
|
|
622
|
-
if (clearCache && !dryRunMode && config.cache_path && config.cache_path !==
|
|
655
|
+
if (clearCache && !dryRunMode && config.cache_path && config.cache_path !== CACHE_LIMITS.DEFAULT_CACHE_PATH) {
|
|
623
656
|
clearPersistentCache({
|
|
624
657
|
silent: silentMode,
|
|
625
658
|
forceDebug,
|
|
@@ -636,11 +669,11 @@ smartCache = createSmartCache({
|
|
|
636
669
|
...config,
|
|
637
670
|
forceDebug,
|
|
638
671
|
max_concurrent_sites: MAX_CONCURRENT_SITES, // Pass concurrency info
|
|
639
|
-
cache_aggressive_mode: MAX_CONCURRENT_SITES >
|
|
672
|
+
cache_aggressive_mode: MAX_CONCURRENT_SITES > CONCURRENCY_LIMITS.HIGH_CONCURRENCY_THRESHOLD, // Auto-enable for high concurrency
|
|
640
673
|
cache_persistence: false, // Disable persistence completely
|
|
641
674
|
cache_autosave: false, // Disable auto-save completely
|
|
642
675
|
cache_autosave_minutes: config.cache_autosave_minutes || 1,
|
|
643
|
-
cache_max_size: config.cache_max_size ||
|
|
676
|
+
cache_max_size: config.cache_max_size || CACHE_LIMITS.DEFAULT_MAX_SIZE
|
|
644
677
|
});
|
|
645
678
|
}
|
|
646
679
|
|
|
@@ -936,6 +969,22 @@ function outputDryRunResults(url, matchedItems, netToolsResults, pageTitle) {
|
|
|
936
969
|
}
|
|
937
970
|
}
|
|
938
971
|
|
|
972
|
+
/**
|
|
973
|
+
* Helper function to check if a URL should be processed (valid HTTP/HTTPS)
|
|
974
|
+
* @param {string} url - URL to validate
|
|
975
|
+
* @param {boolean} forceDebug - Debug logging flag
|
|
976
|
+
* @returns {boolean} True if URL is valid for processing
|
|
977
|
+
*/
|
|
978
|
+
function shouldProcessUrl(url, forceDebug) {
|
|
979
|
+
try {
|
|
980
|
+
const parsed = new URL(url);
|
|
981
|
+
return parsed.protocol === 'http:' || parsed.protocol === 'https:';
|
|
982
|
+
} catch (err) {
|
|
983
|
+
if (forceDebug) console.log(formatLogMessage('debug', `Invalid URL for processing: ${url}`));
|
|
984
|
+
return false;
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
|
|
939
988
|
// ability to use widcards in ignoreDomains
|
|
940
989
|
function matchesIgnoreDomain(domain, ignorePatterns) {
|
|
941
990
|
return ignorePatterns.some(pattern => {
|
|
@@ -1124,8 +1173,8 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1124
1173
|
args: [
|
|
1125
1174
|
// Disk space controls - 50MB cache limits
|
|
1126
1175
|
'--disable-features=VizDisplayCompositor',
|
|
1127
|
-
|
|
1128
|
-
|
|
1176
|
+
`--disk-cache-size=${CACHE_LIMITS.DISK_CACHE_SIZE}`, // 50MB disk cache
|
|
1177
|
+
`--media-cache-size=${CACHE_LIMITS.MEDIA_CACHE_SIZE}`, // 50MB media cache
|
|
1129
1178
|
'--disable-application-cache',
|
|
1130
1179
|
'--disable-offline-load-stale-cache',
|
|
1131
1180
|
'--disable-background-downloads',
|
|
@@ -1170,7 +1219,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1170
1219
|
'--no-zygote', // Better process isolation
|
|
1171
1220
|
],
|
|
1172
1221
|
// Optimized timeouts for Puppeteer 23.x performance
|
|
1173
|
-
protocolTimeout:
|
|
1222
|
+
protocolTimeout: TIMEOUTS.PROTOCOL_TIMEOUT,
|
|
1174
1223
|
slowMo: 0, // No artificial delays
|
|
1175
1224
|
defaultViewport: null, // Use system default viewport
|
|
1176
1225
|
ignoreDefaultArgs: ['--enable-automation'] // Avoid automation detection
|
|
@@ -1318,15 +1367,23 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1318
1367
|
matchedDomains.set('dryRunNetTools', []);
|
|
1319
1368
|
matchedDomains.set('dryRunSearchString', new Map()); // Map URL to search results
|
|
1320
1369
|
}
|
|
1321
|
-
const timeout = siteConfig.timeout ||
|
|
1370
|
+
const timeout = siteConfig.timeout || TIMEOUTS.DEFAULT_PAGE;
|
|
1322
1371
|
|
|
1323
1372
|
if (!silentMode) console.log(`\n${messageColors.scanning('Scanning:')} ${currentUrl}`);
|
|
1324
1373
|
|
|
1374
|
+
// Track ALL domains that should be considered first-party (original + redirects)
|
|
1375
|
+
const firstPartyDomains = new Set();
|
|
1376
|
+
const originalRootDomain = safeGetDomain(currentUrl, false);
|
|
1377
|
+
if (originalRootDomain) {
|
|
1378
|
+
firstPartyDomains.add(originalRootDomain);
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1325
1381
|
// Track redirect domains to exclude from matching
|
|
1326
1382
|
let redirectDomainsToExclude = [];
|
|
1327
1383
|
|
|
1328
|
-
// Track the effective current URL for first-party detection (updates after redirects)
|
|
1384
|
+
// Track the effective current URL and final URL for first-party detection (updates after redirects)
|
|
1329
1385
|
let effectiveCurrentUrl = currentUrl;
|
|
1386
|
+
let finalUrlAfterRedirect = null;
|
|
1330
1387
|
|
|
1331
1388
|
// Enhanced error types for Puppeteer 23.x compatibility
|
|
1332
1389
|
const CRITICAL_BROWSER_ERRORS = [
|
|
@@ -1367,8 +1424,8 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1367
1424
|
|
|
1368
1425
|
// Set aggressive timeouts for problematic operations
|
|
1369
1426
|
// Optimized timeouts for Puppeteer 23.x responsiveness
|
|
1370
|
-
page.setDefaultTimeout(Math.min(timeout,
|
|
1371
|
-
page.setDefaultNavigationTimeout(Math.min(timeout,
|
|
1427
|
+
page.setDefaultTimeout(Math.min(timeout, TIMEOUTS.DEFAULT_PAGE_REDUCED));
|
|
1428
|
+
page.setDefaultNavigationTimeout(Math.min(timeout, TIMEOUTS.DEFAULT_NAVIGATION));
|
|
1372
1429
|
// Aggressive timeouts prevent hanging in Puppeteer 23.x while maintaining speed
|
|
1373
1430
|
|
|
1374
1431
|
page.on('console', (msg) => {
|
|
@@ -1435,8 +1492,8 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1435
1492
|
// Apply flowProxy timeouts if detection is enabled
|
|
1436
1493
|
if (flowproxyDetection) {
|
|
1437
1494
|
const flowproxyTimeouts = getFlowProxyTimeouts(siteConfig);
|
|
1438
|
-
page.setDefaultTimeout(Math.min(flowproxyTimeouts.pageTimeout,
|
|
1439
|
-
page.setDefaultNavigationTimeout(Math.min(flowproxyTimeouts.navigationTimeout,
|
|
1495
|
+
page.setDefaultTimeout(Math.min(flowproxyTimeouts.pageTimeout, TIMEOUTS.DEFAULT_NAVIGATION));
|
|
1496
|
+
page.setDefaultNavigationTimeout(Math.min(flowproxyTimeouts.navigationTimeout, TIMEOUTS.DEFAULT_PAGE));
|
|
1440
1497
|
if (forceDebug) {
|
|
1441
1498
|
console.log(formatLogMessage('debug', `Applied flowProxy timeouts - page: ${flowproxyTimeouts.pageTimeout}ms, nav: ${flowproxyTimeouts.navigationTimeout}ms`));
|
|
1442
1499
|
}
|
|
@@ -1838,13 +1895,9 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1838
1895
|
const checkedUrl = request.url();
|
|
1839
1896
|
const checkedHostname = safeGetDomain(checkedUrl, true);
|
|
1840
1897
|
const checkedRootDomain = safeGetDomain(checkedUrl, false); // Root domain for first-party detection
|
|
1841
|
-
//
|
|
1842
|
-
// This
|
|
1843
|
-
const
|
|
1844
|
-
const effectiveCurrentRootDomain = safeGetDomain(effectiveCurrentUrl, false); // Root domain for comparison
|
|
1845
|
-
|
|
1846
|
-
// FIXED: Compare root domains instead of full hostnames for first-party detection
|
|
1847
|
-
const isFirstParty = checkedRootDomain && effectiveCurrentRootDomain && checkedRootDomain === effectiveCurrentRootDomain;
|
|
1898
|
+
// Check against ALL first-party domains (original + all redirects)
|
|
1899
|
+
// This prevents redirect destinations from being marked as third-party
|
|
1900
|
+
const isFirstParty = checkedRootDomain && firstPartyDomains.has(checkedRootDomain);
|
|
1848
1901
|
|
|
1849
1902
|
// Block infinite iframe loops
|
|
1850
1903
|
const frameUrl = request.frame() ? request.frame().url() : '';
|
|
@@ -2000,14 +2053,6 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2000
2053
|
}
|
|
2001
2054
|
break; // Skip this URL - it's third-party but thirdParty is disabled
|
|
2002
2055
|
}
|
|
2003
|
-
|
|
2004
|
-
// Check ignoreDomains AFTER regex match but BEFORE domain processing
|
|
2005
|
-
if (matchesIgnoreDomain(fullSubdomain, ignoreDomains)) {
|
|
2006
|
-
if (forceDebug) {
|
|
2007
|
-
console.log(formatLogMessage('debug', `Ignoring domain ${fullSubdomain} (matches ignoreDomains pattern)`));
|
|
2008
|
-
}
|
|
2009
|
-
break; // Skip this URL - domain is in ignore list
|
|
2010
|
-
}
|
|
2011
2056
|
|
|
2012
2057
|
// REMOVED: Check if this URL matches any blocked patterns - if so, skip detection but still continue browser blocking
|
|
2013
2058
|
// This check is no longer needed here since even_blocked handles it above
|
|
@@ -2279,13 +2324,13 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2279
2324
|
// Use explicit Promise-based timeouts instead of page.waitForTimeout()
|
|
2280
2325
|
|
|
2281
2326
|
// Use faster defaults for sites with long timeouts to improve responsiveness
|
|
2282
|
-
const isFastSite = timeout <=
|
|
2327
|
+
const isFastSite = timeout <= TIMEOUTS.FAST_SITE_THRESHOLD;
|
|
2283
2328
|
const defaultWaitUntil = 'domcontentloaded'; // Always use faster option in Puppeteer 23.x
|
|
2284
2329
|
|
|
2285
2330
|
// Enhanced navigation options for Puppeteer 23.x
|
|
2286
2331
|
const defaultGotoOptions = {
|
|
2287
2332
|
waitUntil: defaultWaitUntil,
|
|
2288
|
-
timeout: Math.min(timeout,
|
|
2333
|
+
timeout: Math.min(timeout, TIMEOUTS.DEFAULT_PAGE), // Cap at default page timeout
|
|
2289
2334
|
// Puppeteer 23.x: Fixed referrer header handling
|
|
2290
2335
|
...(siteConfig.referrer_headers && (() => {
|
|
2291
2336
|
const referrerUrl = Array.isArray(siteConfig.referrer_headers)
|
|
@@ -2309,6 +2354,19 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2309
2354
|
if (redirected) {
|
|
2310
2355
|
const originalDomain = safeGetDomain(originalUrl);
|
|
2311
2356
|
const finalDomain = safeGetDomain(finalUrl);
|
|
2357
|
+
|
|
2358
|
+
// Add redirect destination to first-party domains immediately
|
|
2359
|
+
if (finalDomain) {
|
|
2360
|
+
firstPartyDomains.add(finalDomain);
|
|
2361
|
+
}
|
|
2362
|
+
|
|
2363
|
+
// Also add any intermediate redirect domains as first-party
|
|
2364
|
+
if (redirectDomains && redirectDomains.length > 0) {
|
|
2365
|
+
redirectDomains.forEach(domain => {
|
|
2366
|
+
const rootDomain = safeGetDomain(`http://${domain}`, false);
|
|
2367
|
+
if (rootDomain) firstPartyDomains.add(rootDomain);
|
|
2368
|
+
});
|
|
2369
|
+
}
|
|
2312
2370
|
|
|
2313
2371
|
if (originalDomain !== finalDomain) {
|
|
2314
2372
|
if (!silentMode) {
|
|
@@ -2317,6 +2375,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2317
2375
|
|
|
2318
2376
|
if (forceDebug) {
|
|
2319
2377
|
console.log(formatLogMessage('debug', `Full redirect chain: ${redirectChain.join(' → ')}`));
|
|
2378
|
+
console.log(formatLogMessage('debug', `All first-party domains: ${Array.from(firstPartyDomains).join(', ')}`));
|
|
2320
2379
|
}
|
|
2321
2380
|
|
|
2322
2381
|
// VALIDATION: Only update currentUrl if finalUrl is a valid HTTP/HTTPS URL
|
|
@@ -2326,6 +2385,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2326
2385
|
|
|
2327
2386
|
// IMPORTANT: Also update effectiveCurrentUrl for first-party detection
|
|
2328
2387
|
effectiveCurrentUrl = finalUrl;
|
|
2388
|
+
finalUrlAfterRedirect = finalUrl;
|
|
2329
2389
|
|
|
2330
2390
|
// Update the redirect domains to exclude from matching
|
|
2331
2391
|
if (redirectDomains && redirectDomains.length > 0) {
|
|
@@ -2389,7 +2449,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2389
2449
|
if (forceDebug) {
|
|
2390
2450
|
try {
|
|
2391
2451
|
// Use fast timeout helper for compatibility
|
|
2392
|
-
await fastTimeout(
|
|
2452
|
+
await fastTimeout(TIMEOUTS.FRAME_LOAD_WAIT); // Give iframes time to load
|
|
2393
2453
|
const frames = page.frames();
|
|
2394
2454
|
console.log(formatLogMessage('debug', `Total frames found: ${frames.length}`));
|
|
2395
2455
|
frames.forEach((frame, index) => {
|
|
@@ -2433,10 +2493,10 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2433
2493
|
const delayMs = siteConfig.delay || 4000;
|
|
2434
2494
|
|
|
2435
2495
|
// Optimized delays for Puppeteer 23.x performance
|
|
2436
|
-
const isFastSite = timeout <=
|
|
2437
|
-
const networkIdleTime =
|
|
2438
|
-
const networkIdleTimeout = Math.min(timeout / 2,
|
|
2439
|
-
const actualDelay = Math.min(delayMs,
|
|
2496
|
+
const isFastSite = timeout <= TIMEOUTS.FAST_SITE_THRESHOLD;
|
|
2497
|
+
const networkIdleTime = TIMEOUTS.NETWORK_IDLE; // Balanced: 2s for reliable network detection
|
|
2498
|
+
const networkIdleTimeout = Math.min(timeout / 2, TIMEOUTS.NETWORK_IDLE_MAX); // Balanced: 10s timeout
|
|
2499
|
+
const actualDelay = Math.min(delayMs, TIMEOUTS.NETWORK_IDLE); // Balanced: 2s delay for stability
|
|
2440
2500
|
|
|
2441
2501
|
await page.waitForNetworkIdle({
|
|
2442
2502
|
idleTime: networkIdleTime,
|
|
@@ -2521,7 +2581,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2521
2581
|
|
|
2522
2582
|
// Wait a moment for async nettools/searchstring operations to complete
|
|
2523
2583
|
// Use fast timeout helper for Puppeteer 22.x compatibility
|
|
2524
|
-
await fastTimeout(
|
|
2584
|
+
await fastTimeout(TIMEOUTS.CURL_HANDLER_DELAY); // Wait for async operations
|
|
2525
2585
|
|
|
2526
2586
|
outputDryRunResults(currentUrl, enhancedMatches, dryRunNetTools, pageTitle);
|
|
2527
2587
|
|
|
@@ -2541,7 +2601,13 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2541
2601
|
};
|
|
2542
2602
|
const formattedRules = formatRules(matchedDomains, siteConfig, globalOptions);
|
|
2543
2603
|
|
|
2544
|
-
return {
|
|
2604
|
+
return {
|
|
2605
|
+
url: currentUrl,
|
|
2606
|
+
rules: formattedRules,
|
|
2607
|
+
success: true,
|
|
2608
|
+
finalUrl: finalUrlAfterRedirect || currentUrl,
|
|
2609
|
+
redirectDomains: redirectDomainsToExclude
|
|
2610
|
+
};
|
|
2545
2611
|
}
|
|
2546
2612
|
|
|
2547
2613
|
} catch (err) {
|
|
@@ -2577,7 +2643,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2577
2643
|
};
|
|
2578
2644
|
const formattedRules = formatRules(matchedDomains, siteConfig, globalOptions);
|
|
2579
2645
|
if (forceDebug) console.log(formatLogMessage('debug', `Saving ${formattedRules.length} rules despite page load failure`));
|
|
2580
|
-
return {
|
|
2646
|
+
return {
|
|
2647
|
+
url: currentUrl,
|
|
2648
|
+
rules: formattedRules,
|
|
2649
|
+
success: false,
|
|
2650
|
+
hasMatches: true,
|
|
2651
|
+
finalUrl: finalUrlAfterRedirect || currentUrl,
|
|
2652
|
+
redirectDomains: redirectDomainsToExclude
|
|
2653
|
+
};
|
|
2581
2654
|
}
|
|
2582
2655
|
|
|
2583
2656
|
if (siteConfig.screenshot === true && page) {
|
|
@@ -2591,7 +2664,13 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2591
2664
|
console.warn(messageColors.warn(`[screenshot failed] ${currentUrl}: ${screenshotErr.message}`));
|
|
2592
2665
|
}
|
|
2593
2666
|
}
|
|
2594
|
-
return {
|
|
2667
|
+
return {
|
|
2668
|
+
url: currentUrl,
|
|
2669
|
+
rules: [],
|
|
2670
|
+
success: false,
|
|
2671
|
+
finalUrl: finalUrlAfterRedirect || currentUrl,
|
|
2672
|
+
redirectDomains: redirectDomainsToExclude
|
|
2673
|
+
};
|
|
2595
2674
|
} finally {
|
|
2596
2675
|
// Guaranteed resource cleanup - this runs regardless of success or failure
|
|
2597
2676
|
|
|
@@ -2640,7 +2719,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2640
2719
|
}
|
|
2641
2720
|
}
|
|
2642
2721
|
|
|
2643
|
-
|
|
2722
|
+
let results = [];
|
|
2644
2723
|
let processedUrlCount = 0;
|
|
2645
2724
|
let urlsSinceLastCleanup = 0;
|
|
2646
2725
|
|
|
@@ -2719,7 +2798,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2719
2798
|
|
|
2720
2799
|
// Reset cleanup counter and add delay
|
|
2721
2800
|
urlsSinceLastCleanup = 0;
|
|
2722
|
-
await fastTimeout(
|
|
2801
|
+
await fastTimeout(TIMEOUTS.BROWSER_STABILIZE_DELAY);
|
|
2723
2802
|
}
|
|
2724
2803
|
|
|
2725
2804
|
if (forceDebug) {
|
|
@@ -2787,13 +2866,27 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2787
2866
|
}
|
|
2788
2867
|
browser = await createBrowser();
|
|
2789
2868
|
urlsSinceLastCleanup = 0; // Reset counter
|
|
2790
|
-
await fastTimeout(
|
|
2869
|
+
await fastTimeout(TIMEOUTS.EMERGENCY_RESTART_DELAY); // Give browser time to stabilize
|
|
2791
2870
|
} catch (emergencyRestartErr) {
|
|
2792
2871
|
if (forceDebug) console.log(formatLogMessage('debug', `Emergency restart failed: ${emergencyRestartErr.message}`));
|
|
2793
2872
|
}
|
|
2794
2873
|
}
|
|
2795
2874
|
}
|
|
2796
2875
|
|
|
2876
|
+
// === POST-SCAN PROCESSING ===
|
|
2877
|
+
// Clean up first-party domains and validate results
|
|
2878
|
+
if (!dryRunMode) {
|
|
2879
|
+
// Always run post-processing for both firstParty cleanup and ignoreDomains safety net
|
|
2880
|
+
const sitesWithFirstPartyDisabled = sites.filter(site => site.firstParty === false);
|
|
2881
|
+
if (sitesWithFirstPartyDisabled.length > 0) {
|
|
2882
|
+
if (forceDebug) {
|
|
2883
|
+
console.log(formatLogMessage('debug', `Running post-scan processing for ${sitesWithFirstPartyDisabled.length} sites with firstParty: false`));
|
|
2884
|
+
}
|
|
2885
|
+
// Always run post-processing for ignoreDomains safety net
|
|
2886
|
+
results = processResults(results, sites, { forceDebug, silentMode, ignoreDomains });
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
|
|
2797
2890
|
// Handle dry run output file writing
|
|
2798
2891
|
if (dryRunMode && outputFile && dryRunOutput.length > 0) {
|
|
2799
2892
|
try {
|
|
@@ -2951,7 +3044,7 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
2951
3044
|
forceDebug,
|
|
2952
3045
|
comprehensive: true
|
|
2953
3046
|
});
|
|
2954
|
-
await fastTimeout(
|
|
3047
|
+
await fastTimeout(TIMEOUTS.BROWSER_STABILIZE_DELAY); // Give filesystem time to sync
|
|
2955
3048
|
|
|
2956
3049
|
// Calculate timing, success rates, and provide summary information
|
|
2957
3050
|
if (forceDebug) console.log(formatLogMessage('debug', `Calculating timing statistics...`));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.69",
|
|
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": {
|