@fanboynz/network-scanner 2.0.66 → 3.0.1
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/.github/workflows/npm-publish.yml +140 -11
- package/CHANGELOG.md +164 -0
- package/CLAUDE.md +40 -7
- package/README.md +29 -4
- package/lib/adblock-rust.js +23 -18
- package/lib/adblock.js +127 -82
- package/lib/browserexit.js +213 -203
- package/lib/browserhealth.js +85 -61
- package/lib/cdp.js +103 -81
- package/lib/clear_sitedata.js +61 -159
- package/lib/cloudflare.js +579 -409
- package/lib/colorize.js +29 -12
- package/lib/compare.js +16 -8
- package/lib/compress.js +2 -1
- package/lib/curl.js +287 -220
- package/lib/domain-cache.js +87 -40
- package/lib/dry-run.js +137 -194
- package/lib/fingerprint.js +341 -176
- package/lib/flowproxy.js +391 -188
- package/lib/ghost-cursor.js +8 -7
- package/lib/grep.js +248 -171
- package/lib/ignore_similar.js +70 -124
- package/lib/interaction.js +132 -235
- package/lib/nettools.js +309 -87
- package/lib/openvpn_vpn.js +12 -11
- package/lib/output.js +92 -59
- package/lib/post-processing.js +216 -162
- package/lib/proxy.js +9 -2
- package/lib/redirect.js +47 -31
- package/lib/referrer.js +158 -165
- package/lib/searchstring.js +290 -381
- package/lib/smart-cache.js +141 -91
- package/lib/socks-relay.js +21 -7
- package/lib/spawn-async.js +137 -0
- package/lib/validate_rules.js +188 -176
- package/lib/wireguard_vpn.js +111 -117
- package/nwss.js +743 -159
- package/package.json +4 -4
- package/scripts/test-stealth.js +281 -0
package/lib/colorize.js
CHANGED
|
@@ -3,12 +3,22 @@
|
|
|
3
3
|
// Provides consistent theming across all modules
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* Decide whether to emit ANSI color escape sequences. Precedence:
|
|
7
|
+
* 1. FORCE_COLOR env var (any truthy value other than '0'/'false') — on,
|
|
8
|
+
* even when piped (useful for `node nwss.js | less -R`).
|
|
9
|
+
* 2. NO_COLOR env var (any non-empty value, per https://no-color.org) — off.
|
|
10
|
+
* 3. --no-color / --no-colour CLI flag — off.
|
|
11
|
+
* 4. Non-TTY stdout (piped, redirected to a file) — off, so log files
|
|
12
|
+
* don't end up with raw escape sequences embedded.
|
|
13
|
+
* 5. Default — on.
|
|
14
|
+
* @returns {boolean} True when colors should be emitted.
|
|
8
15
|
*/
|
|
9
16
|
function shouldEnableColors() {
|
|
10
|
-
|
|
17
|
+
const force = process.env.FORCE_COLOR;
|
|
18
|
+
if (force && force !== '0' && force !== 'false') return true;
|
|
19
|
+
if (process.env.NO_COLOR) return false;
|
|
11
20
|
if (process.argv.includes('--no-color') || process.argv.includes('--no-colour')) return false;
|
|
21
|
+
if (!process.stdout.isTTY) return false;
|
|
12
22
|
return true;
|
|
13
23
|
}
|
|
14
24
|
|
|
@@ -85,7 +95,13 @@ const messageColors = {
|
|
|
85
95
|
// File operations
|
|
86
96
|
fileOp: (text) => colorize(text, colors.magenta),
|
|
87
97
|
compression: (text) => colorize(text, colors.cyan),
|
|
88
|
-
|
|
98
|
+
|
|
99
|
+
// Post-processing cleanup summaries (referenced by lib/post-processing.js).
|
|
100
|
+
// Without this entry the callers were falling through to plain console.log
|
|
101
|
+
// because their `if (messageColors && messageColors.cleanup)` guard saw
|
|
102
|
+
// undefined here.
|
|
103
|
+
cleanup: (text) => colorize(text, colors.brightGreen),
|
|
104
|
+
|
|
89
105
|
// Cloudflare specific
|
|
90
106
|
cloudflare: (text) => colorize(text, colors.orange)
|
|
91
107
|
};
|
|
@@ -111,7 +127,12 @@ const tags = {
|
|
|
111
127
|
error: createTag('error', colors.red),
|
|
112
128
|
match: createTag('match', colors.green),
|
|
113
129
|
compare: createTag('compare', colors.blue),
|
|
114
|
-
cloudflare: createTag('cloudflare', colors.orange)
|
|
130
|
+
cloudflare: createTag('cloudflare', colors.orange),
|
|
131
|
+
// proxy: referenced by lib/proxy.js and nwss.js via formatLogMessage('proxy', ...).
|
|
132
|
+
// Was hitting the createTag(tag, colors.white) fallback, allocating a new
|
|
133
|
+
// tag string per call AND rendering as default-white (indistinguishable
|
|
134
|
+
// from regular terminal text). Precomputed in cyan for visibility.
|
|
135
|
+
proxy: createTag('proxy', colors.cyan)
|
|
115
136
|
};
|
|
116
137
|
|
|
117
138
|
/**
|
|
@@ -159,19 +180,15 @@ module.exports = {
|
|
|
159
180
|
// Core functions
|
|
160
181
|
colorize,
|
|
161
182
|
colors,
|
|
162
|
-
|
|
183
|
+
|
|
163
184
|
// Semantic coloring
|
|
164
185
|
messageColors,
|
|
165
186
|
tags,
|
|
166
187
|
createTag,
|
|
167
188
|
formatLogMessage,
|
|
168
|
-
|
|
189
|
+
|
|
169
190
|
// Utility functions
|
|
170
191
|
isColorEnabled,
|
|
171
192
|
shouldEnableColors,
|
|
172
|
-
rainbow
|
|
173
|
-
|
|
174
|
-
// Legacy compatibility - keep original function names
|
|
175
|
-
colorize: colorize, // Explicit export for backward compatibility
|
|
176
|
-
colors: colors // Explicit export for backward compatibility
|
|
193
|
+
rainbow
|
|
177
194
|
};
|
package/lib/compare.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
const fs = require('fs');
|
|
2
|
-
const
|
|
2
|
+
const { formatLogMessage, messageColors } = require('./colorize');
|
|
3
|
+
|
|
4
|
+
// Subsystem tag matches the project convention used by other modules
|
|
5
|
+
// (lib/adblock.js, lib/adblock-rust.js, flowproxy, cloudflare, curl, grep, etc.).
|
|
6
|
+
const COMPARE_TAG = messageColors.processing('[compare]');
|
|
3
7
|
|
|
4
8
|
// Pre-compiled regexes for rule normalization (shared across functions)
|
|
5
9
|
const RE_ADBLOCK_PREFIX = /^\|\|?/;
|
|
@@ -7,9 +11,14 @@ const RE_LOCALHOST_127 = /^127\.0\.0\.1\s+/;
|
|
|
7
11
|
const RE_LOCALHOST_000 = /^0\.0\.0\.0\s+/;
|
|
8
12
|
const RE_CARET_SUFFIX = /\^.*$/;
|
|
9
13
|
const RE_DOLLAR_SUFFIX = /\$.*$/;
|
|
14
|
+
// Inline hosts-file comments: `0.0.0.0 ads.example.com # tracker`. Must be
|
|
15
|
+
// stripped before the prefix/suffix passes so the host token isn't left with
|
|
16
|
+
// trailing annotation text that would never match an incoming rule.
|
|
17
|
+
const RE_INLINE_COMMENT = /\s+#.*$/;
|
|
10
18
|
|
|
11
19
|
function normalizeRuleInline(rule) {
|
|
12
20
|
return rule
|
|
21
|
+
.replace(RE_INLINE_COMMENT, '')
|
|
13
22
|
.replace(RE_ADBLOCK_PREFIX, '')
|
|
14
23
|
.replace(RE_LOCALHOST_127, '')
|
|
15
24
|
.replace(RE_LOCALHOST_000, '')
|
|
@@ -41,7 +50,7 @@ function loadComparisonRules(compareFilePath, forceDebug = false) {
|
|
|
41
50
|
}
|
|
42
51
|
|
|
43
52
|
if (forceDebug) {
|
|
44
|
-
console.log(
|
|
53
|
+
console.log(formatLogMessage('debug', `${COMPARE_TAG} Loaded ${rules.size} comparison rules from ${compareFilePath}`));
|
|
45
54
|
}
|
|
46
55
|
|
|
47
56
|
return rules;
|
|
@@ -106,7 +115,7 @@ function filterUniqueRules(rules, comparisonRules, forceDebug = false) {
|
|
|
106
115
|
} else {
|
|
107
116
|
duplicateCount++;
|
|
108
117
|
if (forceDebug) {
|
|
109
|
-
console.log(
|
|
118
|
+
console.log(formatLogMessage('debug', `${COMPARE_TAG} Filtered duplicate rule: ${rule} (normalized: ${normalized})`));
|
|
110
119
|
}
|
|
111
120
|
}
|
|
112
121
|
}
|
|
@@ -122,14 +131,14 @@ function filterUniqueRules(rules, comparisonRules, forceDebug = false) {
|
|
|
122
131
|
// Title with no remaining rules - this is an orphaned title
|
|
123
132
|
orphanedTitles++;
|
|
124
133
|
if (forceDebug) {
|
|
125
|
-
console.log(
|
|
134
|
+
console.log(formatLogMessage('debug', `${COMPARE_TAG} Filtered orphaned title: ${group.title} (no unique rules remaining)`));
|
|
126
135
|
}
|
|
127
136
|
}
|
|
128
137
|
}
|
|
129
|
-
|
|
138
|
+
|
|
130
139
|
if (forceDebug) {
|
|
131
|
-
console.log(
|
|
132
|
-
console.log(
|
|
140
|
+
console.log(formatLogMessage('debug', `${COMPARE_TAG} Filtered ${duplicateCount} duplicate rules and ${orphanedTitles} orphaned titles`));
|
|
141
|
+
console.log(formatLogMessage('debug', `${COMPARE_TAG} ${result.filter(r => !r.startsWith('!')).length} unique rules remaining`));
|
|
133
142
|
}
|
|
134
143
|
|
|
135
144
|
return result;
|
|
@@ -137,6 +146,5 @@ function filterUniqueRules(rules, comparisonRules, forceDebug = false) {
|
|
|
137
146
|
|
|
138
147
|
module.exports = {
|
|
139
148
|
loadComparisonRules,
|
|
140
|
-
normalizeRule,
|
|
141
149
|
filterUniqueRules
|
|
142
150
|
};
|
package/lib/compress.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// This module provides gzip compression functionality for log files
|
|
3
3
|
|
|
4
4
|
const fs = require('fs');
|
|
5
|
+
const { formatLogMessage } = require('./colorize');
|
|
5
6
|
const zlib = require('zlib');
|
|
6
7
|
const path = require('path');
|
|
7
8
|
|
|
@@ -42,7 +43,7 @@ async function compressFile(filePath, removeOriginal = true) {
|
|
|
42
43
|
fs.unlinkSync(filePath);
|
|
43
44
|
} catch (removeErr) {
|
|
44
45
|
// If we can't remove original, still consider compression successful
|
|
45
|
-
console.warn(
|
|
46
|
+
console.warn(formatLogMessage('warn', `Failed to remove original file ${filePath}: ${removeErr.message}`));
|
|
46
47
|
}
|
|
47
48
|
}
|
|
48
49
|
resolve(compressedPath);
|