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 +54 -42
- package/dist/cjs/index.js +14 -3
- package/dist/cjs/index.js.map +3 -3
- package/dist/esm/index.js +14 -3
- package/dist/esm/index.js.map +2 -2
- package/dist/types/enhanced-idn-detector.d.ts +236 -0
- package/dist/types/index.d.ts +856 -0
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
>
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
|
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));
|