@fanboynz/network-scanner 2.0.56 → 2.0.58

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.
@@ -1,22 +1,21 @@
1
1
  name: Publish to NPM
2
2
  on:
3
- push:
4
- branches: [ main, master ]
3
+ workflow_dispatch:
5
4
 
6
5
  jobs:
7
6
  publish:
8
7
  runs-on: ubuntu-latest
9
8
  permissions:
10
- contents: write # This is key!
9
+ contents: write
11
10
 
12
11
  steps:
13
- - uses: actions/checkout@v4
12
+ - uses: actions/checkout@v5
14
13
  with:
15
14
  token: ${{ secrets.GITHUB_TOKEN }}
16
15
  fetch-depth: 0
17
16
 
18
17
  - name: Setup Node.js
19
- uses: actions/setup-node@v4
18
+ uses: actions/setup-node@v5
20
19
  with:
21
20
  node-version: '20'
22
21
  registry-url: 'https://registry.npmjs.org'
package/CLAUDE.md ADDED
@@ -0,0 +1,65 @@
1
+ # Network Scanner (NWSS)
2
+
3
+ Puppeteer-based network scanner for analyzing web traffic, generating adblock filter rules, and identifying third-party requests. Features fingerprint spoofing, Cloudflare bypass, content analysis with curl/grep, VPN/proxy routing, and multiple output formats.
4
+
5
+ ## Project Structure
6
+
7
+ - `nwss.js` — Main entry point (~4,600 lines). CLI args, URL processing, orchestration.
8
+ - `config.json` — Default scan configuration (sites, filters, options).
9
+ - `lib/` — 28 focused, single-purpose modules:
10
+ - `fingerprint.js` — Bot detection evasion (device/GPU/timezone spoofing)
11
+ - `cloudflare.js` — Cloudflare challenge detection and solving
12
+ - `browserhealth.js` — Memory management and browser lifecycle
13
+ - `interaction.js` — Human-like mouse/scroll/typing simulation
14
+ - `smart-cache.js` — Multi-layer caching with persistence
15
+ - `nettools.js` — WHOIS/dig integration
16
+ - `output.js` — Multi-format rule output (adblock, dnsmasq, unbound, pihole, etc.)
17
+ - `proxy.js` — SOCKS5/HTTP proxy support
18
+ - `wireguard_vpn.js` / `openvpn_vpn.js` — VPN routing
19
+ - `adblock.js` — Adblock filter parsing and validation
20
+ - `validate_rules.js` — Domain and rule format validation
21
+ - `colorize.js` — Console output formatting and colors
22
+ - `domain-cache.js` — Domain detection cache for performance
23
+ - `post-processing.js` — Result cleanup and deduplication
24
+ - `redirect.js`, `referrer.js`, `cdp.js`, `curl.js`, `grep.js`, `compare.js`, `compress.js`, `dry-run.js`, `browserexit.js`, `clear_sitedata.js`, `flowproxy.js`, `ignore_similar.js`, `searchstring.js`
25
+ - `.github/workflows/npm-publish.yml` — Automated npm publishing
26
+ - `nwss.1` — Man page
27
+
28
+ ## Tech Stack
29
+
30
+ - **Node.js** >=20.0.0
31
+ - **puppeteer** >=20.0.0 — Headless browser automation
32
+ - **psl** — Public Suffix List for domain parsing
33
+ - **lru-cache** — LRU cache implementation
34
+ - **p-limit** — Concurrency limiting (dynamically imported)
35
+ - **eslint** — Linting (`npm run lint`)
36
+
37
+ ## Conventions
38
+
39
+ - Store modular functionality in `./lib/` with focused, single-purpose modules
40
+ - Use `messageColors` and `formatLogMessage` from `./lib/colorize` for consistent console output
41
+ - Implement timeout protection for all Puppeteer operations using `Promise.race` patterns
42
+ - Handle browser lifecycle with comprehensive cleanup in try-finally blocks
43
+ - Validate all external tool availability before use (grep, curl, whois, dig)
44
+ - Use `forceDebug` flag for detailed logging, `silentMode` for minimal output
45
+ - Use `Object.freeze` for constant configuration objects (TIMEOUTS, CACHE_LIMITS, CONCURRENCY_LIMITS)
46
+ - Use `fastTimeout(ms)` helper instead of `node:timers/promises` for Puppeteer 22.x compatibility
47
+
48
+ ## Running
49
+
50
+ ```bash
51
+ node nwss.js # Run with default config.json
52
+ node nwss.js config-custom.json # Run with custom config
53
+ node nwss.js --validate-config # Validate configuration
54
+ node nwss.js --dry-run # Preview without network calls
55
+ node nwss.js --headful # Launch with browser GUI
56
+ ```
57
+
58
+ ## Files to Ignore
59
+
60
+ - `node_modules/**`
61
+ - `logs/**`
62
+ - `sources/**`
63
+ - `.cache/**`
64
+ - `*.log`
65
+ - `*.gz`
package/lib/adblock.js CHANGED
@@ -51,11 +51,12 @@ function parseAdblockRules(filePath, options = {}) {
51
51
  caseSensitive = false
52
52
  } = options;
