spamscanner 6.0.0 → 6.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/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
 
@@ -282,27 +289,27 @@ graph TB
282
289
  C --> D[Language Detection]
283
290
  D --> E[Tokenization]
284
291
  E --> F[Naive Bayes Classification]
285
-
292
+
286
293
  B --> G[Phishing Detection]
287
294
  G --> G1[IDN Homograph Check]
288
295
  G --> G2[Confusables Analysis]
289
296
  G --> G3[URL Analysis]
290
-
297
+
291
298
  B --> H[Attachment Scanning]
292
299
  H --> H1[Virus Scan]
293
300
  H --> H2[Executable Check]
294
301
  H --> H3[Macro Detection]
295
302
  H --> H4[NSFW Detection]
296
-
303
+
297
304
  B --> I[Content Analysis]
298
305
  I --> I1[Toxicity Detection]
299
306
  I --> I2[Pattern Recognition]
300
-
307
+
301
308
  F --> J[Result Aggregation]
302
309
  G --> J
303
310
  H --> J
304
311
  I --> J
305
-
312
+
306
313
  J --> K{Is Spam?}
307
314
  K -->|Yes| L[Spam Result]
308
315
  K -->|No| M[Ham Result]
@@ -317,12 +324,12 @@ sequenceDiagram
317
324
  participant Classifier
318
325
  participant ClamAV
319
326
  participant TensorFlow
320
-
327
+
321
328
  Client->>Scanner: scan(email)
322
329
  Scanner->>Scanner: Parse Email
323
330
  Scanner->>Scanner: Extract URLs
324
331
  Scanner->>Scanner: Detect Language
325
-
332
+
326
333
  par Parallel Detection
327
334
  Scanner->>Classifier: Classify Tokens
328
335
  Scanner->>ClamAV: Scan Attachments
@@ -331,7 +338,7 @@ sequenceDiagram
331
338
  Scanner->>Scanner: Check Phishing
332
339
  Scanner->>Scanner: Check Macros
333
340
  end
334
-
341
+
335
342
  Scanner->>Scanner: Aggregate Results
336
343
  Scanner->>Client: Return Result
