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.
@@ -0,0 +1,959 @@
1
+ import type {ParsedMail, Attachment} from 'mailparser';
2
+ import type {AuthResult, AuthOptions, AuthScoreWeights, AuthScoreResult} from './auth.d.ts';
3
+ import type {ReputationResult, ReputationOptions} from './reputation.d.ts';
4
+ import type {SessionInfo, GetAttributesOptions, ExtractAttributesResult} from './get-attributes.d.ts';
5
+ import type {ArbitraryResult, ArbitraryOptions} from './is-arbitrary.d.ts';
6
+
7
+ // Re-export auth and reputation types
8
+ export type {AuthResult, AuthOptions, AuthScoreWeights, AuthScoreResult} from './auth.d.ts';
9
+ export type {ReputationResult, ReputationOptions} from './reputation.d.ts';
10
+ export type {SessionInfo, GetAttributesOptions, ExtractAttributesResult} from './get-attributes.d.ts';
11
+ export type {ArbitraryResult, ArbitraryOptions} from './is-arbitrary.d.ts';
12
+
13
+ /**
14
+ * ClamScan configuration options
15
+ */
16
+ export type ClamScanConfig = {
17
+ /** Remove infected files automatically */
18
+ removeInfected?: boolean;
19
+ /** Quarantine infected files */
20
+ quarantineInfected?: boolean;
21
+ /** Path to scan log file */
22
+ scanLog?: string | undefined;
23
+ /** Enable debug mode for ClamScan */
24
+ debugMode?: boolean;
25
+ /** File list to scan */
26
+ fileList?: string | undefined;
27
+ /** Scan directories recursively */
28
+ scanRecursively?: boolean;
29
+ /** Path to clamscan binary */
30
+ clamscanPath?: string;
31
+ /** Path to clamdscan binary */
32
+ clamdscanPath?: string;
33
+ /** Preferred scanner to use */
34
+ preference?: 'clamscan' | 'clamdscan';
35
+ };
36
+
37
+ /**
38
+ * SpamScanner configuration options
39
+ */
40
+ export type SpamScannerConfig = {
41
+ /** Enable macro detection in documents */
42
+ enableMacroDetection?: boolean;
43
+ /** Enable performance metrics collection */
44
+ enablePerformanceMetrics?: boolean;
45
+ /** Timeout for operations in milliseconds */
46
+ timeout?: number;
47
+ /** List of supported languages for detection */
48
+ supportedLanguages?: string[];
49
+ /** Enable mixed language detection */
50
+ enableMixedLanguageDetection?: boolean;
51
+ /** Enable advanced pattern recognition */
52
+ enableAdvancedPatternRecognition?: boolean;
53
+ /** Enable debug mode */
54
+ debug?: boolean;
55
+ /** Logger instance */
56
+ logger?: Console | {
57
+ log: (...args: unknown[]) => void;
58
+ error: (...args: unknown[]) => void;
59
+ warn: (...args: unknown[]) => void;
60
+ info: (...args: unknown[]) => void;
61
+ debug: (...args: unknown[]) => void;
62
+ };
63
+ /** ClamScan configuration */
64
+ clamscan?: ClamScanConfig;
65
+ /** Pre-trained classifier data */
66
+ classifier?: Record<string, unknown> | undefined;
67
+ /** Replacement word mappings */
68
+ replacements?: Map<string, string> | Record<string, string> | undefined;
69
+ /** Enable NSFW detection */
70
+ enableNsfwDetection?: boolean;
71
+ /** Enable toxicity detection */
72
+ enableToxicityDetection?: boolean;
73
+ /** Toxicity detection threshold (0-1) */
74
+ toxicityThreshold?: number;
75
+ /** NSFW detection threshold (0-1) */
76
+ nsfwThreshold?: number;
77
+ /** Enable strict IDN detection */
78
+ strictIdnDetection?: boolean;
79
+ /** Enable token hashing */
80
+ hashTokens?: boolean;
81
+ /** Enable email authentication (DKIM/SPF/ARC/DMARC/BIMI) */
82
+ enableAuthentication?: boolean;
83
+ /** Authentication options */
84
+ authOptions?: AuthOptions;
85
+ /** Authentication score weights */
86
+ authScoreWeights?: AuthScoreWeights;
87
+ /** Enable Forward Email reputation checking */
88
+ enableReputation?: boolean;
89
+ /** Reputation API options */
90
+ reputationOptions?: ReputationOptions;
91
+ /** Enable arbitrary spam detection */
92
+ enableArbitraryDetection?: boolean;
93
+ /** Arbitrary spam score threshold */
94
+ arbitraryThreshold?: number;
95
+ };
96
+
97
+ /**
98
+ * Classification result
99
+ */
100
+ export type ClassificationResult = {
101
+ /** Classification category */
102
+ category: 'spam' | 'ham';
103
+ /** Classification probability */
104
+ probability: number;
105
+ };
106
+
107
+ /**
108
+ * Phishing detection result
109
+ */
110
+ export type PhishingResult = {
111
+ /** Type of detection */
112
+ type: 'phishing' | 'suspicious';
113
+ /** The URL that was flagged */
114
+ url: string;
115
+ /** Description of the issue */
116
+ description: string;
117
+ /** Additional details */
118
+ details?: {
119
+ riskFactors?: string[];
120
+ recommendations?: string[];
121
+ confidence?: number;
122
+ };
123
+ };
124
+
125
+ /**
126
+ * Executable detection result
127
+ */
128
+ export type ExecutableResult = {
129
+ /** Type of detection */
130
+ type: 'executable' | 'archive';
131
+ /** Filename of the attachment */
132
+ filename: string;
133
+ /** File extension */
134
+ extension?: string;
135
+ /** Detected file type */
136
+ detectedType?: string;
137
+ /** Description of the issue */
138
+ description: string;
139
+ /** Risk level */
140
+ risk?: 'low' | 'medium' | 'high';
141
+ /** Warning message */
142
+ warning?: string;
143
+ };
144
+
145
+ /**
146
+ * Macro detection result
147
+ */
148
+ export type MacroResult = {
149
+ /** Type of detection */
150
+ type: 'macro';
151
+ /** Subtype of macro */
152
+ subtype: 'vba' | 'powershell' | 'javascript' | 'batch' | 'script' | 'office_document' | 'legacy_office' | 'pdf_javascript';
153
+ /** Filename if from attachment */
154
+ filename?: string;
155
+ /** Description of the issue */
156
+ description: string;
157
+ /** Risk level */
158
+ risk?: 'low' | 'medium' | 'high';
159
+ };
160
+
161
+ /**
162
+ * Arbitrary detection result (e.g., GTUBE, spam patterns)
163
+ */
164
+ export type ArbitraryResult = {
165
+ /** Type of detection */
166
+ type: 'arbitrary';
167
+ /** Subtype of arbitrary detection */
168
+ subtype?: 'gtube' | 'pattern';
169
+ /** Description of the issue */
170
+ description: string;
171
+ /** Arbitrary spam score */
172
+ score?: number;
173
+ /** List of reasons why the message was flagged */
174
+ reasons?: string[];
175
+ };
176
+
177
+ /**
178
+ * Virus detection result
179
+ */
180
+ export type VirusResult = {
181
+ /** Filename of the infected attachment */
182
+ filename: string;
183
+ /** Detected virus names */
184
+ virus: string[];
185
+ /** Type of detection */
186
+ type: 'virus';
187
+ };
188
+
189
+ /**
190
+ * Pattern detection result
191
+ */
192
+ export type PatternResult = {
193
+ /** Type of detection */
194
+ type: 'pattern' | 'file_path';
195
+ /** Subtype of pattern */
196
+ subtype?: string;
197
+ /** Count of matches */
198
+ count?: number;
199
+ /** Detected path */
200
+ path?: string;
201
+ /** Description of the issue */
202
+ description: string;
203
+ };
204
+
205
+ /**
206
+ * IDN Homograph attack detection result
207
+ */
208
+ export type IdnHomographResult = {
209
+ /** Whether an attack was detected */
210
+ detected: boolean;
211
+ /** List of suspicious domains */
212
+ domains: IdnDomainAnalysis[];
213
+ /** Overall risk score (0-1) */
214
+ riskScore: number;
215
+ /** Additional details */
216
+ details: string[];
217
+ };
218
+
219
+ /**
220
+ * IDN domain analysis
221
+ */
222
+ export type IdnDomainAnalysis = {
223
+ /** The domain analyzed */
224
+ domain: string;
225
+ /** Original URL */
226
+ originalUrl: string;
227
+ /** Normalized URL */
228
+ normalizedUrl: string;
229
+ /** Risk score (0-1) */
230
+ riskScore: number;
231
+ /** Risk factors identified */
232
+ riskFactors: string[];
233
+ /** Recommendations */
234
+ recommendations: string[];
235
+ /** Confidence level */
236
+ confidence: number;
237
+ };
238
+
239
+ /**
240
+ * Toxicity detection result
241
+ */
242
+ export type ToxicityResult = {
243
+ /** Type of detection */
244
+ type: 'toxicity';
245
+ /** Toxicity category */
246
+ category: string;
247
+ /** Probability of toxicity */
248
+ probability: number;
249
+ /** Description of the issue */
250
+ description: string;
251
+ };
252
+
253
+ /**
254
+ * NSFW detection result
255
+ */
256
+ export type NsfwResult = {
257
+ /** Type of detection */
258
+ type: 'nsfw';
259
+ /** Filename of the image */
260
+ filename: string;
261
+ /** NSFW category */
262
+ category: 'Porn' | 'Hentai' | 'Sexy' | 'Drawing' | 'Neutral';
263
+ /** Probability of NSFW content */
264
+ probability: number;
265
+ /** Description of the issue */
266
+ description: string;
267
+ };
268
+
269
+ /**
270
+ * All scan results
271
+ */
272
+ /**
273
+ * Extended authentication result with score
274
+ */
275
+ export type AuthenticationResult = AuthResult & {
276
+ /** Authentication score */
277
+ score: AuthScoreResult;
278
+ /** Formatted Authentication-Results header */
279
+ authResultsHeader: string;
280
+ };
281
+
282
+ /**
283
+ * Extended reputation result with details
284
+ */
285
+ export type ExtendedReputationResult = ReputationResult & {
286
+ /** Values that were checked */
287
+ checkedValues: string[];
288
+ /** Detailed results per value */
289
+ details: Record<string, ReputationResult>;
290
+ };
291
+
292
+ /**
293
+ * All scan results
294
+ */
295
+ export type ScanResults = {
296
+ /** Classification result */
297
+ classification: ClassificationResult;
298
+ /** Phishing detection results */
299
+ phishing: PhishingResult[];
300
+ /** Executable detection results */
301
+ executables: ExecutableResult[];
302
+ /** Macro detection results */
303
+ macros: MacroResult[];
304
+ /** Arbitrary pattern results */
305
+ arbitrary: ArbitraryResult[];
306
+ /** Virus detection results */
307
+ viruses: VirusResult[];
308
+ /** Pattern detection results */
309
+ patterns: PatternResult[];
310
+ /** IDN homograph attack results */
311
+ idnHomographAttack: IdnHomographResult;
312
+ /** Toxicity detection results */
313
+ toxicity: ToxicityResult[];
314
+ /** NSFW detection results */
315
+ nsfw: NsfwResult[];
316
+ /** Authentication results (if enabled) */
317
+ authentication?: AuthenticationResult | null;
318
+ /** Reputation results (if enabled) */
319
+ reputation?: ExtendedReputationResult | null;
320
+ };
321
+
322
+ /**
323
+ * Performance metrics
324
+ */
325
+ export type PerformanceMetrics = {
326
+ /** Total processing time in ms */
327
+ totalTime: number;
328
+ /** Classification time in ms */
329
+ classificationTime: number;
330
+ /** Phishing detection time in ms */
331
+ phishingTime: number;
332
+ /** Executable detection time in ms */
333
+ executableTime: number;
334
+ /** Macro detection time in ms */
335
+ macroTime: number;
336
+ /** Virus scan time in ms */
337
+ virusTime: number;
338
+ /** Pattern detection time in ms */
339
+ patternTime: number;
340
+ /** IDN detection time in ms */
341
+ idnTime: number;
342
+ /** Memory usage statistics */
343
+ memoryUsage: NodeJS.MemoryUsage;
344
+ };
345
+
346
+ /**
347
+ * Scanner metrics
348
+ */
349
+ export type ScannerMetrics = {
350
+ /** Total number of scans performed */
351
+ totalScans: number;
352
+ /** Average scan time in ms */
353
+ averageTime: number;
354
+ /** Last scan time in ms */
355
+ lastScanTime: number;
356
+ };
357
+
358
+ /**
359
+ * Scan result
360
+ */
361
+ export type ScanResult = {
362
+ /** Whether the email is spam */
363
+ isSpam: boolean;
364
+ /** Human-readable message */
365
+ message: string;
366
+ /** Detailed results from all detectors */
367
+ results: ScanResults;
368
+ /** Extracted URLs from the email */
369
+ links: string[];
370
+ /** Extracted tokens from the email */
371
+ tokens: string[];
372
+ /** Parsed mail object */
373
+ mail: ParsedMail;
374
+ /** Performance metrics (if enabled) */
375
+ metrics?: PerformanceMetrics;
376
+ };
377
+
378
+ /**
379
+ * Tokens and mail result from source parsing
380
+ */
381
+ export type TokensAndMailResult = {
382
+ /** Extracted tokens */
383
+ tokens: string[];
384
+ /** Parsed mail object */
385
+ mail: ParsedMail;
386
+ };
387
+
388
+ /**
389
+ * Parsed URL result using tldts
390
+ */
391
+ export type ParsedUrl = {
392
+ /** Full domain */
393
+ domain: string | undefined;
394
+ /** Domain without suffix */
395
+ domainWithoutSuffix: string | undefined;
396
+ /** Full hostname */
397
+ hostname: string | undefined;
398
+ /** Public suffix */
399
+ publicSuffix: string | undefined;
400
+ /** Subdomain */
401
+ subdomain: string | undefined;
402
+ /** Whether the hostname is an IP address */
403
+ isIp: boolean;
404
+ /** Whether the domain is ICANN registered */
405
+ isIcann: boolean;
406
+ /** Whether the domain is private */
407
+ isPrivate: boolean;
408
+ };
409
+
410
+ /**
411
+ * Mail object for internal processing
412
+ */
413
+ export type MailObject = {
414
+ /** Plain text content */
415
+ text?: string;
416
+ /** HTML content */
417
+ html?: string;
418
+ /** Email subject */
419
+ subject?: string;
420
+ /** From address */
421
+ from?: Record<string, unknown>;
422
+ /** To addresses */
423
+ to?: unknown[];
424
+ /** Attachments */
425
+ attachments?: Attachment[];
426
+ /** Header lines */
427
+ headerLines?: Array<{line?: string}>;
428
+ /** Headers map */
429
+ headers?: Map<string, unknown> | Record<string, unknown>;
430
+ };
431
+
432
+ /**
433
+ * Source input type for scanning
434
+ */
435
+ export type ScanSource = string | Uint8Array;
436
+
437
+ /**
438
+ * SpamScanner class for email spam detection
439
+ */
440
+ declare class SpamScanner {
441
+ /** Scanner configuration */
442
+ config: SpamScannerConfig & {
443
+ enableMacroDetection: boolean;
444
+ enablePerformanceMetrics: boolean;
445
+ timeout: number;
446
+ supportedLanguages: string[];
447
+ enableMixedLanguageDetection: boolean;
448
+ enableAdvancedPatternRecognition: boolean;
449
+ debug: boolean;
450
+ logger: Console;
451
+ clamscan: ClamScanConfig;
452
+ classifier: Record<string, unknown> | undefined;
453
+ replacements: Map<string, string> | Record<string, string> | undefined;
454
+ };
455
+
456
+ /** Naive Bayes classifier instance */
457
+ classifier: unknown | undefined;
458
+
459
+ /** ClamScan instance */
460
+ clamscan: unknown | undefined;
461
+
462
+ /** Whether the scanner is initialized */
463
+ isInitialized: boolean;
464
+
465
+ /** Replacement word mappings */
466
+ replacements: Map<string, string>;
467
+
468
+ /** Scanner metrics */
469
+ metrics: ScannerMetrics;
470
+
471
+ /**
472
+ * Create a new SpamScanner instance
473
+ * @param options - Configuration options
474
+ */
475
+ constructor(options?: SpamScannerConfig);
476
+
477
+ /**
478
+ * Initialize the classifier
479
+ */
480
+ initializeClassifier(): Promise<void>;
481
+
482
+ /**
483
+ * Initialize replacements
484
+ */
485
+ initializeReplacements(): Promise<void>;
486
+
487
+ /**
488
+ * Initialize regex helpers
489
+ */
490
+ initializeRegex(): void;
491
+
492
+ /**
493
+ * Scan options for per-scan configuration
494
+ */
495
+ scanOptions?: {
496
+ /** Enable authentication for this scan */
497
+ enableAuthentication?: boolean;
498
+ /** Authentication options for this scan */
499
+ authOptions?: AuthOptions;
500
+ /** Enable reputation checking for this scan */
501
+ enableReputation?: boolean;
502
+ /** Reputation options for this scan */
503
+ reputationOptions?: ReputationOptions;
504
+ };
505
+
506
+ /**
507
+ * Scan an email for spam
508
+ * @param source - Email source (string, Uint8Array, or file path)
509
+ * @param scanOptions - Optional per-scan configuration
510
+ * @returns Scan result
511
+ */
512
+ scan(source: ScanSource, scanOptions?: {
513
+ enableAuthentication?: boolean;
514
+ authOptions?: AuthOptions;
515
+ enableReputation?: boolean;
516
+ reputationOptions?: ReputationOptions;
517
+ }): Promise<ScanResult>;
518
+
519
+ /**
520
+ * Get tokens and parsed mail from source
521
+ * @param source - Email source
522
+ * @returns Tokens and mail object
523
+ */
524
+ getTokensAndMailFromSource(source: ScanSource): Promise<TokensAndMailResult>;
525
+
526
+ /**
527
+ * Get classification result for tokens
528
+ * @param tokens - Array of tokens
529
+ * @returns Classification result
530
+ */
531
+ getClassification(tokens: string[]): Promise<ClassificationResult>;
532
+
533
+ /**
534
+ * Get phishing detection results
535
+ * @param mail - Parsed mail object
536
+ * @returns Array of phishing results
537
+ */
538
+ getPhishingResults(mail: MailObject): Promise<PhishingResult[]>;
539
+
540
+ /**
541
+ * Get executable detection results
542
+ * @param mail - Parsed mail object
543
+ * @returns Array of executable results
544
+ */
545
+ getExecutableResults(mail: MailObject): Promise<ExecutableResult[]>;
546
+
547
+ /**
548
+ * Get macro detection results
549
+ * @param mail - Parsed mail object
550
+ * @returns Array of macro results
551
+ */
552
+ getMacroResults(mail: MailObject): Promise<MacroResult[]>;
553
+
554
+ /**
555
+ * Get arbitrary pattern results (e.g., GTUBE)
556
+ * @param mail - Parsed mail object
557
+ * @returns Array of arbitrary results
558
+ */
559
+ getArbitraryResults(mail: MailObject): Promise<ArbitraryResult[]>;
560
+
561
+ /**
562
+ * Get virus scan results
563
+ * @param mail - Parsed mail object
564
+ * @returns Array of virus results
565
+ */
566
+ getVirusResults(mail: MailObject): Promise<VirusResult[]>;
567
+
568
+ /**
569
+ * Get pattern detection results
570
+ * @param mail - Parsed mail object
571
+ * @returns Array of pattern results
572
+ */
573
+ getPatternResults(mail: MailObject): Promise<PatternResult[]>;
574
+
575
+ /**
576
+ * Get file path detection results
577
+ * @param mail - Parsed mail object
578
+ * @returns Array of pattern results
579
+ */
580
+ getFilePathResults(mail: MailObject): Promise<PatternResult[]>;
581
+
582
+ /**
583
+ * Get IDN homograph attack results
584
+ * @param mail - Parsed mail object
585
+ * @returns IDN homograph result
586
+ */
587
+ getIdnHomographResults(mail: MailObject): Promise<IdnHomographResult>;
588
+
589
+ /**
590
+ * Get toxicity detection results
591
+ * @param mail - Parsed mail object
592
+ * @returns Array of toxicity results
593
+ */
594
+ getToxicityResults(mail: MailObject): Promise<ToxicityResult[]>;
595
+
596
+ /**
597
+ * Get NSFW detection results
598
+ * @param mail - Parsed mail object
599
+ * @returns Array of NSFW results
600
+ */
601
+ getNsfwResults(mail: MailObject): Promise<NsfwResult[]>;
602
+
603
+ /**
604
+ * Get tokens from text
605
+ * @param text - Text to tokenize
606
+ * @param locale - Locale code (default: 'en')
607
+ * @param isHtml - Whether the text is HTML
608
+ * @returns Array of tokens
609
+ */
610
+ getTokens(text: string, locale?: string, isHtml?: boolean): Promise<string[]>;
611
+
612
+ /**
613
+ * Preprocess text for analysis
614
+ * @param text - Text to preprocess
615
+ * @returns Preprocessed text
616
+ */
617
+ preprocessText(text: string): Promise<string>;
618
+
619
+ /**
620
+ * Extract URLs from text
621
+ * @param text - Text to extract URLs from
622
+ * @returns Array of URLs
623
+ */
624
+ getUrls(text: string): string[];
625
+
626
+ /**
627
+ * Extract all URLs from mail and source
628
+ * @param mail - Parsed mail object
629
+ * @param originalSource - Original email source
630
+ * @returns Array of URLs
631
+ */
632
+ extractAllUrls(mail: MailObject, originalSource: ScanSource): string[];
633
+
634
+ /**
635
+ * Optimize URL parsing with timeout protection
636
+ * @param url - URL to parse
637
+ * @returns Normalized URL
638
+ */
639
+ optimizeUrlParsing(url: string): Promise<string>;
640
+
641
+ /**
642
+ * Parse URL using tldts
643
+ * @param url - URL to parse
644
+ * @returns Parsed URL result or null
645
+ */
646
+ parseUrlWithTldts(url: string): ParsedUrl | undefined;
647
+
648
+ /**
649
+ * Check if a domain is blocked by Cloudflare
650
+ * @param hostname - Hostname to check
651
+ * @returns Whether the domain is blocked
652
+ */
653
+ isCloudflareBlocked(hostname: string): Promise<boolean>;
654
+
655
+ /**
656
+ * Detect language using hybrid approach
657
+ * @param text - Text to analyze
658
+ * @returns Detected language code
659
+ */
660
+ detectLanguageHybrid(text: string): Promise<string>;
661
+
662
+ /**
663
+ * Parse and normalize locale code
664
+ * @param locale - Locale code to parse
665
+ * @returns Normalized locale code
666
+ */
667
+ parseLocale(locale: string): string;
668
+
669
+ /**
670
+ * Normalize language code from 3-letter to 2-letter format
671
+ * @param code - Language code to normalize
672
+ * @returns Normalized 2-letter language code
673
+ */
674
+ normalizeLanguageCode(code: string): string;
675
+
676
+ /**
677
+ * Validate short text language detection
678
+ * @param text - Text that was analyzed
679
+ * @param detectedLang - Detected language code
680
+ * @returns Whether the detection is valid
681
+ */
682
+ isValidShortTextDetection(text: string, detectedLang: string): boolean;
683
+
684
+ /**
685
+ * Check if a path is a valid file path
686
+ * @param path - Path to validate
687
+ * @returns Whether the path is valid
688
+ */
689
+ isValidFilePath(path: string): boolean;
690
+
691
+ /**
692
+ * Get IDN detector instance
693
+ * @returns IDN detector or null
694
+ */
695
+ getIdnDetector(): Promise<EnhancedIdnDetector | undefined>;
696
+
697
+ /**
698
+ * Get authentication results using mailauth
699
+ * @param source - Email source
700
+ * @param mail - Parsed mail object
701
+ * @param options - Authentication options
702
+ * @returns Authentication result or null
703
+ */
704
+ getAuthenticationResults(
705
+ source: ScanSource,
706
+ mail: MailObject,
707
+ options?: AuthOptions
708
+ ): Promise<AuthenticationResult | null>;
709
+
710
+ /**
711
+ * Get reputation results from Forward Email API
712
+ * @param mail - Parsed mail object
713
+ * @param authOptions - Authentication options (for IP/sender)
714
+ * @param reputationOptions - Reputation API options
715
+ * @returns Reputation result or null
716
+ */
717
+ getReputationResults(
718
+ mail: MailObject,
719
+ authOptions?: AuthOptions,
720
+ reputationOptions?: ReputationOptions
721
+ ): Promise<ExtendedReputationResult | null>;
722
+ }
723
+
724
+ /**
725
+ * Enhanced IDN Detector options
726
+ */
727
+ export type EnhancedIdnDetectorOptions = {
728
+ /** Enable strict mode */
729
+ strictMode?: boolean;
730
+ /** Enable domain whitelist */
731
+ enableWhitelist?: boolean;
732
+ /** Enable brand protection */
733
+ enableBrandProtection?: boolean;
734
+ /** Enable context analysis */
735
+ enableContextAnalysis?: boolean;
736
+ /** Maximum similarity threshold (0-1) */
737
+ maxSimilarityThreshold?: number;
738
+ /** Minimum domain age in days */
739
+ minDomainAge?: number;
740
+ };
741
+
742
+ /**
743
+ * Context for IDN analysis
744
+ */
745
+ export type IdnAnalysisContext = {
746
+ /** Email content */
747
+ emailContent?: string;
748
+ /** Display text (if different from domain) */
749
+ displayText?: string | undefined;
750
+ /** Sender reputation (0-1) */
751
+ senderReputation?: number;
752
+ /** Email headers */
753
+ emailHeaders?: Map<string, unknown> | Record<string, unknown>;
754
+ };
755
+
756
+ /**
757
+ * IDN analysis result
758
+ */
759
+ export type IdnAnalysisResult = {
760
+ /** The domain analyzed */
761
+ domain: string;
762
+ /** Whether the domain is an IDN */
763
+ isIdn: boolean;
764
+ /** Risk score (0-1) */
765
+ riskScore: number;
766
+ /** Risk factors identified */
767
+ riskFactors: string[];
768
+ /** Recommendations */
769
+ recommendations: string[];
770
+ /** Confidence level (0-1) */
771
+ confidence: number;
772
+ };
773
+
774
+ /**
775
+ * Confusable character analysis result
776
+ */
777
+ export type ConfusableAnalysis = {
778
+ /** Risk score contribution */
779
+ score: number;
780
+ /** Risk factors identified */
781
+ factors: string[];
782
+ };
783
+
784
+ /**
785
+ * Brand similarity analysis result
786
+ */
787
+ export type BrandAnalysis = {
788
+ /** Risk score contribution */
789
+ score: number;
790
+ /** Risk factors identified */
791
+ factors: string[];
792
+ };
793
+
794
+ /**
795
+ * Script mixing analysis result
796
+ */
797
+ export type ScriptAnalysis = {
798
+ /** Risk score contribution */
799
+ score: number;
800
+ /** Risk factors identified */
801
+ factors: string[];
802
+ };
803
+
804
+ /**
805
+ * Context analysis result
806
+ */
807
+ export type ContextAnalysis = {
808
+ /** Risk score contribution */
809
+ score: number;
810
+ /** Risk factors identified */
811
+ factors: string[];
812
+ };
813
+
814
+ /**
815
+ * Punycode analysis result
816
+ */
817
+ export type PunycodeAnalysis = {
818
+ /** Risk score contribution */
819
+ score: number;
820
+ /** Risk factors identified */
821
+ factors: string[];
822
+ };
823
+
824
+ /**
825
+ * Enhanced IDN Homograph Attack Detector
826
+ */
827
+ declare class EnhancedIdnDetector {
828
+ /** Detector options */
829
+ options: EnhancedIdnDetectorOptions & {
830
+ strictMode: boolean;
831
+ enableWhitelist: boolean;
832
+ enableBrandProtection: boolean;
833
+ enableContextAnalysis: boolean;
834
+ maxSimilarityThreshold: number;
835
+ minDomainAge: number;
836
+ };
837
+
838
+ /** Analysis cache */
839
+ cache: Map<string, IdnAnalysisResult>;
840
+
841
+ /**
842
+ * Create a new EnhancedIdnDetector instance
843
+ * @param options - Configuration options
844
+ */
845
+ constructor(options?: EnhancedIdnDetectorOptions);
846
+
847
+ /**
848
+ * Detect homograph attack in a domain
849
+ * @param domain - Domain to analyze
850
+ * @param context - Analysis context
851
+ * @returns Analysis result
852
+ */
853
+ detectHomographAttack(domain: string, context?: IdnAnalysisContext): IdnAnalysisResult;
854
+
855
+ /**
856
+ * Comprehensive analysis of a domain
857
+ * @param domain - Domain to analyze
858
+ * @param context - Analysis context
859
+ * @returns Analysis result
860
+ */
861
+ analyzeComprehensive(domain: string, context: IdnAnalysisContext): IdnAnalysisResult;
862
+
863
+ /**
864
+ * Check if domain contains IDN characters
865
+ * @param domain - Domain to check
866
+ * @returns Whether the domain is an IDN
867
+ */
868
+ isIdnDomain(domain: string): boolean;
869
+
870
+ /**
871
+ * Check if domain is whitelisted
872
+ * @param domain - Domain to check
873
+ * @returns Whether the domain is whitelisted
874
+ */
875
+ isWhitelisted(domain: string): boolean;
876
+
877
+ /**
878
+ * Analyze confusable characters in domain
879
+ * @param domain - Domain to analyze
880
+ * @returns Confusable analysis result
881
+ */
882
+ analyzeConfusableCharacters(domain: string): ConfusableAnalysis;
883
+
884
+ /**
885
+ * Analyze brand similarity
886
+ * @param domain - Domain to analyze
887
+ * @returns Brand analysis result
888
+ */
889
+ analyzeBrandSimilarity(domain: string): BrandAnalysis;
890
+
891
+ /**
892
+ * Analyze script mixing patterns
893
+ * @param domain - Domain to analyze
894
+ * @returns Script analysis result
895
+ */
896
+ analyzeScriptMixing(domain: string): ScriptAnalysis;
897
+
898
+ /**
899
+ * Analyze context for additional risk factors
900
+ * @param domain - Domain to analyze
901
+ * @param context - Analysis context
902
+ * @returns Context analysis result
903
+ */
904
+ analyzeContext(domain: string, context: IdnAnalysisContext): ContextAnalysis;
905
+
906
+ /**
907
+ * Analyze punycode domain
908
+ * @param domain - Domain to analyze
909
+ * @returns Punycode analysis result
910
+ */
911
+ analyzePunycode(domain: string): PunycodeAnalysis;
912
+
913
+ /**
914
+ * Normalize domain for comparison
915
+ * @param domain - Domain to normalize
916
+ * @returns Normalized domain
917
+ */
918
+ normalizeDomain(domain: string): string;
919
+
920
+ /**
921
+ * Calculate string similarity using Levenshtein distance
922
+ * @param string1 - First string
923
+ * @param string2 - Second string
924
+ * @returns Similarity score (0-1)
925
+ */
926
+ calculateSimilarity(string1: string, string2: string): number;
927
+
928
+ /**
929
+ * Detect scripts used in domain
930
+ * @param domain - Domain to analyze
931
+ * @returns Set of detected scripts
932
+ */
933
+ detectScripts(domain: string): Set<string>;
934
+
935
+ /**
936
+ * Decode punycode domain
937
+ * @param domain - Domain to decode
938
+ * @returns Decoded domain
939
+ */
940
+ decodePunycode(domain: string): string;
941
+
942
+ /**
943
+ * Generate recommendations based on analysis
944
+ * @param analysis - Analysis result
945
+ * @returns Array of recommendations
946
+ */
947
+ generateRecommendations(analysis: IdnAnalysisResult): string[];
948
+
949
+ /**
950
+ * Get cache key for analysis
951
+ * @param domain - Domain
952
+ * @param context - Analysis context
953
+ * @returns Cache key
954
+ */
955
+ getCacheKey(domain: string, context: IdnAnalysisContext): string;
956
+ }
957
+
958
+ export default SpamScanner;
959
+ export {SpamScanner, EnhancedIdnDetector};