spamscanner 6.0.0 → 6.1.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/README.md CHANGED
@@ -1,19 +1,26 @@
1
- # Spam Scanner
2
-
3
- > **The best anti-spam, email filtering, and phishing prevention service for Node.js**
4
-
5
- [![build status](https://github.com/spamscanner/spamscanner/actions/workflows/ci.yml/badge.svg)](https://github.com/spamscanner/spamscanner/actions/workflows/ci.yml)
6
- [![code coverage](https://img.shields.io/badge/coverage-88.41%25-brightgreen.svg)](https://github.com/spamscanner/spamscanner)
7
- [![code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
8
- [![styled with prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://github.com/prettier/prettier)
9
- [![made with lass](https://img.shields.io/badge/made_with-lass-95CC28.svg)](https://lass.js.org)
10
- [![license](https://img.shields.io/github/license/spamscanner/spamscanner.svg)](LICENSE)
1
+ <h1 align="center">
2
+ <a href="https://spamscanner.net"><img src="https://raw.githubusercontent.com/spamscanner/spamscanner/master/media/spamscanner.png" alt="spamscanner" /></a>
3
+ </h1>
4
+ <div align="center">
5
+ <a href="https://github.com/spamscanner/spamscanner/actions/workflows/ci.yml"><img src="https://github.com/spamscanner/spamscanner/actions/workflows/ci.yml/badge.svg" alt="build status" /></a>
6
+ <a href="https://github.com/sindresorhus/xo"><img src="https://img.shields.io/badge/code_style-XO-5ed9c7.svg" alt="code style" /></a>
7
+ <a href="https://github.com/prettier/prettier"><img src="https://img.shields.io/badge/styled_with-prettier-ff69b4.svg" alt="styled with prettier" /></a>
8
+ <a href="https://lass.js.org"><img src="https://img.shields.io/badge/made_with-lass-95CC28.svg" alt="made with lass" /></a>
9
+ <a href="LICENSE"><img src="https://img.shields.io/github/license/spamscanner/spamscanner.svg" alt="license" /></a>
10
+ </div>
11
+ <br />
12
+ <div align="center">
13
+ Spam Scanner is the best <a href="https://en.wikipedia.org/wiki/Anti-spam_techniques" target="_blank">anti-spam</a>, <a href="https://en.wikipedia.org/wiki/Email_filtering" target="_blank">email filtering</a>, and <a href="https://en.wikipedia.org/wiki/Phishing" target="_blank">phishing prevention</a> service.
14
+ </div>
15
+ <hr />
16
+ <div align="center">
17
+ Spam Scanner is a drop-in replacement and the best alternative to SpamAssassin, rspamd, SpamTitan, and more.
18
+ </div>
19
+ <hr />
11
20
 
12
21
  > \[!NOTE]
13
22
  > Spam Scanner is actively maintained and used in production at [Forward Email](https://forwardemail.net) to protect millions of emails daily.
14
23
 
15
- ---
16
-
17
24
 
18
25
  ## Table of Contents
19
26
 
@@ -59,6 +66,19 @@
59
66
  * [Selective Feature Disabling](#selective-feature-disabling)
60
67
  * [Custom Timeout](#custom-timeout)
61
68
  * [Custom Logger](#custom-logger)
69
+ * [CLI (Command Line Interface)](#cli-command-line-interface)
70
+ * [CLI Installation](#cli-installation)
71
+ * [Commands](#commands)
72
+ * [Exit Codes](#exit-codes)
73
+ * [CLI Examples](#cli-examples)
74
+ * [ARF (Abuse Reporting Format)](#arf-abuse-reporting-format)
75
+ * [Parsing ARF Reports](#parsing-arf-reports)
76
+ * [Creating ARF Reports](#creating-arf-reports)
77
+ * [ARF Result Object](#arf-result-object)
78
+ * [Mail Server Integration](#mail-server-integration)
79
+ * [Postfix Integration](#postfix-integration)
80
+ * [Dovecot Integration](#dovecot-integration)
81
+ * [TCP Server Mode](#tcp-server-mode)
62
82
  * [Performance](#performance)
63
83
  * [Benchmarks](#benchmarks)
64
84
  * [Optimization Tips](#optimization-tips)
@@ -282,27 +302,27 @@ graph TB
282
302
  C --> D[Language Detection]
283
303
  D --> E[Tokenization]
284
304
  E --> F[Naive Bayes Classification]
285
-
305
+
286
306
  B --> G[Phishing Detection]
287
307
  G --> G1[IDN Homograph Check]
288
308
  G --> G2[Confusables Analysis]
289
309
  G --> G3[URL Analysis]
290
-
310
+
291
311
  B --> H[Attachment Scanning]
292
312
  H --> H1[Virus Scan]
293
313
  H --> H2[Executable Check]
294
314
  H --> H3[Macro Detection]
295
315
  H --> H4[NSFW Detection]
296
-
316
+
297
317
  B --> I[Content Analysis]
298
318
  I --> I1[Toxicity Detection]
299
319
  I --> I2[Pattern Recognition]
300
-
320
+
301
321
  F --> J[Result Aggregation]
302
322
  G --> J
303
323
  H --> J
304
324
  I --> J
305
-
325
+
306
326
  J --> K{Is Spam?}
307
327
  K -->|Yes| L[Spam Result]
308
328
  K -->|No| M[Ham Result]
@@ -317,12 +337,12 @@ sequenceDiagram
317
337
  participant Classifier
318
338
  participant ClamAV
319
339
  participant TensorFlow
320
-
340
+
321
341
  Client->>Scanner: scan(email)
322
342
  Scanner->>Scanner: Parse Email
323
343
  Scanner->>Scanner: Extract URLs
324
344
  Scanner->>Scanner: Detect Language
325
-
345
+
326
346
  par Parallel Detection
327
347
  Scanner->>Classifier: Classify Tokens
328
348
  Scanner->>ClamAV: Scan Attachments
@@ -331,7 +351,7 @@ sequenceDiagram
331
351
  Scanner->>Scanner: Check Phishing
332
352
  Scanner->>Scanner: Check Macros
333
353
  end
334
-
354
+
335
355
  Scanner->>Scanner: Aggregate Results
336
356
  Scanner->>Client: Return Result
337
357
  ```
@@ -344,20 +364,20 @@ graph LR
344
364
  A --> C[Classifiers]
345
365
  A --> D[Detectors]
346
366
  A --> E[Analyzers]
347
-
367
+
348
368
  B --> B1[Email Parser]
349
369
  B --> B2[Tokenizer]
350
370
  B --> B3[Preprocessor]
351
-
371
+
352
372
  C --> C1[Naive Bayes]
353
373
  C --> C2[TensorFlow NSFW]
354
374
  C --> C3[TensorFlow Toxicity]
355
-
375
+
356
376
  D --> D1[Phishing Detector]
357
377
  D --> D2[Virus Scanner]
358
378
  D --> D3[Macro Detector]
359
379
  D --> D4[Executable Detector]
360
-
380
+
361
381
  E --> E1[Language Analyzer]
362
382
  E --> E2[URL Analyzer]
363
383
  E --> E3[Pattern Analyzer]
@@ -465,16 +485,16 @@ import SpamScanner from 'spamscanner';
465
485
  const scanner = new SpamScanner({
466
486
  // Enable performance metrics
467
487
  enablePerformanceMetrics: true,
468
-
488
+
469
489
  // Filter to supported languages
470
490
  supportedLanguages: ['en', 'es', 'fr', 'de'],
471
-
491
+
472
492
  // Enable macro detection
473
493
  enableMacroDetection: true,
474
-
494
+
475
495
  // Set scan timeout
476
496
  timeout: 30000,
477
-
497
+
478
498
  // Custom ClamAV configuration
479
499
  clamscan: {
480
500
  preference: 'clamdscan',
@@ -954,7 +974,7 @@ The `scan()` method returns a comprehensive result object:
954
974
  // Overall spam classification
955
975
  isSpam: boolean,
956
976
  message: string, // 'Ham' or 'Spam: <reasons>'
957
-
977
+
958
978
  // Detection results
959
979
  results: {
960
980
  // Classification details
@@ -962,7 +982,7 @@ The `scan()` method returns a comprehensive result object:
962
982
  category: 'spam' | 'ham',
963
983
  probability: number
964
984
  },
965
-
985
+
966
986
  // Phishing detection
967
987
  phishing: [
968
988
  {
@@ -971,7 +991,7 @@ The `scan()` method returns a comprehensive result object:
971
991
  message: string
972
992
  }
973
993
  ],
974
-
994
+
975
995
  // Executable detection
976
996
  executables: [
977
997
  {
@@ -981,7 +1001,7 @@ The `scan()` method returns a comprehensive result object:
981
1001
  risk: 'high' | 'medium' | 'low'
982
1002
  }
983
1003
  ],
984
-
1004
+
985
1005
  // Macro detection
986
1006
  macros: [
987
1007
  {
@@ -989,10 +1009,10 @@ The `scan()` method returns a comprehensive result object:
989
1009
  message: string
990
1010
  }
991
1011
  ],
992
-
1012
+
993
1013
  // Arbitrary results (custom detections)
994
1014
  arbitrary: [],
995
-
1015
+
996
1016
  // Virus scanning
997
1017
  viruses: [
998
1018
  {
@@ -1001,7 +1021,7 @@ The `scan()` method returns a comprehensive result object:
1001
1021
  type: 'virus'
1002
1022
  }
1003
1023
  ],
1004
-
1024
+
1005
1025
  // Pattern recognition
1006
1026
  patterns: {
1007
1027
  credit_cards: number,
@@ -1013,10 +1033,10 @@ The `scan()` method returns a comprehensive result object:
1013
1033
  dates: number,
1014
1034
  file_paths: number
1015
1035
  },
1016
-
1036
+
1017
1037
  // IDN homograph attack detection
1018
1038
  idnHomographAttack: [],
1019
-
1039
+
1020
1040
  // Toxicity detection (array of results)
1021
1041
  toxicity: [
1022
1042
  {
@@ -1026,7 +1046,7 @@ The `scan()` method returns a comprehensive result object:
1026
1046
  description: string
1027
1047
  }
1028
1048
  ],
1029
-
1049
+
1030
1050
  // NSFW detection (array of results)
1031
1051
  nsfw: [
1032
1052
  {
@@ -1038,13 +1058,13 @@ The `scan()` method returns a comprehensive result object:
1038
1058
  }
1039
1059
  ]
1040
1060
  },
1041
-
1061
+
1042
1062
  // All URLs extracted from email
1043
1063
  links: string[],
1044
-
1064
+
1045
1065
  // Tokens extracted from email
1046
1066
  tokens: string[],
1047
-
1067
+
1048
1068
  // Email metadata
1049
1069
  mail: {
1050
1070
  from: object,
@@ -1055,7 +1075,7 @@ The `scan()` method returns a comprehensive result object:
1055
1075
  attachments: object[],
1056
1076
  headers: object
1057
1077
  },
1058
-
1078
+
1059
1079
  // Performance metrics (if enabled)
1060
1080
  metrics: {
1061
1081
  totalTime: number, // milliseconds
@@ -1178,6 +1198,508 @@ const scanner = new SpamScanner({
1178
1198
  ---
1179
1199
 
1180
1200
 
1201
+ ## CLI (Command Line Interface)
1202
+
1203
+ SpamScanner provides a command-line interface for scanning emails directly from the terminal or integrating with mail servers.
1204
+
1205
+ ### CLI Installation
1206
+
1207
+ SpamScanner can be installed via npm or as a standalone binary. The standalone binary includes Node.js and all dependencies, so no additional runtime is required.
1208
+
1209
+ #### Install via npm (requires Node.js)
1210
+
1211
+ ```bash
1212
+ # Install globally
1213
+ npm install -g spamscanner
1214
+
1215
+ # Or use npx without installing
1216
+ npx spamscanner --help
1217
+ ```
1218
+
1219
+ #### Install Standalone Binary
1220
+
1221
+ ##### macOS
1222
+
1223
+ ```bash
1224
+ # Using curl (Intel or Apple Silicon - auto-detected)
1225
+ curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-darwin-$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/arm64/' | sed 's/arm64/arm64/') -o /usr/local/bin/spamscanner
1226
+ chmod +x /usr/local/bin/spamscanner
1227
+
1228
+ # Or download manually for Intel Mac
1229
+ curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-darwin-x64 -o /usr/local/bin/spamscanner
1230
+ chmod +x /usr/local/bin/spamscanner
1231
+
1232
+ # Or download manually for Apple Silicon (M1/M2/M3)
1233
+ curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-darwin-arm64 -o /usr/local/bin/spamscanner
1234
+ chmod +x /usr/local/bin/spamscanner
1235
+ ```
1236
+
1237
+ ##### Linux
1238
+
1239
+ ```bash
1240
+ # Download and install to /usr/local/bin
1241
+ sudo curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-linux-x64 -o /usr/local/bin/spamscanner
1242
+ sudo chmod +x /usr/local/bin/spamscanner
1243
+
1244
+ # Or install to user directory (no sudo required)
1245
+ mkdir -p ~/.local/bin
1246
+ curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-linux-x64 -o ~/.local/bin/spamscanner
1247
+ chmod +x ~/.local/bin/spamscanner
1248
+ # Add to PATH if not already: export PATH="$HOME/.local/bin:$PATH"
1249
+ ```
1250
+
1251
+ ##### Windows
1252
+
1253
+ ```powershell
1254
+ # Using PowerShell (run as Administrator)
1255
+ Invoke-WebRequest -Uri "https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-win-x64.exe" -OutFile "C:\Program Files\spamscanner\spamscanner.exe"
1256
+ # Add to PATH via System Properties > Environment Variables
1257
+
1258
+ # Or download to current directory
1259
+ Invoke-WebRequest -Uri "https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-win-x64.exe" -OutFile ".\spamscanner.exe"
1260
+ ```
1261
+
1262
+ ##### Verify Installation
1263
+
1264
+ ```bash
1265
+ # Check version
1266
+ spamscanner version
1267
+
1268
+ # Check for updates
1269
+ spamscanner update
1270
+ ```
1271
+
1272
+ #### Automatic Updates
1273
+
1274
+ SpamScanner CLI automatically checks for updates once every 24 hours and displays a notification if a new version is available. You can also manually check for updates:
1275
+
1276
+ ```bash
1277
+ # Check for updates
1278
+ spamscanner update
1279
+
1280
+ # Disable automatic update checks
1281
+ spamscanner scan email.eml --no-update-check
1282
+ ```
1283
+
1284
+ To update to the latest version, simply re-run the installation command for your platform or use npm:
1285
+
1286
+ ```bash
1287
+ # Update via npm
1288
+ npm update -g spamscanner
1289
+
1290
+ # Or re-download the binary (macOS/Linux)
1291
+ curl -fsSL https://github.com/spamscanner/spamscanner/releases/latest/download/spamscanner-$(uname -s | tr '[:upper:]' '[:lower:]')-$(uname -m | sed 's/x86_64/x64/' | sed 's/aarch64/arm64/') -o /usr/local/bin/spamscanner
1292
+ chmod +x /usr/local/bin/spamscanner
1293
+ ```
1294
+
1295
+ ### Commands
1296
+
1297
+ | Command | Description |
1298
+ | ------------------------- | --------------------- |
1299
+ | `spamscanner scan <file>` | Scan an email file |
1300
+ | `spamscanner scan -` | Scan email from stdin |
1301
+ | `spamscanner server` | Start TCP server mode |
1302
+ | `spamscanner help` | Show help message |
1303
+ | `spamscanner version` | Show version number |
1304
+ | `spamscanner update` | Check for updates |
1305
+
1306
+ #### General Options
1307
+
1308
+ | Option | Description |
1309
+ | ------------------- | --------------------------------------------- |
1310
+ | `-h, --help` | Show help |
1311
+ | `-v, --version` | Show version |
1312
+ | `-j, --json` | Output results as JSON |
1313
+ | `--verbose` | Show detailed output |
1314
+ | `--debug` | Enable debug mode |
1315
+ | `--timeout <ms>` | Scan timeout in milliseconds (default: 30000) |
1316
+ | `--no-update-check` | Disable automatic update check |
1317
+
1318
+ #### Spam Detection Options
1319
+
1320
+ SpamScanner calculates a spam score based on multiple detection methods. You can configure which checks are included and customize the score weights.
1321
+
1322
+ | Option | Description |
1323
+ | --------------------- | ------------------------------------------------- |
1324
+ | `--threshold <score>` | Spam score threshold (default: 5.0) |
1325
+ | `--check-classifier` | Include Bayesian classifier in scoring (default) |
1326
+ | `--check-phishing` | Include phishing detection in scoring (default) |
1327
+ | `--check-executables` | Include executable detection in scoring (default) |
1328
+ | `--check-macros` | Include macro detection in scoring (default) |
1329
+ | `--check-virus` | Include virus detection in scoring (default) |
1330
+ | `--check-nsfw` | Include NSFW detection in scoring (disabled) |
1331
+ | `--check-toxicity` | Include toxicity detection in scoring (disabled) |
1332
+ | `--no-classifier` | Disable Bayesian classifier scoring |
1333
+ | `--no-phishing` | Disable phishing scoring |
1334
+ | `--no-executables` | Disable executable scoring |
1335
+ | `--no-macros` | Disable macro scoring |
1336
+ | `--no-virus` | Disable virus scoring |
1337
+
1338
+ #### Score Weights
1339
+
1340
+ Customize how much each detection type contributes to the total spam score:
1341
+
1342
+ | Option | Description |
1343
+ | ------------------------ | ------------------------------------------- |
1344
+ | `--score-classifier <n>` | Classifier spam score weight (default: 5.0) |
1345
+ | `--score-phishing <n>` | Phishing score per issue (default: 5.0) |
1346
+ | `--score-executable <n>` | Executable score per file (default: 10.0) |
1347
+ | `--score-macro <n>` | Macro score per detection (default: 5.0) |
1348
+ | `--score-virus <n>` | Virus score per detection (default: 100.0) |
1349
+ | `--score-nsfw <n>` | NSFW score per detection (default: 3.0) |
1350
+ | `--score-toxicity <n>` | Toxicity score per detection (default: 3.0) |
1351
+
1352
+ #### Header Options
1353
+
1354
+ For mail server integration, SpamScanner can add X-Spam headers to emails (similar to [SpamAssassin](https://github.com/apache/spamassassin) and [Stalwart](https://github.com/stalwartlabs/stalwart)):
1355
+
1356
+ | Option | Description |
1357
+ | --------------------- | ------------------------------------------ |
1358
+ | `--add-headers` | Add X-Spam-* headers to output |
1359
+ | `--prepend-subject` | Prepend [SPAM] to subject if spam detected |
1360
+ | `--subject-tag <tag>` | Custom subject tag (default: [SPAM]) |
1361
+
1362
+ **X-Spam Headers Added:**
1363
+
1364
+ | Header | Description |
1365
+ | --------------- | -------------------------------------------------------------------- |
1366
+ | `X-Spam-Status` | `Yes/No, score=X.X required=Y.Y tests=TEST1,TEST2,... version=X.X.X` |
1367
+ | `X-Spam-Score` | Numeric spam score (e.g., `7.5`) |
1368
+ | `X-Spam-Flag` | `YES` or `NO` |
1369
+ | `X-Spam-Tests` | Comma-separated list of triggered tests |
1370
+
1371
+ #### Scanner Configuration Options
1372
+
1373
+ These options configure the underlying SpamScanner engine:
1374
+
1375
+ | Option | Description |
1376
+ | -------------------------- | ------------------------------------------------------- |
1377
+ | `--languages <list>` | Comma-separated language codes (default: all languages) |
1378
+ | `--mixed-language` | Enable mixed language detection in emails |
1379
+ | `--no-macro-detection` | Disable macro detection in attachments |
1380
+ | `--no-pattern-recognition` | Disable advanced pattern recognition |
1381
+ | `--strict-idn` | Enable strict IDN/homograph detection |
1382
+ | `--nsfw-threshold <n>` | NSFW detection threshold 0.0-1.0 (default: 0.6) |
1383
+ | `--toxicity-threshold <n>` | Toxicity detection threshold 0.0-1.0 (default: 0.7) |
1384
+ | `--clamscan-path <path>` | Path to clamscan binary (default: /usr/bin/clamscan) |
1385
+ | `--clamdscan-path <path>` | Path to clamdscan binary (default: /usr/bin/clamdscan) |
1386
+
1387
+ ##### Supported Languages
1388
+
1389
+ Use ISO 639-1 language codes with the `--languages` option. Pass an empty string or `all` to enable all languages (default).
1390
+
1391
+ | Code | Language | Code | Language | Code | Language |
1392
+ | ---- | --------------- | ---- | ---------- | ---- | ---------- |
1393
+ | `en` | English | `fr` | French | `es` | Spanish |
1394
+ | `de` | German | `it` | Italian | `pt` | Portuguese |
1395
+ | `ru` | Russian | `ja` | Japanese | `ko` | Korean |
1396
+ | `zh` | Chinese | `ar` | Arabic | `hi` | Hindi |
1397
+ | `bn` | Bengali | `ur` | Urdu | `tr` | Turkish |
1398
+ | `pl` | Polish | `nl` | Dutch | `sv` | Swedish |
1399
+ | `no` | Norwegian | `da` | Danish | `fi` | Finnish |
1400
+ | `hu` | Hungarian | `cs` | Czech | `sk` | Slovak |
1401
+ | `sl` | Slovenian | `hr` | Croatian | `sr` | Serbian |
1402
+ | `bg` | Bulgarian | `ro` | Romanian | `el` | Greek |
1403
+ | `he` | Hebrew | `th` | Thai | `vi` | Vietnamese |
1404
+ | `id` | Indonesian | `ms` | Malay | `tl` | Tagalog |
1405
+ | `uk` | Ukrainian | `be` | Belarusian | `lt` | Lithuanian |
1406
+ | `lv` | Latvian | `et` | Estonian | `ca` | Catalan |
1407
+ | `eu` | Basque | `gl` | Galician | `ga` | Irish |
1408
+ | `gd` | Scottish Gaelic | `cy` | Welsh | `is` | Icelandic |
1409
+ | `mt` | Maltese | `af` | Afrikaans | `sw` | Swahili |
1410
+ | `am` | Amharic | `ha` | Hausa | `yo` | Yoruba |
1411
+ | `ig` | Igbo | `so` | Somali | `om` | Oromo |
1412
+ | `ti` | Tigrinya | `mg` | Malagasy | `ny` | Chichewa |
1413
+ | `sn` | Shona | `xh` | Xhosa | `zu` | Zulu |
1414
+ | `st` | Southern Sotho | `tn` | Tswana | | |
1415
+
1416
+ #### Server Options
1417
+
1418
+ | Option | Description |
1419
+ | --------------- | ------------------------------------ |
1420
+ | `--port <port>` | TCP server port (default: 7830) |
1421
+ | `--host <host>` | TCP server host (default: 127.0.0.1) |
1422
+
1423
+ ### Exit Codes
1424
+
1425
+ | Code | Meaning |
1426
+ | ---- | ---------------- |
1427
+ | `0` | Clean (not spam) |
1428
+ | `1` | Spam detected |
1429
+ | `2` | Error occurred |
1430
+
1431
+ ### CLI Examples
1432
+
1433
+ ```bash
1434
+ # Scan a file
1435
+ spamscanner scan email.eml
1436
+
1437
+ # Scan from stdin (for Postfix integration)
1438
+ cat email.eml | spamscanner scan -
1439
+
1440
+ # Scan with JSON output (includes score and tests)
1441
+ spamscanner scan email.eml --json
1442
+
1443
+ # Scan with verbose output
1444
+ spamscanner scan email.eml --verbose
1445
+
1446
+ # Scan with custom spam threshold
1447
+ spamscanner scan email.eml --threshold 3.0
1448
+
1449
+ # Scan with only classifier and phishing checks
1450
+ spamscanner scan email.eml --no-executables --no-macros --no-virus
1451
+
1452
+ # Scan and add X-Spam headers (for mail server integration)
1453
+ spamscanner scan email.eml --add-headers
1454
+
1455
+ # Scan, add headers, and prepend [SPAM] to subject
1456
+ spamscanner scan email.eml --add-headers --prepend-subject
1457
+
1458
+ # Scan with custom subject tag
1459
+ spamscanner scan email.eml --add-headers --prepend-subject --subject-tag "[JUNK]"
1460
+
1461
+ # Enable NSFW and toxicity checks with custom weights
1462
+ spamscanner scan email.eml --check-nsfw --check-toxicity --score-nsfw 5.0
1463
+
1464
+ # Start TCP server on custom port
1465
+ spamscanner server --port 8080
1466
+
1467
+ # Start TCP server with custom threshold
1468
+ spamscanner server --port 8080 --threshold 3.0
1469
+
1470
+ # Scan with specific language support (English, Spanish, French only)
1471
+ spamscanner scan email.eml --languages en,es,fr
1472
+
1473
+ # Scan with mixed language detection enabled
1474
+ spamscanner scan email.eml --mixed-language
1475
+
1476
+ # Scan with strict IDN/homograph detection
1477
+ spamscanner scan email.eml --strict-idn
1478
+
1479
+ # Scan with custom NSFW threshold (more sensitive)
1480
+ spamscanner scan email.eml --check-nsfw --nsfw-threshold 0.3
1481
+
1482
+ # Scan with custom ClamAV paths
1483
+ spamscanner scan email.eml --clamscan-path /opt/clamav/bin/clamscan
1484
+ ```
1485
+
1486
+ #### Example JSON Output
1487
+
1488
+ ```json
1489
+ {
1490
+ "isSpam": true,
1491
+ "score": 7.5,
1492
+ "threshold": 5.0,
1493
+ "tests": ["BAYES_SPAM(5.0)", "PHISHING_DETECTED(2.5)"],
1494
+ "message": "Spam",
1495
+ "results": {
1496
+ "classification": { "category": "spam", "probability": 0.95 },
1497
+ "phishing": [{ "type": "suspicious_link", "url": "http://example.com" }]
1498
+ },
1499
+ "headers": {
1500
+ "X-Spam-Status": "Yes, score=7.5 required=5.0 tests=BAYES_SPAM(5.0),PHISHING_DETECTED(2.5) version=6.0.1",
1501
+ "X-Spam-Score": "7.5",
1502
+ "X-Spam-Flag": "YES",
1503
+ "X-Spam-Tests": "BAYES_SPAM(5.0), PHISHING_DETECTED(2.5)"
1504
+ }
1505
+ }
1506
+ ```
1507
+
1508
+ ---
1509
+
1510
+
1511
+ ## ARF (Abuse Reporting Format)
1512
+
1513
+ SpamScanner includes a native [ARF (Abuse Reporting Format)](https://www.rfc-editor.org/rfc/rfc5965.html) parser for handling email feedback reports from ISPs and email providers.
1514
+
1515
+ ### Parsing ARF Reports
1516
+
1517
+ ```js
1518
+ import {ArfParser} from 'spamscanner/arf';
1519
+ import fs from 'node:fs';
1520
+
1521
+ // Read an ARF report email
1522
+ const arfEmail = fs.readFileSync('feedback_report.eml');
1523
+
1524
+ // Parse the ARF report
1525
+ const report = await ArfParser.parse(arfEmail);
1526
+
1527
+ console.log('Feedback Type:', report.feedbackType);
1528
+ console.log('Source IP:', report.sourceIp);
1529
+ console.log('Original Sender:', report.originalMailFrom);
1530
+ console.log('Original Recipients:', report.originalRcptTo);
1531
+ ```
1532
+
1533
+ #### Safe Parsing
1534
+
1535
+ ```js
1536
+ // Use tryParse for safe parsing (returns null if not ARF)
1537
+ const report = await ArfParser.tryParse(emailContent);
1538
+
1539
+ if (report) {
1540
+ console.log('ARF report detected:', report.feedbackType);
1541
+ } else {
1542
+ console.log('Not an ARF report');
1543
+ }
1544
+ ```
1545
+
1546
+ ### Creating ARF Reports
1547
+
1548
+ ```js
1549
+ import {ArfParser} from 'spamscanner/arf';
1550
+
1551
+ const arfMessage = ArfParser.create({
1552
+ feedbackType: 'abuse',
1553
+ userAgent: 'MyMailServer/1.0',
1554
+ from: 'abuse@yourdomain.com',
1555
+ to: 'abuse@theirisp.com',
1556
+ originalMessage: originalEmailContent,
1557
+ humanReadable: 'This email was reported as spam by our users.',
1558
+ sourceIp: '192.168.1.100',
1559
+ originalMailFrom: 'spammer@example.com',
1560
+ originalRcptTo: ['victim@yourdomain.com'],
1561
+ arrivalDate: new Date(),
1562
+ reportingMta: 'mail.yourdomain.com',
1563
+ });
1564
+
1565
+ // Send arfMessage to the abuse address
1566
+ ```
1567
+
1568
+ ### ARF Result Object
1569
+
1570
+ | Property | Type | Description |
1571
+ | ------------------ | ---------- | ----------------------------------------------------------------------------- |
1572
+ | `isArf` | `boolean` | Whether this is a valid ARF message |
1573
+ | `feedbackType` | `string` | Type: `abuse`, `fraud`, `virus`, `other`, `not-spam`, `auth-failure`, `dmarc` |
1574
+ | `userAgent` | `string` | User agent that generated the report |
1575
+ | `version` | `string` | ARF version (usually "1") |
1576
+ | `sourceIp` | `string` | Source IP of the original message |
1577
+ | `originalMailFrom` | `string` | Original MAIL FROM address |
1578
+ | `originalRcptTo` | `string[]` | Original RCPT TO addresses |
1579
+ | `arrivalDate` | `Date` | When the original message arrived |
1580
+ | `reportingMta` | `object` | Reporting MTA info (`{type, name}`) |
1581
+ | `incidents` | `number` | Number of incidents reported |
1582
+ | `humanReadable` | `string` | Human-readable description |
1583
+ | `originalMessage` | `string` | The original reported message |
1584
+ | `originalHeaders` | `object` | Parsed headers from original message |
1585
+
1586
+ ---
1587
+
1588
+
1589
+ ## Mail Server Integration
1590
+
1591
+ SpamScanner can be integrated with popular mail servers like [Postfix](https://www.postfix.org/) and [Dovecot](https://www.dovecot.org/) as a content filter.
1592
+
1593
+ ### Postfix Integration
1594
+
1595
+ #### Using Pipe Content Filter
1596
+
1597
+ This is the recommended method for most Postfix setups.
1598
+
1599
+ 1. **Create a dedicated user** (recommended for security):
1600
+
1601
+ ```bash
1602
+ sudo useradd -r -s /bin/false spamscanner
1603
+ ```
1604
+
1605
+ 2. **Edit `/etc/postfix/master.cf`**:
1606
+
1607
+ ```cf
1608
+ # SpamScanner content filter
1609
+ spamscanner unix - n n - - pipe
1610
+ flags=Rq user=spamscanner argv=/usr/local/bin/spamscanner scan -
1611
+ ```
1612
+
1613
+ 3. **Edit `/etc/postfix/main.cf`**:
1614
+
1615
+ ```cf
1616
+ content_filter = spamscanner:dummy
1617
+ ```
1618
+
1619
+ 4. **Reload Postfix**:
1620
+
1621
+ ```bash
1622
+ sudo postfix reload
1623
+ ```
1624
+
1625
+ Postfix will now pipe all incoming emails to SpamScanner. If SpamScanner exits with code 1 (spam), Postfix will reject the message.
1626
+
1627
+ ### Dovecot Integration
1628
+
1629
+ #### Using Sieve and Pipe
1630
+
1631
+ 1. **Enable Pigeonhole Sieve** (ensure `dovecot-pigeonhole` is installed)
1632
+
1633
+ 2. **Create a Sieve script** (`/var/lib/dovecot/sieve/default.sieve`):
1634
+
1635
+ ```sieve
1636
+ require ["vnd.dovecot.pipe"];
1637
+
1638
+ # Scan all incoming mail
1639
+ if header :contains "X-Spam-Flag" "NO" {
1640
+ pipe "/usr/local/bin/spamscanner-sieve-helper";
1641
+ }
1642
+ ```
1643
+
1644
+ 3. **Create a helper script** (`/usr/local/bin/spamscanner-sieve-helper`):
1645
+
1646
+ ```bash
1647
+ #!/bin/bash
1648
+ EMAIL=$(cat)
1649
+ RESULT=$(echo "$EMAIL" | /usr/local/bin/spamscanner scan -)
1650
+ if [[ $? -eq 1 ]]; then
1651
+ echo "X-Spam-Flag: YES" | cat - <(echo "$EMAIL")
1652
+ else
1653
+ echo "$EMAIL"
1654
+ fi
1655
+ ```
1656
+
1657
+ ### TCP Server Mode
1658
+
1659
+ For high-volume environments, run SpamScanner as a persistent TCP server:
1660
+
1661
+ ```bash
1662
+ # Start the server
1663
+ spamscanner server --port 7830 --host 127.0.0.1
1664
+ ```
1665
+
1666
+ #### Systemd Service
1667
+
1668
+ Create `/etc/systemd/system/spamscanner.service`:
1669
+
1670
+ ```ini
1671
+ [Unit]
1672
+ Description=SpamScanner TCP Server
1673
+ After=network.target
1674
+
1675
+ [Service]
1676
+ Type=simple
1677
+ User=spamscanner
1678
+ ExecStart=/usr/local/bin/spamscanner server --port 7830
1679
+ Restart=always
1680
+ RestartSec=5
1681
+
1682
+ [Install]
1683
+ WantedBy=multi-user.target
1684
+ ```
1685
+
1686
+ Enable and start:
1687
+
1688
+ ```bash
1689
+ sudo systemctl enable spamscanner
1690
+ sudo systemctl start spamscanner
1691
+ ```
1692
+
1693
+ #### Client Example
1694
+
1695
+ ```bash
1696
+ # Send email to TCP server and get JSON response
1697
+ cat email.eml | nc localhost 7830
1698
+ ```
1699
+
1700
+ ---
1701
+
1702
+
1181
1703
  ## Performance
1182
1704
 
1183
1705
  ### Benchmarks
@@ -1276,3 +1798,8 @@ npm run test-coverage
1276
1798
  ---
1277
1799
 
1278
1800
  > Made with ❤️ by the [Forward Email](https://forwardemail.net) team
1801
+
1802
+
1803
+ ##
1804
+
1805
+ <a href="#"><img src="https://raw.githubusercontent.com/spamscanner/spamscanner/master/media/footer.png" alt="#" /></a>