@fanboynz/network-scanner 1.0.65 → 1.0.67
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/fingerprint.js +149 -12
- package/lib/interaction.js +89 -21
- package/nwss.js +7 -3
- package/package.json +1 -1
package/lib/fingerprint.js
CHANGED
|
@@ -292,7 +292,11 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
292
292
|
/tz check/i,
|
|
293
293
|
/new window\\.Error.*<anonymous>/i,
|
|
294
294
|
/Failed to load resource.*server responded with a status of 40[34]/i,
|
|
295
|
-
/Blocked script execution in 'about:blank'.*sandboxed.*allow-scripts/i
|
|
295
|
+
/Blocked script execution in 'about:blank'.*sandboxed.*allow-scripts/i,
|
|
296
|
+
/Page JavaScript error:/i,
|
|
297
|
+
/^[a-zA-Z0-9_$]+\[.*\]\s+is not a function/i,
|
|
298
|
+
/^[a-zA-Z0-9_$]+\(.*\)\s+is not a function/i,
|
|
299
|
+
/^[a-zA-Z0-9_$]+\.[a-zA-Z0-9_$]+.*is not a function/i
|
|
296
300
|
];
|
|
297
301
|
return patterns.some(pattern => pattern.test(String(message || '')));
|
|
298
302
|
}
|
|
@@ -568,6 +572,76 @@ async function applyUserAgentSpoofing(page, siteConfig, forceDebug, currentUrl)
|
|
|
568
572
|
}, 'battery API spoofing');
|
|
569
573
|
|
|
570
574
|
// Suppress common console errors
|
|
575
|
+
|
|
576
|
+
// Enhanced Mouse/Pointer Spoofing
|
|
577
|
+
safeExecute(() => {
|
|
578
|
+
// Spoof pointer capabilities
|
|
579
|
+
if (navigator.maxTouchPoints !== undefined) {
|
|
580
|
+
safeDefinePropertyLocal(navigator, 'maxTouchPoints', {
|
|
581
|
+
get: () => Math.random() > 0.7 ? 0 : Math.floor(Math.random() * 5) + 1
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Spoof mouse timing patterns to prevent behavioral fingerprinting
|
|
586
|
+
const originalAddEventListener = EventTarget.prototype.addEventListener;
|
|
587
|
+
EventTarget.prototype.addEventListener = function(type, listener, options) {
|
|
588
|
+
if (type === 'mousemove' && typeof listener === 'function') {
|
|
589
|
+
const wrappedListener = function(event) {
|
|
590
|
+
// Add slight timing variation to prevent pattern detection
|
|
591
|
+
const delay = Math.random() * 2; // 0-2ms variation
|
|
592
|
+
setTimeout(() => listener.call(this, event), delay);
|
|
593
|
+
};
|
|
594
|
+
return originalAddEventListener.call(this, type, wrappedListener, options);
|
|
595
|
+
}
|
|
596
|
+
return originalAddEventListener.call(this, type, listener, options);
|
|
597
|
+
};
|
|
598
|
+
|
|
599
|
+
// Spoof PointerEvent if available
|
|
600
|
+
if (window.PointerEvent) {
|
|
601
|
+
const OriginalPointerEvent = window.PointerEvent;
|
|
602
|
+
window.PointerEvent = function(type, eventInitDict = {}) {
|
|
603
|
+
// Add realistic pointer properties
|
|
604
|
+
const enhancedDict = {
|
|
605
|
+
...eventInitDict,
|
|
606
|
+
pressure: eventInitDict.pressure || (Math.random() * 0.3 + 0.2), // 0.2-0.5
|
|
607
|
+
tangentialPressure: eventInitDict.tangentialPressure || 0,
|
|
608
|
+
tiltX: eventInitDict.tiltX || (Math.random() * 10 - 5), // -5 to 5
|
|
609
|
+
tiltY: eventInitDict.tiltY || (Math.random() * 10 - 5),
|
|
610
|
+
twist: eventInitDict.twist || Math.random() * 360,
|
|
611
|
+
pointerType: eventInitDict.pointerType || 'mouse'
|
|
612
|
+
};
|
|
613
|
+
return new OriginalPointerEvent(type, enhancedDict);
|
|
614
|
+
};
|
|
615
|
+
Object.setPrototypeOf(window.PointerEvent, OriginalPointerEvent);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// Spoof touch capabilities for mobile detection evasion
|
|
619
|
+
if (!window.TouchEvent && Math.random() > 0.8) {
|
|
620
|
+
// 20% chance to add touch support to confuse fingerprinters
|
|
621
|
+
window.TouchEvent = function(type, eventInitDict = {}) {
|
|
622
|
+
return new MouseEvent(type, eventInitDict);
|
|
623
|
+
};
|
|
624
|
+
|
|
625
|
+
safeDefinePropertyLocal(navigator, 'maxTouchPoints', { get: () => 1 });
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// Spoof mouse wheel behavior
|
|
629
|
+
const originalWheelEvent = window.WheelEvent;
|
|
630
|
+
if (originalWheelEvent) {
|
|
631
|
+
window.WheelEvent = function(type, eventInitDict = {}) {
|
|
632
|
+
const enhancedDict = {
|
|
633
|
+
...eventInitDict,
|
|
634
|
+
deltaMode: eventInitDict.deltaMode || 0,
|
|
635
|
+
deltaX: eventInitDict.deltaX || 0,
|
|
636
|
+
deltaY: eventInitDict.deltaY || (Math.random() * 100 - 50),
|
|
637
|
+
deltaZ: eventInitDict.deltaZ || 0
|
|
638
|
+
};
|
|
639
|
+
return new originalWheelEvent(type, enhancedDict);
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
}, 'enhanced mouse/pointer spoofing');
|
|
644
|
+
|
|
571
645
|
safeExecute(() => {
|
|
572
646
|
const originalConsoleError = console.error;
|
|
573
647
|
console.error = function(...args) {
|
|
@@ -728,35 +802,98 @@ async function applyFingerprintProtection(page, siteConfig, forceDebug, currentU
|
|
|
728
802
|
|
|
729
803
|
/**
|
|
730
804
|
* Simulate human-like behavior
|
|
805
|
+
* Enhanced with realistic mouse patterns and timing
|
|
731
806
|
*/
|
|
732
807
|
async function simulateHumanBehavior(page, forceDebug) {
|
|
733
808
|
try {
|
|
734
809
|
await page.evaluateOnNewDocument((debugEnabled) => {
|
|
735
810
|
|
|
736
811
|
try {
|
|
737
|
-
|
|
738
|
-
let
|
|
812
|
+
// Enhanced human-like mouse simulation with realistic patterns
|
|
813
|
+
let mouseX = Math.random() * (window.innerWidth - 100) + 50;
|
|
814
|
+
let mouseY = Math.random() * (window.innerHeight - 100) + 50;
|
|
815
|
+
let lastMoveTime = Date.now();
|
|
816
|
+
let moveCount = 0;
|
|
817
|
+
|
|
818
|
+
// Realistic mouse movement patterns
|
|
819
|
+
const movePatterns = {
|
|
820
|
+
linear: () => ({
|
|
821
|
+
deltaX: (Math.random() - 0.5) * 4,
|
|
822
|
+
deltaY: (Math.random() - 0.5) * 4
|
|
823
|
+
}),
|
|
824
|
+
curved: () => {
|
|
825
|
+
const angle = moveCount * 0.1;
|
|
826
|
+
return {
|
|
827
|
+
deltaX: Math.sin(angle) * 3 + (Math.random() - 0.5) * 2,
|
|
828
|
+
deltaY: Math.cos(angle) * 3 + (Math.random() - 0.5) * 2
|
|
829
|
+
};
|
|
830
|
+
},
|
|
831
|
+
jittery: () => ({
|
|
832
|
+
deltaX: (Math.random() - 0.5) * 8,
|
|
833
|
+
deltaY: (Math.random() - 0.5) * 8
|
|
834
|
+
})
|
|
835
|
+
};
|
|
836
|
+
|
|
837
|
+
const patterns = Object.keys(movePatterns);
|
|
838
|
+
let currentPattern = patterns[Math.floor(Math.random() * patterns.length)];
|
|
839
|
+
let patternChangeCounter = 0;
|
|
739
840
|
|
|
740
841
|
const moveInterval = setInterval(() => {
|
|
741
|
-
|
|
742
|
-
|
|
842
|
+
const now = Date.now();
|
|
843
|
+
const timeDelta = now - lastMoveTime;
|
|
743
844
|
|
|
744
|
-
|
|
745
|
-
|
|
845
|
+
// Change pattern occasionally
|
|
846
|
+
if (patternChangeCounter++ > 20 + Math.random() * 30) {
|
|
847
|
+
currentPattern = patterns[Math.floor(Math.random() * patterns.length)];
|
|
848
|
+
patternChangeCounter = 0;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
// Apply movement pattern
|
|
852
|
+
const movement = movePatterns[currentPattern]();
|
|
853
|
+
mouseX += movement.deltaX;
|
|
854
|
+
mouseY += movement.deltaY;
|
|
855
|
+
|
|
856
|
+
// Keep within bounds with padding
|
|
857
|
+
mouseX = Math.max(10, Math.min(window.innerWidth - 10, mouseX));
|
|
858
|
+
mouseY = Math.max(10, Math.min(window.innerHeight - 10, mouseY));
|
|
746
859
|
|
|
747
860
|
try {
|
|
861
|
+
// Dispatch realistic mouse events with varying timing
|
|
748
862
|
document.dispatchEvent(new MouseEvent('mousemove', {
|
|
749
863
|
clientX: mouseX,
|
|
750
864
|
clientY: mouseY,
|
|
751
|
-
bubbles: true
|
|
865
|
+
bubbles: true,
|
|
866
|
+
cancelable: true,
|
|
867
|
+
view: window,
|
|
868
|
+
detail: 0,
|
|
869
|
+
buttons: 0,
|
|
870
|
+
button: 0
|
|
752
871
|
}));
|
|
872
|
+
|
|
873
|
+
// Occasionally simulate clicks for more realistic behavior
|
|
874
|
+
if (Math.random() > 0.995) { // Very rare clicks
|
|
875
|
+
document.dispatchEvent(new MouseEvent('click', {
|
|
876
|
+
clientX: mouseX,
|
|
877
|
+
clientY: mouseY,
|
|
878
|
+
bubbles: true,
|
|
879
|
+
cancelable: true,
|
|
880
|
+
view: window
|
|
881
|
+
}));
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
moveCount++;
|
|
885
|
+
lastMoveTime = now;
|
|
886
|
+
|
|
753
887
|
} catch (e) {}
|
|
754
|
-
},
|
|
888
|
+
}, 50 + Math.random() * 100); // More frequent, realistic timing (50-150ms)
|
|
755
889
|
|
|
756
|
-
// Stop after
|
|
890
|
+
// Stop after 45 seconds with gradual slowdown
|
|
757
891
|
setTimeout(() => {
|
|
758
|
-
try {
|
|
759
|
-
|
|
892
|
+
try {
|
|
893
|
+
clearInterval(moveInterval);
|
|
894
|
+
if (debugEnabled) console.log('[fingerprint] Enhanced mouse simulation completed');
|
|
895
|
+
} catch (e) {}
|
|
896
|
+
}, 45000);
|
|
760
897
|
|
|
761
898
|
} catch (err) {
|
|
762
899
|
if (debugEnabled) console.log(`[fingerprint] Human behavior simulation failed: ${err.message}`);
|
package/lib/interaction.js
CHANGED
|
@@ -164,6 +164,38 @@ const PROBABILITIES = {
|
|
|
164
164
|
}
|
|
165
165
|
};
|
|
166
166
|
|
|
167
|
+
// === PERFORMANCE OPTIMIZATION VARIABLES ===
|
|
168
|
+
// Viewport caching to reduce repeated page.viewport() calls
|
|
169
|
+
let cachedViewport = null;
|
|
170
|
+
let lastViewportCheck = 0;
|
|
171
|
+
const VIEWPORT_CACHE_DURATION = 30000; // 30 seconds
|
|
172
|
+
let interactionMemoryCleanupCounter = 0;
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Gets viewport dimensions with caching for performance
|
|
176
|
+
* Caches viewport for 30 seconds to avoid repeated queries
|
|
177
|
+
*
|
|
178
|
+
* @param {import('puppeteer').Page} page - Puppeteer page object
|
|
179
|
+
* @returns {Promise<object>} Viewport dimensions {width, height}
|
|
180
|
+
*/
|
|
181
|
+
async function getCachedViewport(page) {
|
|
182
|
+
const now = Date.now();
|
|
183
|
+
|
|
184
|
+
// Return cached viewport if still valid
|
|
185
|
+
if (cachedViewport && (now - lastViewportCheck) < VIEWPORT_CACHE_DURATION) {
|
|
186
|
+
return cachedViewport;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
try {
|
|
190
|
+
cachedViewport = await page.viewport();
|
|
191
|
+
lastViewportCheck = now;
|
|
192
|
+
return cachedViewport || { width: DEFAULT_VIEWPORT.WIDTH, height: DEFAULT_VIEWPORT.HEIGHT };
|
|
193
|
+
} catch (viewportErr) {
|
|
194
|
+
// Return defaults if viewport query fails
|
|
195
|
+
return { width: DEFAULT_VIEWPORT.WIDTH, height: DEFAULT_VIEWPORT.HEIGHT };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
167
199
|
/**
|
|
168
200
|
* Generates random coordinates within viewport bounds with intelligent placement
|
|
169
201
|
*
|
|
@@ -481,8 +513,8 @@ async function interactWithElements(page, options = {}) {
|
|
|
481
513
|
return;
|
|
482
514
|
}
|
|
483
515
|
|
|
484
|
-
//
|
|
485
|
-
await page.waitForSelector('body', { timeout:
|
|
516
|
+
// Very short timeout since page should already be loaded
|
|
517
|
+
await page.waitForSelector('body', { timeout: 1000 });
|
|
486
518
|
} catch (bodyWaitErr) {
|
|
487
519
|
if (options.forceDebug) {
|
|
488
520
|
console.log(`[interaction] Page not ready for element interaction: ${bodyWaitErr.message}`);
|
|
@@ -490,10 +522,10 @@ async function interactWithElements(page, options = {}) {
|
|
|
490
522
|
return;
|
|
491
523
|
}
|
|
492
524
|
|
|
493
|
-
//
|
|
494
|
-
const viewport = await page
|
|
495
|
-
const maxX = viewport
|
|
496
|
-
const maxY = viewport
|
|
525
|
+
// Use cached viewport for better performance
|
|
526
|
+
const viewport = await getCachedViewport(page);
|
|
527
|
+
const maxX = viewport.width;
|
|
528
|
+
const maxY = viewport.height;
|
|
497
529
|
|
|
498
530
|
for (let attempt = 0; attempt < maxAttempts; attempt++) {
|
|
499
531
|
try {
|
|
@@ -638,6 +670,33 @@ async function simulateTyping(page, text, options = {}) {
|
|
|
638
670
|
}
|
|
639
671
|
}
|
|
640
672
|
|
|
673
|
+
/**
|
|
674
|
+
* Cleans up interaction-related memory and cached data
|
|
675
|
+
* Should be called periodically in long-running sessions
|
|
676
|
+
*
|
|
677
|
+
* @param {boolean} force - Force cleanup regardless of timing
|
|
678
|
+
*/
|
|
679
|
+
function cleanupInteractionMemory(force = false) {
|
|
680
|
+
interactionMemoryCleanupCounter++;
|
|
681
|
+
|
|
682
|
+
// Only cleanup every 10 calls unless forced
|
|
683
|
+
if (!force && interactionMemoryCleanupCounter % 10 !== 0) {
|
|
684
|
+
return;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Clear cached viewport if it's older than cache duration
|
|
688
|
+
const now = Date.now();
|
|
689
|
+
if (cachedViewport && (now - lastViewportCheck) > VIEWPORT_CACHE_DURATION) {
|
|
690
|
+
cachedViewport = null;
|
|
691
|
+
lastViewportCheck = 0;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
// Force garbage collection if available (helps with memory pressure)
|
|
695
|
+
if (global.gc) {
|
|
696
|
+
global.gc();
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
|
|
641
700
|
/**
|
|
642
701
|
* Performs comprehensive page interaction simulation - MAIN ENTRY POINT
|
|
643
702
|
*
|
|
@@ -711,10 +770,9 @@ async function performPageInteraction(page, currentUrl, options = {}, forceDebug
|
|
|
711
770
|
try {
|
|
712
771
|
// Validate page state before starting interaction
|
|
713
772
|
try {
|
|
714
|
-
//
|
|
715
|
-
|
|
716
|
-
const
|
|
717
|
-
const bodyTimeout = Math.min(Math.max(siteTimeout / 6, 3000), 8000); // 3-8 seconds
|
|
773
|
+
// Optimized timeout calculation - shorter for better performance
|
|
774
|
+
const siteTimeout = options.siteTimeout || 20000; // Reduced default
|
|
775
|
+
const bodyTimeout = Math.min(Math.max(siteTimeout / 8, 2000), 5000); // 2-5 seconds (reduced)
|
|
718
776
|
|
|
719
777
|
await page.waitForSelector('body', { timeout: bodyTimeout });
|
|
720
778
|
|
|
@@ -735,9 +793,9 @@ async function performPageInteraction(page, currentUrl, options = {}, forceDebug
|
|
|
735
793
|
}
|
|
736
794
|
} catch (bodyCheckErr) {
|
|
737
795
|
if (forceDebug) {
|
|
738
|
-
console.log(`[interaction] Page not ready for interaction on ${currentUrl} (waited ${
|
|
796
|
+
console.log(`[interaction] Page not ready for interaction on ${currentUrl} (waited ${Math.min(Math.max((options.siteTimeout || 20000) / 8, 2000), 5000)}ms): ${bodyCheckErr.message}`);
|
|
739
797
|
// For very slow sites, we might want to try a minimal interaction anyway
|
|
740
|
-
if (
|
|
798
|
+
if (Math.min(Math.max((options.siteTimeout || 20000) / 8, 2000), 5000) >= 4000 && !bodyCheckErr.message.includes('closed')) {
|
|
741
799
|
console.log(`[interaction] Attempting minimal mouse movement only for slow-loading ${currentUrl}`);
|
|
742
800
|
return await performMinimalInteraction(page, currentUrl, options, forceDebug);
|
|
743
801
|
}
|
|
@@ -745,10 +803,10 @@ async function performPageInteraction(page, currentUrl, options = {}, forceDebug
|
|
|
745
803
|
return;
|
|
746
804
|
}
|
|
747
805
|
|
|
748
|
-
//
|
|
749
|
-
const viewport = await page
|
|
750
|
-
const maxX = viewport
|
|
751
|
-
const maxY = viewport
|
|
806
|
+
// Use cached viewport for better performance
|
|
807
|
+
const viewport = await getCachedViewport(page);
|
|
808
|
+
const maxX = viewport.width;
|
|
809
|
+
const maxY = viewport.height;
|
|
752
810
|
|
|
753
811
|
if (forceDebug) {
|
|
754
812
|
console.log(`[interaction] Starting enhanced interaction simulation for ${new URL(currentUrl).hostname} (${intensity} intensity)`);
|
|
@@ -760,7 +818,13 @@ async function performPageInteraction(page, currentUrl, options = {}, forceDebug
|
|
|
760
818
|
|
|
761
819
|
// Start with random position
|
|
762
820
|
let currentPos = generateRandomCoordinates(maxX, maxY, { preferEdges: true });
|
|
821
|
+
|
|
822
|
+
// Batch mouse move operations for better performance
|
|
823
|
+
try {
|
|
763
824
|
await page.mouse.move(currentPos.x, currentPos.y);
|
|
825
|
+
} catch (mouseMoveErr) {
|
|
826
|
+
return; // Exit gracefully if mouse operations fail
|
|
827
|
+
}
|
|
764
828
|
|
|
765
829
|
const startTime = Date.now();
|
|
766
830
|
const totalDuration = duration * settings.pauseMultiplier;
|
|
@@ -812,6 +876,9 @@ async function performPageInteraction(page, currentUrl, options = {}, forceDebug
|
|
|
812
876
|
});
|
|
813
877
|
}
|
|
814
878
|
|
|
879
|
+
// Periodic memory cleanup during interaction
|
|
880
|
+
cleanupInteractionMemory();
|
|
881
|
+
|
|
815
882
|
// Final hover position
|
|
816
883
|
const finalPos = generateRandomCoordinates(maxX, maxY);
|
|
817
884
|
await humanLikeMouseMove(page, currentPos.x, currentPos.y, finalPos.x, finalPos.y);
|
|
@@ -847,9 +914,9 @@ async function performMinimalInteraction(page, currentUrl, options = {}, forceDe
|
|
|
847
914
|
try {
|
|
848
915
|
if (page.isClosed()) return;
|
|
849
916
|
|
|
850
|
-
const viewport = await page
|
|
851
|
-
const maxX = viewport
|
|
852
|
-
const maxY = viewport
|
|
917
|
+
const viewport = await getCachedViewport(page);
|
|
918
|
+
const maxX = viewport.width;
|
|
919
|
+
const maxY = viewport.height;
|
|
853
920
|
|
|
854
921
|
if (forceDebug) {
|
|
855
922
|
console.log(`[interaction] Performing minimal interaction for slow page: ${new URL(currentUrl).hostname}`);
|
|
@@ -860,7 +927,7 @@ async function performMinimalInteraction(page, currentUrl, options = {}, forceDe
|
|
|
860
927
|
const endPos = generateRandomCoordinates(maxX, maxY);
|
|
861
928
|
|
|
862
929
|
await page.mouse.move(startPos.x, startPos.y);
|
|
863
|
-
await fastTimeout(
|
|
930
|
+
await fastTimeout(200);
|
|
864
931
|
await humanLikeMouseMove(page, startPos.x, startPos.y, endPos.x, endPos.y);
|
|
865
932
|
|
|
866
933
|
} catch (minimalErr) {
|
|
@@ -1016,7 +1083,8 @@ module.exports = {
|
|
|
1016
1083
|
// Main interaction functions
|
|
1017
1084
|
performPageInteraction,
|
|
1018
1085
|
createInteractionConfig,
|
|
1019
|
-
|
|
1086
|
+
getCachedViewport,
|
|
1087
|
+
cleanupInteractionMemory,
|
|
1020
1088
|
// Component functions for custom implementations
|
|
1021
1089
|
humanLikeMouseMove,
|
|
1022
1090
|
simulateScrolling,
|
package/nwss.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// === Network scanner script (nwss.js) v1.0.
|
|
1
|
+
// === Network scanner script (nwss.js) v1.0.67 ===
|
|
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
|
|
@@ -85,7 +85,7 @@ const { navigateWithRedirectHandling, handleRedirectTimeout } = require('./lib/r
|
|
|
85
85
|
const { monitorBrowserHealth, isBrowserHealthy } = require('./lib/browserhealth');
|
|
86
86
|
|
|
87
87
|
// --- Script Configuration & Constants ---
|
|
88
|
-
const VERSION = '1.0.
|
|
88
|
+
const VERSION = '1.0.67'; // Script version
|
|
89
89
|
|
|
90
90
|
// get startTime
|
|
91
91
|
const startTime = Date.now();
|
|
@@ -1837,10 +1837,14 @@ function setupFrameHandling(page, forceDebug) {
|
|
|
1837
1837
|
page.on('request', request => {
|
|
1838
1838
|
const checkedUrl = request.url();
|
|
1839
1839
|
const checkedHostname = safeGetDomain(checkedUrl, true);
|
|
1840
|
+
const checkedRootDomain = safeGetDomain(checkedUrl, false); // Root domain for first-party detection
|
|
1840
1841
|
// Use effectiveCurrentUrl which gets updated after redirects
|
|
1841
1842
|
// This ensures first-party detection uses the final redirected domain
|
|
1842
1843
|
const effectiveCurrentHostname = safeGetDomain(effectiveCurrentUrl, true);
|
|
1843
|
-
|
|
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;
|
|
1844
1848
|
|
|
1845
1849
|
// Block infinite iframe loops
|
|
1846
1850
|
const frameUrl = request.frame() ? request.frame().url() : '';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fanboynz/network-scanner",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.67",
|
|
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": {
|