337
344
  ```
@@ -344,20 +351,20 @@ graph LR
344
351
  A --> C[Classifiers]
345
352
  A --> D[Detectors]
346
353
  A --> E[Analyzers]
347
-
354
+
348
355
  B --> B1[Email Parser]
349
356
  B --> B2[Tokenizer]
350
357
  B --> B3[Preprocessor]
351
-
358
+
352
359
  C --> C1[Naive Bayes]
353
360
  C --> C2[TensorFlow NSFW]
354
361
  C --> C3[TensorFlow Toxicity]
355
-
362
+
356
363
  D --> D1[Phishing Detector]
357
364
  D --> D2[Virus Scanner]
358
365
  D --> D3[Macro Detector]
359
366
  D --> D4[Executable Detector]
360
-
367
+
361
368
  E --> E1[Language Analyzer]
362
369
  E --> E2[URL Analyzer]
363
370
  E --> E3[Pattern Analyzer]
@@ -465,16 +472,16 @@ import SpamScanner from 'spamscanner';
465
472
  const scanner = new SpamScanner({
466
473
  // Enable performance metrics
467
474
  enablePerformanceMetrics: true,
468
-
475
+
469
476
  // Filter to supported languages
470
477
  supportedLanguages: ['en', 'es', 'fr', 'de'],
471
-
478
+
472
479
  // Enable macro detection
473
480
  enableMacroDetection: true,
474
-
481
+
475
482
  // Set scan timeout
476
483
  timeout: 30000,
477
-
484
+
478
485
  // Custom ClamAV configuration
479
486
  clamscan: {
480
487
  preference: 'clamdscan',
@@ -954,7 +961,7 @@ The `scan()` method returns a comprehensive result object:
954
961
  // Overall spam classification
955
962
  isSpam: boolean,
956
963
  message: string, // 'Ham' or 'Spam: <reasons>'
957
-
964
+
958
965
  // Detection results
959
966
  results: {
960
967
  // Classification details
@@ -962,7 +969,7 @@ The `scan()` method returns a comprehensive result object:
962
969
  category: 'spam' | 'ham',
963
970
  probability: number
964
971
  },
965
-
972
+
966
973
  // Phishing detection
967
974
  phishing: [
968
975
  {
@@ -971,7 +978,7 @@ The `scan()` method returns a comprehensive result object:
971
978
  message: string
972
979
  }
973
980
  ],
974
-
981
+
975
982
  // Executable detection
976
983
  executables: [
977
984
  {
@@ -981,7 +988,7 @@ The `scan()` method returns a comprehensive result object:
981
988
  risk: 'high' | 'medium' | 'low'
982
989
  }
983
990
  ],
984
-
991
+
985
992
  // Macro detection
986
993
  macros: [
987
994
  {
@@ -989,10 +996,10 @@ The `scan()` method returns a comprehensive result object:
989
996
  message: string
990
997
  }
991
998
  ],
992
-
999
+
993
1000
  // Arbitrary results (custom detections)
994
1001
  arbitrary: [],
995
-
1002
+
996
1003
  // Virus scanning
997
1004
  viruses: [
998
1005
  {
@@ -1001,7 +1008,7 @@ The `scan()` method returns a comprehensive result object:
1001
1008
  type: 'virus'
1002
1009
  }
1003
1010
  ],
1004
-
1011
+
1005
1012
  // Pattern recognition
1006
1013
  patterns: {
1007
1014
  credit_cards: number,
@@ -1013,10 +1020,10 @@ The `scan()` method returns a comprehensive result object:
1013
1020
  dates: number,
1014
1021
  file_paths: number
1015
1022
  },
1016
-
1023
+
1017
1024
  // IDN homograph attack detection
1018
1025
  idnHomographAttack: [],
1019
-
1026
+
1020
1027
  // Toxicity detection (array of results)
1021
1028
  toxicity: [
1022
1029
  {
@@ -1026,7 +1033,7 @@ The `scan()` method returns a comprehensive result object:
1026
1033
  description: string
1027
1034
  }
1028
1035
  ],
1029
-
1036
+
1030
1037
  // NSFW detection (array of results)
1031
1038
  nsfw: [
1032
1039
  {
@@ -1038,13 +1045,13 @@ The `scan()` method returns a comprehensive result object:
1038
1045
  }
1039
1046
  ]
1040
1047
  },
1041
-
1048
+
1042
1049
  // All URLs extracted from email
1043
1050
  links: string[],
1044
-
1051
+
1045
1052
  // Tokens extracted from email
1046
1053
  tokens: string[],
1047
-
1054
+
1048
1055
  // Email metadata
1049
1056
  mail: {
1050
1057
  from: object,
@@ -1055,7 +1062,7 @@ The `scan()` method returns a comprehensive result object:
1055
1062
  attachments: object[],
1056
1063
  headers: object
1057
1064
  },
1058
-
1065
+
1059
1066
  // Performance metrics (if enabled)
1060
1067
  metrics: {
1061
1068
  totalTime: number, // milliseconds
@@ -1276,3 +1283,8 @@ npm run test-coverage
1276
1283
  ---
1277
1284
 
1278
1285
  > Made with ❤️ by the [Forward Email](https://forwardemail.net) team
1286
+
1287
+
1288
+ ##
1289
+
1290
+ <a href="#"><img src="https://raw.githubusercontent.com/spamscanner/spamscanner/master/media/footer.png" alt="#" /></a>
package/dist/cjs/index.js CHANGED
@@ -582,9 +582,20 @@ var import_url_regex_safe = __toESM(require("url-regex-safe"), 1);
582
582
  var import_mailparser = require("mailparser");
583
583
  var import_file_type = require("file-type");
584
584
  var import_meta = {};
585
- var __filename = (0, import_node_url.fileURLToPath)(import_meta.url);
586
- var __dirname = import_node_path.default.dirname(__filename);
587
- var executablesData = JSON.parse(import_node_fs3.default.readFileSync(import_node_path.default.join(__dirname, "..", "executables.json"), "utf8"));
585
+ var __filename = import_meta.url ? (0, import_node_url.fileURLToPath)(import_meta.url) : "";
586
+ var __dirname = __filename ? import_node_path.default.dirname(__filename) : import_node_process.default.cwd();
587
+ var findPackageRoot = (startDir) => {
588
+ let dir = startDir;
589
+ while (dir !== import_node_path.default.dirname(dir)) {
590
+ if (import_node_fs3.default.existsSync(import_node_path.default.join(dir, "package.json"))) {
591
+ return dir;
592
+ }
593
+ dir = import_node_path.default.dirname(dir);
594
+ }
595
+ return startDir;
596
+ };
597
+ var packageRoot = findPackageRoot(__dirname);
598
+ var executablesData = JSON.parse(import_node_fs3.default.readFileSync(import_node_path.default.join(packageRoot, "executables.json"), "utf8"));
588
599
  var EXECUTABLES = new Set(executablesData);
589
600
  var getReplacements = async () => {
590
601
  const { default: replacements2 } = await Promise.resolve().then(() => (init_replacements(), replacements_exports));