privacy-brush 1.0.0 β 1.0.2
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/typecheck.yml +32 -31
- package/.nvmrc +1 -0
- package/README-zh.md +496 -496
- package/README.md +314 -302
- package/package.json +26 -5
- package/src/cli.mjs +25 -5
- package/src/cli.test.mjs +25 -16
- package/src/index.mjs +17 -0
- package/src/lib/config.mjs +6 -1
- package/src/lib/parse-args.mjs +4 -0
package/README.md
CHANGED
|
@@ -1,302 +1,314 @@
|
|
|
1
|
-
<h1 align="center" title="PrivacyBrush">π‘οΈ PrivβcyBrβsh ποΈ</h1>
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
-
|
|
20
|
-
-
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
privacy-brush
|
|
34
|
-
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
//
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
DEBUG:
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
//
|
|
104
|
-
// DEBUG:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
#
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
--
|
|
120
|
-
--
|
|
121
|
-
--
|
|
122
|
-
--
|
|
123
|
-
--
|
|
124
|
-
--
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
###
|
|
178
|
-
|
|
179
|
-
-
|
|
180
|
-
-
|
|
181
|
-
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
-
|
|
187
|
-
-
|
|
188
|
-
-
|
|
189
|
-
|
|
190
|
-
###
|
|
191
|
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
```
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
1
|
+
<h1 align="center" title="PrivacyBrush">π‘οΈ PrivβcyBrβsh ποΈ</h1>
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Share Safely, Start with PrivacyBrush</strong><br>
|
|
5
|
+
<sub>Protect privacy, communicate with confidence</sub>
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
[](https://www.npmjs.com/package/privacy-brush)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
[](https://github.com/legend80s/privacy-brush/actions/workflows/typecheck.yml)
|
|
11
|
+
|
|
12
|
+
<p align="center">
|
|
13
|
+
<img src="https://raw.githubusercontent.com/legend80s/privacy-brush/main/docs/demo.gif" alt="PrivacyBrush Demo" width="800">
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
## β¨ Features
|
|
17
|
+
|
|
18
|
+
- π― **Smart Detection** - Auto-detects 20+ sensitive information patterns
|
|
19
|
+
- π§ **Highly Configurable** - Custom masking rules and characters
|
|
20
|
+
- β‘ **High Performance** - Stream processing for large files
|
|
21
|
+
- π‘οΈ **Privacy First** - Local processing only, no data leaves your machine
|
|
22
|
+
- π¦ **Multiple Formats** - CLI, API, Stream, File processing
|
|
23
|
+
- π **Multi-language** - Supports English, Chinese, and other log formats
|
|
24
|
+
- π¨ **Customizable** - Add your own sensitive patterns
|
|
25
|
+
|
|
26
|
+
## π Quick Start
|
|
27
|
+
|
|
28
|
+
### Basic Usage
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Direct terminal output processing
|
|
32
|
+
flutter devices | pnpx privacy-brush
|
|
33
|
+
flutter doctor | pnpx privacy-brush
|
|
34
|
+
|
|
35
|
+
# Process files
|
|
36
|
+
privacy-brush -i input.log -o masked.log
|
|
37
|
+
|
|
38
|
+
# Real-time command output
|
|
39
|
+
echo 'Microsoft Windows [Version 10.0.12345.6785]' | privacy-brush
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### In Your Node.js Project
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
// Or ES Module
|
|
46
|
+
import { PrivacyBrush } from 'privacy-brush';
|
|
47
|
+
|
|
48
|
+
// Create instance
|
|
49
|
+
const brush = new PrivacyBrush();
|
|
50
|
+
|
|
51
|
+
// Process text
|
|
52
|
+
const sensitiveText = `Windows [Version 10.0.12345.1234]
|
|
53
|
+
Chrome 144.0.1234.12
|
|
54
|
+
User IP: 192.123.1.123`;
|
|
55
|
+
|
|
56
|
+
const safeText = brush.maskText(sensitiveText);
|
|
57
|
+
console.log(safeText);
|
|
58
|
+
|
|
59
|
+
// Output:
|
|
60
|
+
// Windows [Version 10.β.βββββ.ββββ]
|
|
61
|
+
// Chrome 144.β.ββββ.ββ
|
|
62
|
+
// User IP: 192.βββ.β.βββ
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## π Examples
|
|
66
|
+
|
|
67
|
+
### Example 1: Process Flutter Output
|
|
68
|
+
|
|
69
|
+
**Original:**
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
β― flutter devices
|
|
73
|
+
Found 4 connected devices:
|
|
74
|
+
Windows (desktop) β’ windows β’ windows-x64 β’ Microsoft Windows [Version 10.0.12345.1234]
|
|
75
|
+
Chrome (web) β’ chrome β’ web-javascript β’ Google Chrome 144.0.1234.60
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**After PrivacyBrush:**
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
β― flutter devices | privacy-brush
|
|
82
|
+
Found 4 connected devices:
|
|
83
|
+
Windows (desktop) β’ windows β’ windows-x64 β’ Microsoft Windows [Version 10.β.βββββ.ββββ]
|
|
84
|
+
Chrome (web) β’ chrome β’ web-javascript β’ Google Chrome 144.β.ββββ.ββ
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Example 2: Process Node.js Debug Logs
|
|
88
|
+
|
|
89
|
+
```javascript
|
|
90
|
+
const masker = new PrivacyBrush({
|
|
91
|
+
maskChar: '*',
|
|
92
|
+
preserveFirstPart: false
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const debugLog = `
|
|
96
|
+
DEBUG: User login from IP 192.168.1.100
|
|
97
|
+
DEBUG: Session ID: abc123def456
|
|
98
|
+
DEBUG: Browser: Chrome/144.0.1234.60
|
|
99
|
+
DEBUG: OS: Windows 10.0.12345
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
console.log(masker.mask(debugLog));
|
|
103
|
+
// Output:
|
|
104
|
+
// DEBUG: User login from IP ***.***.*.***
|
|
105
|
+
// DEBUG: Session ID: ************
|
|
106
|
+
// DEBUG: Browser: Chrome/***.*.***.**
|
|
107
|
+
// DEBUG: OS: Windows **.*.*****
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## βοΈ Configuration
|
|
111
|
+
|
|
112
|
+
### CLI Options
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Basic usage
|
|
116
|
+
privacy-brush [options]
|
|
117
|
+
|
|
118
|
+
# Options
|
|
119
|
+
--char, -c <char> Mask character (default: β)
|
|
120
|
+
--preserve-first Keep first part of version numbers
|
|
121
|
+
--input, -i <file> File to read from
|
|
122
|
+
--output, -o <file> Output to file
|
|
123
|
+
--strict Strict mode (mask more info)
|
|
124
|
+
--config <file> Use config file
|
|
125
|
+
--list-patterns List all built-in patterns
|
|
126
|
+
--add-pattern <regex> Add custom regex pattern
|
|
127
|
+
--version Show version
|
|
128
|
+
--help Show help
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Read from stdin by default.
|
|
132
|
+
|
|
133
|
+
### JavaScript API Options
|
|
134
|
+
|
|
135
|
+
```javascript
|
|
136
|
+
const masker = new PrivacyBrush({
|
|
137
|
+
// Basic config
|
|
138
|
+
maskChar: 'β', // Mask character
|
|
139
|
+
preserveFirstPart: true, // Keep first part of versions
|
|
140
|
+
|
|
141
|
+
// Pattern config
|
|
142
|
+
patterns: {
|
|
143
|
+
ipAddress: true,
|
|
144
|
+
macAddress: true,
|
|
145
|
+
email: true,
|
|
146
|
+
phone: true,
|
|
147
|
+
creditCard: true,
|
|
148
|
+
jwtToken: true,
|
|
149
|
+
apiKey: true,
|
|
150
|
+
|
|
151
|
+
osVersion: true,
|
|
152
|
+
browserVersion: true,
|
|
153
|
+
appVersion: true,
|
|
154
|
+
|
|
155
|
+
deviceId: true,
|
|
156
|
+
serialNumber: true,
|
|
157
|
+
|
|
158
|
+
filePaths: false, // Don't mask file paths
|
|
159
|
+
localhost: false // Don't mask localhost
|
|
160
|
+
},
|
|
161
|
+
|
|
162
|
+
// Custom patterns
|
|
163
|
+
customPatterns: [
|
|
164
|
+
{
|
|
165
|
+
name: 'custom-id',
|
|
166
|
+
regex: /ID-\d{6}/g,
|
|
167
|
+
mask: 'ID-******'
|
|
168
|
+
}
|
|
169
|
+
]
|
|
170
|
+
});
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## π§ Built-in Patterns
|
|
174
|
+
|
|
175
|
+
PrivacyBrush includes 20+ pre-configured sensitive information patterns:
|
|
176
|
+
|
|
177
|
+
### π Personal Information
|
|
178
|
+
|
|
179
|
+
- Email addresses `user@example.com` β `***@example.com`
|
|
180
|
+
- Phone numbers `13800138000` β `138****8000`
|
|
181
|
+
- ID numbers `110101199001011234` β `110101********1234`
|
|
182
|
+
|
|
183
|
+
### π» Technical Information
|
|
184
|
+
|
|
185
|
+
- IP addresses `192.168.1.100` β `192.168.*.*`
|
|
186
|
+
- MAC addresses `00:1A:2B:3C:4D:5E` β `00:**:**:**:**:**`
|
|
187
|
+
- Port numbers `:8080` β `:****`
|
|
188
|
+
- API keys `sk_live_1234567890` β `sk_live_********`
|
|
189
|
+
|
|
190
|
+
### π₯οΈ System & Browser
|
|
191
|
+
|
|
192
|
+
- Windows versions `10.0.12345.1234` β `10.βββ.βββ.βββ`
|
|
193
|
+
- Chrome versions `144.0.1234.60` β `144.βββ.βββ.βββ`
|
|
194
|
+
- Android versions `Android 16` β `Android ββ`
|
|
195
|
+
|
|
196
|
+
### π’ Business Data
|
|
197
|
+
|
|
198
|
+
- Credit cards `4111 1111 1111 1111` β `4111 **** **** 1111`
|
|
199
|
+
- JWT tokens `eyJhbGciOiJIUzI1...` β `eyJ********...`
|
|
200
|
+
- Session IDs `session-abc123def456` β `session-************`
|
|
201
|
+
|
|
202
|
+
## π οΈ Advanced Usage
|
|
203
|
+
|
|
204
|
+
### Stream Processing for Large Files
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
const fs = require('fs');
|
|
208
|
+
const { createMaskStream } = require('privacy-brush');
|
|
209
|
+
|
|
210
|
+
const inputStream = fs.createReadStream('huge.log');
|
|
211
|
+
const maskStream = createMaskStream();
|
|
212
|
+
|
|
213
|
+
inputStream
|
|
214
|
+
.pipe(maskStream)
|
|
215
|
+
.pipe(fs.createWriteStream('masked-huge.log'))
|
|
216
|
+
.on('finish', () => {
|
|
217
|
+
console.log('Large file processing completed!');
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
### Express.js Integration
|
|
222
|
+
|
|
223
|
+
```javascript
|
|
224
|
+
const express = require('express');
|
|
225
|
+
const { PrivacyBrush } = require('privacy-brush');
|
|
226
|
+
const app = express();
|
|
227
|
+
const masker = new PrivacyBrush();
|
|
228
|
+
|
|
229
|
+
// Middleware: auto-mask sensitive info in responses
|
|
230
|
+
app.use((req, res, next) => {
|
|
231
|
+
const originalSend = res.send;
|
|
232
|
+
res.send = function(body) {
|
|
233
|
+
if (typeof body === 'string' && body.includes('sensitive')) {
|
|
234
|
+
body = masker.mask(body);
|
|
235
|
+
}
|
|
236
|
+
originalSend.call(this, body);
|
|
237
|
+
};
|
|
238
|
+
next();
|
|
239
|
+
});
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### Git Hook Integration
|
|
243
|
+
|
|
244
|
+
```bash
|
|
245
|
+
#!/bin/bash
|
|
246
|
+
# .git/hooks/pre-commit
|
|
247
|
+
|
|
248
|
+
for file in $(git diff --cached --name-only | grep -E '\.(log|txt|json)$'); do
|
|
249
|
+
if privacy-brush --check "$file"; then
|
|
250
|
+
echo "β File $file contains unmasked sensitive information"
|
|
251
|
+
echo "Use: privacy-brush $file -o $file && git add $file"
|
|
252
|
+
exit 1
|
|
253
|
+
fi
|
|
254
|
+
done
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
## π Configuration File
|
|
258
|
+
|
|
259
|
+
Create `privacy-brush.config.json`:
|
|
260
|
+
|
|
261
|
+
```json
|
|
262
|
+
{
|
|
263
|
+
"maskChar": "β",
|
|
264
|
+
"preserveFirstPart": true,
|
|
265
|
+
"patterns": {
|
|
266
|
+
"ipAddress": true,
|
|
267
|
+
"email": true,
|
|
268
|
+
"phone": true,
|
|
269
|
+
"osVersion": true,
|
|
270
|
+
"browserVersion": true
|
|
271
|
+
},
|
|
272
|
+
"customPatterns": [
|
|
273
|
+
{
|
|
274
|
+
"name": "project-api-key",
|
|
275
|
+
"regex": "PROJECT_API_KEY=\\w{32}",
|
|
276
|
+
"mask": "PROJECT_API_KEY=******************************"
|
|
277
|
+
}
|
|
278
|
+
]
|
|
279
|
+
}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
## π€ Contributing
|
|
283
|
+
|
|
284
|
+
We welcome contributions! See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
285
|
+
|
|
286
|
+
1. Fork the repository
|
|
287
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
288
|
+
3. Commit changes (`git commit -m 'Add amazing feature'`)
|
|
289
|
+
4. Push to branch (`git push origin feature/amazing-feature`)
|
|
290
|
+
5. Open a Pull Request
|
|
291
|
+
|
|
292
|
+
## π License
|
|
293
|
+
|
|
294
|
+
MIT License Β© 2024 PrivacyBrush Contributors
|
|
295
|
+
|
|
296
|
+
## π Support
|
|
297
|
+
|
|
298
|
+
- π [Issue Tracker](https://github.com/legend80s/privacy-brush/issues)
|
|
299
|
+
- π¬ [Discussions](https://github.com/legend80s/privacy-brush/discussions)
|
|
300
|
+
- π [Documentation](https://github.com/legend80s/privacy-brush/)
|
|
301
|
+
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
> **Terminal Output Masking Tool | Safely Share Logs by Hiding Sensitive Information**
|
|
305
|
+
|
|
306
|
+
## Development
|
|
307
|
+
|
|
308
|
+
```sh
|
|
309
|
+
# mask stdin with custom patterns
|
|
310
|
+
echo 'DEEPSEEK_API_KEY=sk-af75149812524eb08eb302bf9604c8e8' | node src/cli.mjs --pattern '/sk-[a-z0-9]{20οΌ}/'
|
|
311
|
+
|
|
312
|
+
echo '/c/Users/legend80s/AppData/ /Users/test/code/' | node src/cli.mjs --pattern '/Users/[a-z]{2οΌ}/i'
|
|
313
|
+
# /c/Users/βββββββββ/AppData/ /Users/ββββ/code/
|
|
314
|
+
```
|