53
53
 
54
- if (!fs.existsSync(filePath)) {
54
+ let fileContent;
55
+ try {
56
+ fileContent = fs.readFileSync(filePath, 'utf-8');
57
+ } catch (err) {
55
58
  throw new Error(`Adblock rules file not found: ${filePath}`);
56
59
  }
57
-
58
- const fileContent = fs.readFileSync(filePath, 'utf-8');
59
60
  const lines = fileContent.split('\n');
60
61
 
61
62
  const rules = {
@@ -5,6 +5,7 @@
5
5
 
6
6
 
7
7
  const fs = require('fs');
8
+ const path = require('path');
8
9
  const { execSync } = require('child_process');
9
10
 
10
11
  // Constants for temp file cleanup
@@ -15,20 +16,55 @@ const CHROME_TEMP_PATHS = [
15
16
  ];
16
17
 
17
18
  const CHROME_TEMP_PATTERNS = [
18
- 'com.google.Chrome.*', // Google Chrome temp files (no leading dot)
19
- '.org.chromium.Chromium.*',
20
- 'puppeteer-*'
19
+ /^\.?com\.google\.Chrome\./,
20
+ /^\.?org\.chromium\.Chromium\./,
21
+ /^puppeteer-/
21
22
  ];
22
23
 
24
+ /**
25
+ * Count and remove matching Chrome/Puppeteer temp entries from a directory using fs
26
+ * @param {string} basePath - Directory to scan
27
+ * @param {boolean} forceDebug - Whether to output debug logs
28
+ * @returns {number} Number of items cleaned
29
+ */
30
+ function cleanTempDir(basePath, forceDebug) {
31
+ let entries;
32
+ try {
33
+ entries = fs.readdirSync(basePath);
34
+ } catch {
35
+ if (forceDebug) console.log(`[debug] [temp-cleanup] Cannot read ${basePath}`);
36
+ return 0;
37
+ }
38
+
39
+ let cleaned = 0;
40
+ for (const entry of entries) {
41
+ let matched = false;
42
+ for (const re of CHROME_TEMP_PATTERNS) {
43
+ if (re.test(entry)) { matched = true; break; }
44
+ }
45
+ if (!matched) continue;
46
+
47
+ try {
48
+ fs.rmSync(path.join(basePath, entry), { recursive: true, force: true });
49
+ cleaned++;
50
+ if (forceDebug) console.log(`[debug] [temp-cleanup] Removed ${basePath}/${entry}`);
51
+ } catch (rmErr) {
52
+ if (forceDebug) console.log(`[debug] [temp-cleanup] Failed to remove ${basePath}/${entry}: ${rmErr.message}`);
53
+ }
54
+ }
55
+
56
+ return cleaned;
57
+ }
58
+
23
59
  /**
24
60
  * Clean Chrome temporary files and directories
25
61
  * @param {Object} options - Cleanup options
26
62
  * @param {boolean} options.includeSnapTemp - Whether to clean snap temp directories
27
63
  * @param {boolean} options.forceDebug - Whether to output debug logs
28
64
  * @param {boolean} options.comprehensive - Whether to perform comprehensive cleanup of all temp locations
29
- * @returns {Promise<Object>} Cleanup results
65
+ * @returns {Object} Cleanup results
30
66
  */
31
- async function cleanupChromeTempFiles(options = {}) {
67
+ function cleanupChromeTempFiles(options = {}) {
32
68
  const {
33
69
  includeSnapTemp = false,
34
70
  forceDebug = false,
@@ -36,57 +72,20 @@ async function cleanupChromeTempFiles(options = {}) {
36
72
  } = options;
37
73
 
38
74
  try {
39
-
40
- // Base cleanup commands for standard temp directories
41
- const cleanupCommands = [
42
- 'rm -rf /tmp/com.google.Chrome.* 2>/dev/null || true',
43
- 'rm -rf /tmp/.com.google.Chrome.* 2>/dev/null || true',
44
- 'rm -rf /tmp/.org.chromium.Chromium.* 2>/dev/null || true',
45
- 'rm -rf /tmp/puppeteer-* 2>/dev/null || true',
46
- 'rm -rf /dev/shm/.com.google.Chrome.* 2>/dev/null || true',
47
- 'rm -rf /dev/shm/.org.chromium.Chromium.* 2>/dev/null || true'
48
- ];
49
-
50
- // Add snap-specific cleanup if requested
51
- if (includeSnapTemp || comprehensive) {
52
- cleanupCommands.push('rm -rf /dev/shm/com.google.Chrome.* 2>/dev/null || true');
53
- cleanupCommands.push(
54
- 'rm -rf /tmp/snap-private-tmp/snap.chromium/tmp/.org.chromium.Chromium.* 2>/dev/null || true',
55
- 'rm -rf /tmp/snap-private-tmp/snap.chromium/tmp/puppeteer-* 2>/dev/null || true'
56
- );
57
- }
75
+ const paths = comprehensive || includeSnapTemp
76
+ ? CHROME_TEMP_PATHS
77
+ : CHROME_TEMP_PATHS.slice(0, 2); // /tmp and /dev/shm only
58
78
 
59
79
  let totalCleaned = 0;
60
-
61
- for (const command of cleanupCommands) {
62
- try {
63
- // Extract glob pattern and count matches before deletion
64
- const globPattern = command.match(/rm -rf ([^ ]+)/)?.[1];
65
- if (!globPattern) continue;
66
- const fileCount = parseInt(execSync(`ls -1d ${globPattern} 2>/dev/null | wc -l || echo 0`, { stdio: 'pipe' }).toString().trim()) || 0;
67
-
68
- if (fileCount > 0) {
69
- execSync(command, { stdio: 'ignore' });
70
- totalCleaned += fileCount;
71
-
72
- if (forceDebug) {
73
- console.log(`[debug] [temp-cleanup] Cleaned ${fileCount} items from ${globPattern}`);
74
- }
75
- }
76
- } catch (cmdErr) {
77
- // Ignore individual command errors but log in debug mode
78
- if (forceDebug) {
79
- console.log(`[debug] [temp-cleanup] Cleanup command failed: ${command} (${cmdErr.message})`);
80
- }
81
- }
80
+ for (const basePath of paths) {
81
+ totalCleaned += cleanTempDir(basePath, forceDebug);
82
82
  }
83
83
 
84
84
  if (forceDebug) {
85
- console.log(`[debug] [temp-cleanup] Standard cleanup completed (${totalCleaned} items)`);
85
+ console.log(`[debug] [temp-cleanup] Cleanup completed (${totalCleaned} items)`);
86
86
  }
87
-
87
+
88
88
  return { success: true, itemsCleaned: totalCleaned };
89
-
90
89
  } catch (cleanupErr) {
91
90
  if (forceDebug) {
92
91
  console.log(`[debug] [temp-cleanup] Chrome cleanup error: ${cleanupErr.message}`);
@@ -96,72 +95,38 @@ async function cleanupChromeTempFiles(options = {}) {
96
95
  }
97
96
 
98
97
  /**
99
- * Comprehensive temp file cleanup that systematically checks all known Chrome temp locations
98
+ * Comprehensive temp file cleanup that checks all known Chrome temp locations
100
99
  * @param {Object} options - Cleanup options
101
100
  * @param {boolean} options.forceDebug - Whether to output debug logs
102
101
  * @param {boolean} options.verbose - Whether to show verbose output
103
- * @returns {Promise<Object>} Cleanup results
102
+ * @returns {Object} Cleanup results
104
103
  */
105
- async function comprehensiveChromeTempCleanup(options = {}) {
104
+ function comprehensiveChromeTempCleanup(options = {}) {
106
105
  const { forceDebug = false, verbose = false } = options;
107
-
106
+
108
107
  try {
109
- let totalCleaned = 0;
110
-
111
108
  if (verbose && !forceDebug) {
112
109
  console.log(`[temp-cleanup] Scanning Chrome/Puppeteer temporary files...`);
113
110
  }
114
-
111
+
112
+ let totalCleaned = 0;
115
113
  for (const basePath of CHROME_TEMP_PATHS) {
116
- // Check if the base path exists before trying to clean it
117
- try {
118
- const pathExists = fs.existsSync(basePath);
119
-
120
- if (!pathExists) {
121
- if (forceDebug) {
122
- console.log(`[debug] [temp-cleanup] Skipping non-existent path: ${basePath}`);
123
- }
124
- continue;
125
- }
126
-
127
- for (const pattern of CHROME_TEMP_PATTERNS) {
128
- const fullPattern = `${basePath}/${pattern}`;
129
-
130
- // Count items before deletion
131
- const countCommand = `ls -1d ${fullPattern} 2>/dev/null | wc -l || echo 0`;
132
- const itemCount = parseInt(execSync(countCommand, { stdio: 'pipe' }).toString().trim()) || 0;
133
-
134
- if (itemCount > 0) {
135
- const deleteCommand = `rm -rf ${fullPattern} 2>/dev/null || true`;
136
- execSync(deleteCommand, { stdio: 'ignore' });
137
- totalCleaned += itemCount;
138
-
139
- if (forceDebug) {
140
- console.log(`[debug] [temp-cleanup] Removed ${itemCount} items matching ${fullPattern}`);
141
- }
142
- }
143
- }
144
- } catch (pathErr) {
145
- if (forceDebug) {
146
- console.log(`[debug] [temp-cleanup] Error checking path ${basePath}: ${pathErr.message}`);
147
- }
148
- }
114
+ totalCleaned += cleanTempDir(basePath, forceDebug);
149
115
  }
150
-
116
+
151
117
  if (verbose && totalCleaned > 0) {
152
- console.log(`[temp-cleanup] ? Removed ${totalCleaned} temporary file(s)/folder(s)`);
118
+ console.log(`[temp-cleanup] Removed ${totalCleaned} temporary file(s)/folder(s)`);
153
119
  } else if (verbose && totalCleaned === 0) {
154
- console.log(`[temp-cleanup] ? Clean - no remaining temporary files`);
120
+ console.log(`[temp-cleanup] Clean - no remaining temporary files`);
155
121
  } else if (forceDebug) {
156
122
  console.log(`[debug] [temp-cleanup] Comprehensive cleanup completed (${totalCleaned} items)`);
157
123
  }
158
-
124
+
159
125
  return { success: true, itemsCleaned: totalCleaned };
160
-
161
126
  } catch (err) {
162
127
  const errorMsg = `Comprehensive temp file cleanup failed: ${err.message}`;
163
128
  if (verbose) {
164
- console.warn(`[temp-cleanup] ? ${errorMsg}`);
129
+ console.warn(`[temp-cleanup] ${errorMsg}`);
165
130
  } else if (forceDebug) {
166
131
  console.log(`[debug] [temp-cleanup] ${errorMsg}`);
167
132
  }
@@ -317,7 +282,7 @@ async function forceBrowserKill(browser, forceDebug = false) {
317
282
  }
318
283
 
319
284
  // Wait for graceful termination
320
- await new Promise(resolve => setTimeout(resolve, 3000));
285
+ await new Promise(resolve => setTimeout(resolve, 1000));
321
286
 
322
287
  // Force kill any remaining processes with SIGKILL
323
288
  for (const pid of pidsToKill) {