logshield-cli 0.4.3 → 0.5.0
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/CHANGELOG.md +149 -120
- package/README.md +59 -12
- package/dist/cli/index.cjs +69 -21
- package/package.json +36 -8
- package/dist/android-chrome-192x192.png +0 -0
- package/dist/android-chrome-512x512.png +0 -0
- package/dist/apple-touch-icon.png +0 -0
- package/dist/assets/index-B3qxIuiz.css +0 -1
- package/dist/assets/index-DDJ1Wxio.js +0 -29
- package/dist/engine/applyRules.js +0 -27
- package/dist/engine/engine/applyRules.d.ts +0 -5
- package/dist/engine/engine/applyRules.js +0 -30
- package/dist/engine/engine/guard.d.ts +0 -1
- package/dist/engine/engine/guard.js +0 -12
- package/dist/engine/engine/sanitizeLog.d.ts +0 -11
- package/dist/engine/engine/sanitizeLog.js +0 -18
- package/dist/engine/guard.js +0 -9
- package/dist/engine/rules/cloud.d.ts +0 -2
- package/dist/engine/rules/cloud.js +0 -15
- package/dist/engine/rules/credentials.d.ts +0 -2
- package/dist/engine/rules/credentials.js +0 -15
- package/dist/engine/rules/creditCard.d.ts +0 -2
- package/dist/engine/rules/creditCard.js +0 -15
- package/dist/engine/rules/custom.d.ts +0 -2
- package/dist/engine/rules/custom.js +0 -14
- package/dist/engine/rules/index.d.ts +0 -11
- package/dist/engine/rules/index.js +0 -38
- package/dist/engine/rules/tokens.d.ts +0 -2
- package/dist/engine/rules/tokens.js +0 -20
- package/dist/engine/rules/types.d.ts +0 -9
- package/dist/engine/rules/types.js +0 -2
- package/dist/engine/rules/urls.d.ts +0 -2
- package/dist/engine/rules/urls.js +0 -10
- package/dist/engine/sanitizeLog.js +0 -15
- package/dist/engine/utils/luhn.d.ts +0 -1
- package/dist/engine/utils/luhn.js +0 -19
- package/dist/favicon-16x16.png +0 -0
- package/dist/favicon-32x32.png +0 -0
- package/dist/favicon.ico +0 -0
- package/dist/features.jsx +0 -462
- package/dist/privacy.html +0 -217
- package/dist/refund.html +0 -221
- package/dist/robots.txt +0 -4
- package/dist/rules/cloud.js +0 -12
- package/dist/rules/credentials.js +0 -12
- package/dist/rules/creditCard.js +0 -12
- package/dist/rules/custom.js +0 -11
- package/dist/rules/index.js +0 -35
- package/dist/rules/tokens.js +0 -17
- package/dist/rules/types.js +0 -1
- package/dist/rules/urls.js +0 -7
- package/dist/site.webmanifest +0 -20
- package/dist/terms.html +0 -140
- package/dist/utils/luhn.js +0 -16
- package/dist/vite.svg +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,120 +1,149 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## v0.
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
### Notes
|
|
47
|
-
|
|
48
|
-
- No breaking changes
|
|
49
|
-
- No new features
|
|
50
|
-
-
|
|
51
|
-
|
|
52
|
-
## v0.4.
|
|
53
|
-
|
|
54
|
-
###
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
- `--
|
|
69
|
-
|
|
70
|
-
### Improved
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
###
|
|
100
|
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## v0.5.0
|
|
4
|
+
|
|
5
|
+
### Security
|
|
6
|
+
|
|
7
|
+
- Hardened dry-run result shape: dry-run no longer returns the raw input in `output` (safe to serialize and avoids re-leakage in programmatic contexts)
|
|
8
|
+
- `--dry-run` can be combined with `--json` for machine-readable detection without leaking log content (`output` is intentionally empty)
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- Added detection-only helper `scanLog(input)` (internal only; safe to serialize)
|
|
13
|
+
|
|
14
|
+
### Compatibility
|
|
15
|
+
|
|
16
|
+
- CLI behavior is unchanged: dry-run still prints a human report and never echoes log content
|
|
17
|
+
- Programmatic consumers: `dryRun` now returns `output: ""` (intentional)
|
|
18
|
+
- npm package ships CLI only; no supported JS API surface is published
|
|
19
|
+
|
|
20
|
+
## v0.4.4
|
|
21
|
+
|
|
22
|
+
### Fixed
|
|
23
|
+
|
|
24
|
+
- Expanded PASSWORD redaction to cover quoted values (including spaces) and JSON forms (`"password": "..."`)
|
|
25
|
+
- Expanded DB URL credential redaction to cover additional common schemes (`redis://`, `mssql://`, and variants)
|
|
26
|
+
|
|
27
|
+
### Notes
|
|
28
|
+
|
|
29
|
+
- No breaking changes
|
|
30
|
+
- Behavior is still deterministic; this release reduces false negatives in common log formats
|
|
31
|
+
|
|
32
|
+
## v0.4.3
|
|
33
|
+
|
|
34
|
+
### Fixed
|
|
35
|
+
|
|
36
|
+
- Prevented API key redaction from corrupting header names (`x-api-key`)
|
|
37
|
+
- Preserved key labels when redacting `api_key=...` values
|
|
38
|
+
- Corrected CLI exit code for invalid flag combinations (e.g., `--summary --json` exits with code 2)
|
|
39
|
+
|
|
40
|
+
### Improved
|
|
41
|
+
|
|
42
|
+
- Deterministic and aligned `--summary` output (alphabetical, indented)
|
|
43
|
+
- Hardened CLI behavior with end-to-end golden tests
|
|
44
|
+
- Strengthened regression coverage for rule overlap and precedence
|
|
45
|
+
|
|
46
|
+
### Notes
|
|
47
|
+
|
|
48
|
+
- No breaking changes
|
|
49
|
+
- No new features
|
|
50
|
+
- Hardening and correctness release
|
|
51
|
+
|
|
52
|
+
## v0.4.2
|
|
53
|
+
|
|
54
|
+
### Fixed
|
|
55
|
+
|
|
56
|
+
- CLI errors are now written to stderr (CI-safe piping)
|
|
57
|
+
- JSON output is newline-terminated
|
|
58
|
+
- URL redaction is no longer overly aggressive; only credentials and sensitive parameters are redacted
|
|
59
|
+
- PASSWORD redaction preserves original delimiter and spacing
|
|
60
|
+
- Improved dry-run reporting consistency
|
|
61
|
+
- Added contract tests for CLI output and URL behavior
|
|
62
|
+
|
|
63
|
+
## v0.4.1
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- Prevented secret leakage in `--json` output by removing raw match values from the public result shape
|
|
68
|
+
- Forwarded `--dry-run` into the engine to ensure consistent, future-proof behavior
|
|
69
|
+
|
|
70
|
+
### Improved
|
|
71
|
+
|
|
72
|
+
- Expanded credential detection for common API key variants (`api_key`, `api-key`, `apikey`) and `Authorization: Bearer ...`
|
|
73
|
+
- Hardened AWS secret key strict detection to reduce false positives while keeping strict mode safe
|
|
74
|
+
|
|
75
|
+
### Notes
|
|
76
|
+
|
|
77
|
+
- No breaking changes
|
|
78
|
+
- No new features
|
|
79
|
+
- Stability and safety hardening release
|
|
80
|
+
|
|
81
|
+
## v0.4.0
|
|
82
|
+
|
|
83
|
+
### Changed
|
|
84
|
+
|
|
85
|
+
- License updated to Apache-2.0
|
|
86
|
+
- README, website, and blog content aligned to reflect the new license and current project state
|
|
87
|
+
|
|
88
|
+
### Notes
|
|
89
|
+
|
|
90
|
+
- No engine or CLI behavior changes
|
|
91
|
+
- No breaking changes
|
|
92
|
+
|
|
93
|
+
## v0.3.6
|
|
94
|
+
|
|
95
|
+
### Fixed
|
|
96
|
+
|
|
97
|
+
- `--summary` output now correctly written to stderr (safe for piping & redirects)
|
|
98
|
+
|
|
99
|
+
### Improved
|
|
100
|
+
|
|
101
|
+
- CLI documentation clarity
|
|
102
|
+
|
|
103
|
+
### Notes
|
|
104
|
+
|
|
105
|
+
- No breaking changes
|
|
106
|
+
|
|
107
|
+
## v0.3.5
|
|
108
|
+
|
|
109
|
+
### Fixed
|
|
110
|
+
|
|
111
|
+
- Corrected CLI version injection in built CJS output
|
|
112
|
+
- Ensured published npm package reflects actual CLI version
|
|
113
|
+
|
|
114
|
+
### Improved
|
|
115
|
+
|
|
116
|
+
- Deterministic `--dry-run` report formatting (aligned, CI-safe)
|
|
117
|
+
- Dry-run output now strictly non-contextual and stdout-only
|
|
118
|
+
|
|
119
|
+
### Notes
|
|
120
|
+
|
|
121
|
+
- No engine or rule behavior changes
|
|
122
|
+
- Pure CLI/build correctness release
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## v0.3.4
|
|
127
|
+
|
|
128
|
+
### Fixed
|
|
129
|
+
|
|
130
|
+
- README CI badge link on npmjs.com
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## v0.3.3
|
|
135
|
+
|
|
136
|
+
### Added
|
|
137
|
+
|
|
138
|
+
- `--dry-run` mode to detect secrets without modifying output
|
|
139
|
+
- CI-friendly detection workflow (`--dry-run --fail-on-detect`)
|
|
140
|
+
|
|
141
|
+
### Improved
|
|
142
|
+
|
|
143
|
+
- CLI UX consistency
|
|
144
|
+
- README documentation clarity
|
|
145
|
+
|
|
146
|
+
### Notes
|
|
147
|
+
|
|
148
|
+
- No breaking changes
|
|
149
|
+
- Engine behavior unchanged
|
package/README.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
[](https://www.npmjs.com/package/logshield-cli)
|
|
4
4
|
[](https://www.npmjs.com/package/logshield-cli)
|
|
5
5
|
[](https://github.com/afria85/LogShield/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/afria85/LogShield/blob/main/LICENSE)
|
|
7
|
+
[](https://github.com/sponsors/afria85)
|
|
6
8
|
|
|
7
9
|
Your logs already contain secrets. You just don't see them.
|
|
8
10
|
|
|
@@ -95,6 +97,29 @@ It is designed to be **predictable, conservative, and safe for production pipeli
|
|
|
95
97
|
The website and documentation live in the `/docs` directory.
|
|
96
98
|
They are deployed to **https://logshield.dev** via Vercel.
|
|
97
99
|
|
|
100
|
+
## Project links
|
|
101
|
+
|
|
102
|
+
- Website: https://logshield.dev
|
|
103
|
+
- Docs: https://logshield.dev/docs.html
|
|
104
|
+
- GitHub: https://github.com/afria85/LogShield
|
|
105
|
+
- Sponsor: https://github.com/sponsors/afria85
|
|
106
|
+
|
|
107
|
+
## Local preview (website)
|
|
108
|
+
|
|
109
|
+
To preview the website on your computer:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
npm run dev
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
To preview on a phone/tablet on the same Wi-Fi:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
npm run dev:lan
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Then open the printed LAN URL on your device.
|
|
122
|
+
|
|
98
123
|
---
|
|
99
124
|
|
|
100
125
|
## Why LogShield exists
|
|
@@ -193,6 +218,8 @@ logshield scan [file]
|
|
|
193
218
|
|
|
194
219
|
If a file is not provided and input is piped, LogShield automatically reads from **STDIN**.
|
|
195
220
|
|
|
221
|
+
Note: the npm package ships the CLI only; there is no supported JS API surface.
|
|
222
|
+
|
|
196
223
|
---
|
|
197
224
|
|
|
198
225
|
## CLI Flags
|
|
@@ -213,7 +240,7 @@ If a file is not provided and input is piped, LogShield automatically reads from
|
|
|
213
240
|
Print a compact redaction summary
|
|
214
241
|
|
|
215
242
|
- `--json`
|
|
216
|
-
JSON output (
|
|
243
|
+
JSON output (can be combined with `--dry-run`; output is empty in dry-run)
|
|
217
244
|
|
|
218
245
|
- `--version`
|
|
219
246
|
Print CLI version
|
|
@@ -351,8 +378,8 @@ Example:
|
|
|
351
378
|
|
|
352
379
|
```
|
|
353
380
|
LogShield Summary
|
|
354
|
-
API_KEY_HEADER
|
|
355
|
-
PASSWORD
|
|
381
|
+
API_KEY_HEADER x1
|
|
382
|
+
PASSWORD x2
|
|
356
383
|
```
|
|
357
384
|
|
|
358
385
|
Notes:
|
|
@@ -371,9 +398,16 @@ Structured output for tooling and automation:
|
|
|
371
398
|
logshield scan --json < logs.txt
|
|
372
399
|
```
|
|
373
400
|
|
|
401
|
+
Detection-only JSON (safe to serialize; no log content):
|
|
402
|
+
|
|
403
|
+
```bash
|
|
404
|
+
logshield scan --json --dry-run < logs.txt
|
|
405
|
+
```
|
|
406
|
+
|
|
374
407
|
Notes:
|
|
375
408
|
|
|
376
|
-
- `--json`
|
|
409
|
+
- `--json` can be combined with `--dry-run` for machine-readable detection
|
|
410
|
+
- In `--dry-run` JSON mode, `output` is intentionally an empty string
|
|
377
411
|
- Usage errors exit with code `2`
|
|
378
412
|
- Output is always newline-terminated
|
|
379
413
|
|
|
@@ -381,11 +415,11 @@ Notes:
|
|
|
381
415
|
|
|
382
416
|
## Exit codes
|
|
383
417
|
|
|
384
|
-
| Code | Meaning
|
|
385
|
-
| ---: |
|
|
386
|
-
| 0 | Success
|
|
387
|
-
| 1 | Detection found (`--fail-on-detect`)
|
|
388
|
-
| 2 | Runtime or input error
|
|
418
|
+
| Code | Meaning |
|
|
419
|
+
| ---: | --------------------------------------------- |
|
|
420
|
+
| 0 | Success (detection does not change exit code) |
|
|
421
|
+
| 1 | Detection found (`--fail-on-detect`) |
|
|
422
|
+
| 2 | Runtime or input error |
|
|
389
423
|
|
|
390
424
|
---
|
|
391
425
|
|
|
@@ -393,13 +427,13 @@ Notes:
|
|
|
393
427
|
|
|
394
428
|
Depending on rules and mode:
|
|
395
429
|
|
|
396
|
-
- Passwords
|
|
430
|
+
- Passwords (supports quoted and JSON forms)
|
|
397
431
|
- API key headers
|
|
398
432
|
- Authorization bearer tokens
|
|
399
433
|
- JWTs
|
|
400
434
|
- Emails
|
|
401
435
|
- URLs with embedded credentials
|
|
402
|
-
- Database credentials
|
|
436
|
+
- Database credentials (including redis:// and mssql://)
|
|
403
437
|
- Cloud provider credentials
|
|
404
438
|
- Credit card numbers (Luhn-validated)
|
|
405
439
|
|
|
@@ -426,7 +460,7 @@ Depending on rules and mode:
|
|
|
426
460
|
LogShield guarantees:
|
|
427
461
|
|
|
428
462
|
- Deterministic output
|
|
429
|
-
- Stable behavior within **v0.
|
|
463
|
+
- Stable behavior within the current minor line **v0.5.x**
|
|
430
464
|
- No runtime dependencies
|
|
431
465
|
- Snapshot-tested and contract-tested
|
|
432
466
|
- No telemetry
|
|
@@ -457,3 +491,16 @@ It is a **last-line safety net**, not a primary defense.
|
|
|
457
491
|
## License
|
|
458
492
|
|
|
459
493
|
Apache-2.0
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
## Contributing
|
|
497
|
+
|
|
498
|
+
See `CONTRIBUTING.md`.
|
|
499
|
+
|
|
500
|
+
## Security
|
|
501
|
+
|
|
502
|
+
See `SECURITY.md`.
|
|
503
|
+
|
|
504
|
+
## Support
|
|
505
|
+
|
|
506
|
+
See `SUPPORT.md`.
|
package/dist/cli/index.cjs
CHANGED
|
@@ -36,22 +36,24 @@ var readInput_exports = {};
|
|
|
36
36
|
__export(readInput_exports, {
|
|
37
37
|
readInput: () => readInput
|
|
38
38
|
});
|
|
39
|
-
async function readInput(file) {
|
|
39
|
+
async function readInput(file, opts) {
|
|
40
40
|
if (file) {
|
|
41
41
|
if (!import_node_fs.default.existsSync(file)) {
|
|
42
42
|
throw new Error(`File not found: ${file}`);
|
|
43
43
|
}
|
|
44
44
|
return import_node_fs.default.readFileSync(file, "utf8");
|
|
45
45
|
}
|
|
46
|
-
|
|
46
|
+
const stdin = opts?.stdin ?? process.stdin;
|
|
47
|
+
const forceStdin = Boolean(opts?.forceStdin);
|
|
48
|
+
if (!stdin.isTTY || forceStdin) {
|
|
47
49
|
return new Promise((resolve, reject) => {
|
|
48
50
|
let data = "";
|
|
49
|
-
|
|
50
|
-
|
|
51
|
+
stdin.setEncoding?.("utf8");
|
|
52
|
+
stdin.on("data", (chunk) => {
|
|
51
53
|
data += chunk;
|
|
52
54
|
});
|
|
53
|
-
|
|
54
|
-
|
|
55
|
+
stdin.on("end", () => resolve(data));
|
|
56
|
+
stdin.on("error", reject);
|
|
55
57
|
});
|
|
56
58
|
}
|
|
57
59
|
throw new Error("No input provided");
|
|
@@ -200,13 +202,27 @@ var init_credentials = __esm({
|
|
|
200
202
|
// Examples:
|
|
201
203
|
// password=secret -> password=<REDACTED_PASSWORD>
|
|
202
204
|
// Password : 123 -> Password : <REDACTED_PASSWORD>
|
|
203
|
-
|
|
204
|
-
|
|
205
|
+
// Supports quoted keys/values and JSON forms:
|
|
206
|
+
// password="secret value" -> password="<REDACTED_PASSWORD>"
|
|
207
|
+
// "password": "secret value" -> "password": "<REDACTED_PASSWORD>"
|
|
208
|
+
// NOTE: for unquoted values, we stop at whitespace and common JSON delimiters.
|
|
209
|
+
pattern: /\b(["']?password["']?)(\s*[:=]\s*)(?:(["'])([^"'\r\n]*?)\3|([^\s,}\]]+))/gi,
|
|
210
|
+
replace: (_match, _ctx, groups) => {
|
|
211
|
+
const key = groups[0];
|
|
212
|
+
const delim = groups[1];
|
|
213
|
+
const quote = groups[2];
|
|
214
|
+
if (quote) {
|
|
215
|
+
return `${key}${delim}${quote}<REDACTED_PASSWORD>${quote}`;
|
|
216
|
+
}
|
|
217
|
+
return `${key}${delim}<REDACTED_PASSWORD>`;
|
|
218
|
+
}
|
|
205
219
|
},
|
|
206
220
|
// DB URL credential: postgres://user:pass@host
|
|
207
221
|
{
|
|
208
222
|
name: "DB_URL_CREDENTIAL",
|
|
209
|
-
|
|
223
|
+
// Support the most common DB/cache schemes.
|
|
224
|
+
// This focuses only on the user:pass@ authority portion.
|
|
225
|
+
pattern: /\b(postgres(?:ql)?|mysql|mariadb|mongodb(?:\+srv)?|redis|rediss|mssql|sqlserver):\/\/([^:\s]+):([^@\s]+)@/gi,
|
|
210
226
|
replace: (_match, _ctx, groups) => `${groups[0]}://${groups[1]}:<REDACTED_PASSWORD>@`
|
|
211
227
|
},
|
|
212
228
|
// x-api-key: ....
|
|
@@ -489,7 +505,7 @@ function sanitizeLog(input, options) {
|
|
|
489
505
|
const matches = [];
|
|
490
506
|
if (ctx.dryRun) {
|
|
491
507
|
applyRules(input, allRules, ctx, matches);
|
|
492
|
-
return { output:
|
|
508
|
+
return { output: "", matches };
|
|
493
509
|
}
|
|
494
510
|
const output = applyRules(input, allRules, ctx, matches);
|
|
495
511
|
return { output, matches };
|
|
@@ -508,8 +524,18 @@ var { writeOutput: writeOutput2 } = (init_writeOutput(), __toCommonJS(writeOutpu
|
|
|
508
524
|
var { printSummary: printSummary2 } = (init_summary(), __toCommonJS(summary_exports));
|
|
509
525
|
var { sanitizeLog: sanitizeLog2 } = (init_sanitizeLog(), __toCommonJS(sanitizeLog_exports));
|
|
510
526
|
var rawArgs = process.argv.slice(2).map((arg) => arg === "-h" ? "--help" : arg);
|
|
527
|
+
var ALLOWED_FLAGS = /* @__PURE__ */ new Set([
|
|
528
|
+
"--strict",
|
|
529
|
+
"--dry-run",
|
|
530
|
+
"--stdin",
|
|
531
|
+
"--fail-on-detect",
|
|
532
|
+
"--json",
|
|
533
|
+
"--summary",
|
|
534
|
+
"--version",
|
|
535
|
+
"--help"
|
|
536
|
+
]);
|
|
511
537
|
function getVersion() {
|
|
512
|
-
return true ? "0.
|
|
538
|
+
return true ? "0.5.0" : "unknown";
|
|
513
539
|
}
|
|
514
540
|
function printHelp() {
|
|
515
541
|
process.stdout.write(`Usage: logshield scan [file]
|
|
@@ -536,14 +562,23 @@ function writeErr(message) {
|
|
|
536
562
|
function parseArgs(args) {
|
|
537
563
|
const flags = /* @__PURE__ */ new Set();
|
|
538
564
|
const positionals = [];
|
|
565
|
+
const unknownFlags = [];
|
|
539
566
|
for (const arg of args) {
|
|
540
|
-
if (arg.startsWith("
|
|
541
|
-
|
|
567
|
+
if (arg.startsWith("-")) {
|
|
568
|
+
if (arg.startsWith("--")) {
|
|
569
|
+
if (!ALLOWED_FLAGS.has(arg)) {
|
|
570
|
+
unknownFlags.push(arg);
|
|
571
|
+
} else {
|
|
572
|
+
flags.add(arg);
|
|
573
|
+
}
|
|
574
|
+
} else {
|
|
575
|
+
unknownFlags.push(arg);
|
|
576
|
+
}
|
|
542
577
|
} else {
|
|
543
578
|
positionals.push(arg);
|
|
544
579
|
}
|
|
545
580
|
}
|
|
546
|
-
return { flags, positionals };
|
|
581
|
+
return { flags, positionals, unknownFlags };
|
|
547
582
|
}
|
|
548
583
|
function isStdinPiped() {
|
|
549
584
|
return !process.stdin.isTTY;
|
|
@@ -582,16 +617,23 @@ function exitUsageError(message) {
|
|
|
582
617
|
process.exit(2);
|
|
583
618
|
}
|
|
584
619
|
async function main() {
|
|
585
|
-
if (rawArgs.length === 0
|
|
620
|
+
if (rawArgs.length === 0) {
|
|
586
621
|
printHelp();
|
|
587
622
|
process.exit(0);
|
|
588
623
|
}
|
|
589
|
-
|
|
624
|
+
const { flags, positionals, unknownFlags } = parseArgs(rawArgs);
|
|
625
|
+
if (unknownFlags.length > 0) {
|
|
626
|
+
exitUsageError(`Unknown flag: ${unknownFlags[0]}`);
|
|
627
|
+
}
|
|
628
|
+
if (flags.has("--help")) {
|
|
629
|
+
printHelp();
|
|
630
|
+
process.exit(0);
|
|
631
|
+
}
|
|
632
|
+
if (flags.has("--version")) {
|
|
590
633
|
process.stdout.write(`logshield v${getVersion()}
|
|
591
634
|
`);
|
|
592
635
|
process.exit(0);
|
|
593
636
|
}
|
|
594
|
-
const { flags, positionals } = parseArgs(rawArgs);
|
|
595
637
|
const command = positionals[0];
|
|
596
638
|
if (command !== "scan") {
|
|
597
639
|
exitUsageError("Unknown command");
|
|
@@ -608,16 +650,22 @@ async function main() {
|
|
|
608
650
|
if (useStdin && file) {
|
|
609
651
|
exitUsageError("Cannot read from both STDIN and file");
|
|
610
652
|
}
|
|
611
|
-
if (dryRun && json) {
|
|
612
|
-
exitUsageError("--dry-run cannot be used with --json");
|
|
613
|
-
}
|
|
614
653
|
if (json && summary) {
|
|
615
654
|
exitUsageError("--summary cannot be used with --json");
|
|
616
655
|
}
|
|
617
656
|
try {
|
|
618
|
-
const input = await readInput2(useStdin ? void 0 : file
|
|
657
|
+
const input = await readInput2(useStdin ? void 0 : file, {
|
|
658
|
+
forceStdin: stdinFlag
|
|
659
|
+
});
|
|
619
660
|
const result = sanitizeLog2(input, { strict, dryRun });
|
|
620
661
|
if (dryRun) {
|
|
662
|
+
if (json) {
|
|
663
|
+
writeOutput2(result, { json: true });
|
|
664
|
+
if (failOnDetect && result.matches.length > 0) {
|
|
665
|
+
process.exit(1);
|
|
666
|
+
}
|
|
667
|
+
process.exit(0);
|
|
668
|
+
}
|
|
621
669
|
renderDryRunReport(result.matches);
|
|
622
670
|
if (failOnDetect && result.matches.length > 0) {
|
|
623
671
|
process.exit(1);
|
package/package.json
CHANGED
|
@@ -1,35 +1,63 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "logshield-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"bin": {
|
|
7
7
|
"logshield": "dist/cli/index.cjs"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
|
-
"dist",
|
|
10
|
+
"dist/cli",
|
|
11
11
|
"README.md",
|
|
12
12
|
"CHANGELOG.md",
|
|
13
13
|
"LICENSE"
|
|
14
14
|
],
|
|
15
15
|
"scripts": {
|
|
16
16
|
"build": "node scripts/build-cli.cjs",
|
|
17
|
-
"build:web": "vite build --outDir dist-web",
|
|
18
17
|
"build:blog": "node scripts/build-blog.js",
|
|
19
|
-
"dev:web": "vite",
|
|
20
18
|
"typecheck": "tsc -p tsconfig.core.json && tsc -p tsconfig.cli.json --noEmit",
|
|
21
19
|
"pretest": "npm run build",
|
|
22
20
|
"test": "vitest",
|
|
21
|
+
"lint": "npm run typecheck",
|
|
22
|
+
"clean:dist": "node scripts/clean-dist.mjs",
|
|
23
|
+
"prepack": "npm run clean:dist && npm run build",
|
|
24
|
+
"pack:check": "npm pack --dry-run",
|
|
25
|
+
"release:check": "npm run prepublish:check && npm run pack:check",
|
|
23
26
|
"prepublish:check": "npm run typecheck && npm test",
|
|
24
|
-
"prepublishOnly": "npm run prepublish:check"
|
|
27
|
+
"prepublishOnly": "npm run prepublish:check",
|
|
28
|
+
"dev": "node scripts/dev-docs-server.mjs",
|
|
29
|
+
"dev:lan": "node scripts/dev-docs-server.mjs --host 0.0.0.0"
|
|
25
30
|
},
|
|
26
31
|
"devDependencies": {
|
|
27
32
|
"@types/node": "^25.0.3",
|
|
28
|
-
"autoprefixer": "^10.4.23",
|
|
29
33
|
"esbuild": "^0.25.0",
|
|
30
|
-
"postcss": "^8.5.6",
|
|
31
|
-
"tailwindcss": "^3.4.19",
|
|
32
34
|
"typescript": "^5.9.3",
|
|
33
35
|
"vitest": "^4.0.0"
|
|
36
|
+
},
|
|
37
|
+
"description": "Deterministic, rule-based CLI to sanitize secrets from logs. No AI. No cloud. No config.",
|
|
38
|
+
"keywords": [
|
|
39
|
+
"log-sanitization",
|
|
40
|
+
"secret-detection",
|
|
41
|
+
"redaction",
|
|
42
|
+
"security",
|
|
43
|
+
"devops",
|
|
44
|
+
"cli",
|
|
45
|
+
"deterministic",
|
|
46
|
+
"no-ai"
|
|
47
|
+
],
|
|
48
|
+
"repository": {
|
|
49
|
+
"type": "git",
|
|
50
|
+
"url": "git+https://github.com/afria85/LogShield.git"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://logshield.dev",
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/afria85/LogShield/issues"
|
|
55
|
+
},
|
|
56
|
+
"funding": {
|
|
57
|
+
"type": "github",
|
|
58
|
+
"url": "https://github.com/sponsors/afria85"
|
|
59
|
+
},
|
|
60
|
+
"engines": {
|
|
61
|
+
"node": ">=18"
|
|
34
62
|
}
|
|
35
63
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|