mailauth 4.11.0 → 4.12.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/index.d.ts ADDED
@@ -0,0 +1,1354 @@
1
+ // Type definitions for mailauth
2
+ // Project: https://github.com/postalsys/mailauth
3
+ // Definitions by: Claude Code
4
+
5
+ /// <reference types="node" />
6
+
7
+ import { Readable, Transform } from 'stream';
8
+
9
+ /**
10
+ * DNS resolver function type for custom DNS resolution
11
+ */
12
+ export type DNSResolver = (domain: string, rrtype: string) => Promise<string[][] | string[]>;
13
+
14
+ /**
15
+ * Input types accepted by mailauth functions
16
+ */
17
+ export type MessageInput = Readable | Buffer | string;
18
+
19
+ // ============================================================================
20
+ // Main authenticate() function
21
+ // ============================================================================
22
+
23
+ /**
24
+ * Options for the authenticate() function
25
+ */
26
+ export interface AuthenticateOptions {
27
+ /**
28
+ * If true, parse ip and helo values from Received header and sender value from Return-Path
29
+ */
30
+ trustReceived?: boolean;
31
+
32
+ /**
33
+ * Address from MAIL FROM
34
+ */
35
+ sender?: string;
36
+
37
+ /**
38
+ * Client IP address
39
+ */
40
+ ip?: string;
41
+
42
+ /**
43
+ * Hostname from EHLO/HELO
44
+ */
45
+ helo?: string;
46
+
47
+ /**
48
+ * MTA/MX hostname (defaults to os.hostname())
49
+ */
50
+ mta?: string;
51
+
52
+ /**
53
+ * Minimal allowed length of public keys in bits (default: 1024)
54
+ * If DKIM/ARC key is smaller, verification fails
55
+ */
56
+ minBitLength?: number;
57
+
58
+ /**
59
+ * Custom DNS resolver function
60
+ */
61
+ resolver?: DNSResolver;
62
+
63
+ /**
64
+ * If true, do not perform ARC validation and sealing
65
+ */
66
+ disableArc?: boolean;
67
+
68
+ /**
69
+ * If true, do not perform DMARC check
70
+ */
71
+ disableDmarc?: boolean;
72
+
73
+ /**
74
+ * If true, do not perform BIMI check
75
+ */
76
+ disableBimi?: boolean;
77
+
78
+ /**
79
+ * Require aligned DKIM signature for BIMI
80
+ */
81
+ bimiWithAlignedDkim?: boolean;
82
+
83
+ /**
84
+ * ARC sealing options
85
+ */
86
+ seal?: ARCSealOptions;
87
+ }
88
+
89
+ /**
90
+ * ARC sealing options
91
+ */
92
+ export interface ARCSealOptions {
93
+ /**
94
+ * ARC key domain name
95
+ */
96
+ signingDomain: string;
97
+
98
+ /**
99
+ * ARC key selector
100
+ */
101
+ selector: string;
102
+
103
+ /**
104
+ * Private key for signing (PEM format)
105
+ */
106
+ privateKey: string | Buffer;
107
+
108
+ /**
109
+ * Canonicalization algorithm (default: 'relaxed/relaxed')
110
+ */
111
+ canonicalization?: string;
112
+
113
+ /**
114
+ * Signing algorithm (default: 'rsa-sha256')
115
+ * Supported: 'rsa-sha256', 'ed25519-sha256'
116
+ */
117
+ algorithm?: string;
118
+
119
+ /**
120
+ * Headers to include in signature
121
+ */
122
+ headerList?: string[];
123
+
124
+ /**
125
+ * Signing timestamp
126
+ */
127
+ signTime?: Date | string | number;
128
+ }
129
+
130
+ /**
131
+ * Policy information attached to authentication status
132
+ */
133
+ export interface AuthPolicy {
134
+ /**
135
+ * DKIM policy rules (e.g., 'weak-key' when key is undersized)
136
+ */
137
+ 'dkim-rules'?: string;
138
+
139
+ /**
140
+ * Additional policy properties
141
+ */
142
+ [key: string]: string | undefined;
143
+ }
144
+
145
+ /**
146
+ * Status result from authentication checks
147
+ */
148
+ export interface AuthStatus {
149
+ result: 'pass' | 'fail' | 'neutral' | 'none' | 'temperror' | 'temperr' | 'permerror' | 'policy' | 'softfail' | 'skipped';
150
+ comment?: string;
151
+ header?: Record<string, any>;
152
+ smtp?: {
153
+ mailfrom?: string;
154
+ helo?: string;
155
+ };
156
+ policy?: AuthPolicy;
157
+ }
158
+
159
+ /**
160
+ * DKIM verification result for a single signature
161
+ */
162
+ export interface DKIMResult {
163
+ /**
164
+ * Signature identifier
165
+ */
166
+ id?: string;
167
+
168
+ /**
169
+ * Signing domain
170
+ */
171
+ signingDomain: string;
172
+
173
+ /**
174
+ * Key selector
175
+ */
176
+ selector?: string;
177
+
178
+ /**
179
+ * Verification status
180
+ */
181
+ status: AuthStatus & {
182
+ aligned?: boolean;
183
+ underSized?: boolean;
184
+ };
185
+
186
+ /**
187
+ * Authentication-Results formatted info
188
+ */
189
+ info: string;
190
+
191
+ /**
192
+ * Signature algorithm
193
+ */
194
+ algorithm?: string;
195
+
196
+ /**
197
+ * Canonicalization method
198
+ */
199
+ canonicalization?: string;
200
+
201
+ /**
202
+ * Signing timestamp
203
+ */
204
+ signingTime?: Date;
205
+
206
+ /**
207
+ * Signature expiration
208
+ */
209
+ expiration?: Date;
210
+ }
211
+
212
+ /**
213
+ * DKIM verification results
214
+ */
215
+ export interface DKIMVerifyResult {
216
+ /**
217
+ * Domain from From header
218
+ */
219
+ headerFrom: string[];
220
+
221
+ /**
222
+ * Domain from Return-Path header
223
+ */
224
+ envelopeFrom: string | false;
225
+
226
+ /**
227
+ * Individual signature verification results
228
+ */
229
+ results: DKIMResult[];
230
+
231
+ /**
232
+ * Parsed message headers (non-enumerable property)
233
+ * Access with result.headers or Object.getOwnPropertyDescriptor()
234
+ */
235
+ readonly headers?: {
236
+ parsed: Array<{ key: string; line: string }>;
237
+ [key: string]: any;
238
+ };
239
+
240
+ /**
241
+ * ARC chain data for sealing (non-enumerable property)
242
+ * Access with result.arc or Object.getOwnPropertyDescriptor()
243
+ */
244
+ readonly arc?: ARCSigningData;
245
+
246
+ /**
247
+ * ARC sealing options passed to dkimVerify (non-enumerable property)
248
+ * Access with result.seal or Object.getOwnPropertyDescriptor()
249
+ */
250
+ readonly seal?: ARCSealOptions;
251
+ }
252
+
253
+ /**
254
+ * SPF verification result
255
+ */
256
+ export interface SPFResult {
257
+ /**
258
+ * Sender domain
259
+ */
260
+ domain: string;
261
+
262
+ /**
263
+ * Client IP address
264
+ */
265
+ 'client-ip': string;
266
+
267
+ /**
268
+ * HELO/EHLO hostname
269
+ */
270
+ helo?: string;
271
+
272
+ /**
273
+ * Envelope sender address
274
+ */
275
+ 'envelope-from'?: string;
276
+
277
+ /**
278
+ * Verification status
279
+ */
280
+ status: AuthStatus;
281
+
282
+ /**
283
+ * SPF record used for verification
284
+ */
285
+ rr?: string;
286
+
287
+ /**
288
+ * Formatted Received-SPF header
289
+ */
290
+ header: string;
291
+
292
+ /**
293
+ * Authentication-Results formatted info
294
+ */
295
+ info: string;
296
+
297
+ /**
298
+ * DNS lookup statistics
299
+ */
300
+ lookups?: {
301
+ limit: number;
302
+ count: number;
303
+ void: number;
304
+ subqueries: Record<string, number>;
305
+ };
306
+ }
307
+
308
+ /**
309
+ * ARC verification result
310
+ */
311
+ export interface ARCResult {
312
+ /**
313
+ * ARC instance number
314
+ */
315
+ i: number | false;
316
+
317
+ /**
318
+ * Verification status
319
+ */
320
+ status: AuthStatus & {
321
+ shouldSeal?: boolean;
322
+ };
323
+
324
+ /**
325
+ * ARC-Message-Signature verification result
326
+ */
327
+ signature?: DKIMResult | false;
328
+
329
+ /**
330
+ * Parsed Authentication-Results from ARC chain
331
+ */
332
+ authenticationResults?: Record<string, any>;
333
+
334
+ /**
335
+ * Authentication-Results formatted info
336
+ */
337
+ info?: string;
338
+
339
+ /**
340
+ * Formatted Authentication-Results header value
341
+ */
342
+ authResults?: string;
343
+
344
+ /**
345
+ * ARC chain entries (non-enumerable property)
346
+ * Access with result.chain or Object.getOwnPropertyDescriptor()
347
+ */
348
+ readonly chain?: ARCChainEntry[];
349
+ }
350
+
351
+ /**
352
+ * DMARC verification result
353
+ */
354
+ export interface DMARCResult {
355
+ /**
356
+ * Organization domain
357
+ */
358
+ domain: string;
359
+
360
+ /**
361
+ * DMARC policy ('none', 'quarantine', 'reject')
362
+ */
363
+ policy: string;
364
+
365
+ /**
366
+ * Policy for organizational domain
367
+ */
368
+ p: string;
369
+
370
+ /**
371
+ * Policy for subdomains
372
+ */
373
+ sp: string;
374
+
375
+ /**
376
+ * Percentage of messages subject to filtering (0-100)
377
+ */
378
+ pct?: number;
379
+
380
+ /**
381
+ * DMARC DNS record
382
+ */
383
+ rr?: string;
384
+
385
+ /**
386
+ * Verification status
387
+ */
388
+ status: AuthStatus;
389
+
390
+ /**
391
+ * Alignment results
392
+ */
393
+ alignment: {
394
+ spf: {
395
+ result: string | false;
396
+ strict: boolean;
397
+ };
398
+ dkim: {
399
+ result: string | false;
400
+ strict: boolean;
401
+ underSized?: boolean;
402
+ };
403
+ };
404
+
405
+ /**
406
+ * Authentication-Results formatted info
407
+ */
408
+ info: string;
409
+
410
+ /**
411
+ * Error message if verification failed
412
+ */
413
+ error?: string;
414
+ }
415
+
416
+ /**
417
+ * BIMI verification result
418
+ */
419
+ export interface BIMIResult {
420
+ /**
421
+ * Verification status
422
+ */
423
+ status: AuthStatus;
424
+
425
+ /**
426
+ * BIMI DNS record
427
+ */
428
+ rr?: string;
429
+
430
+ /**
431
+ * Logo location URL
432
+ */
433
+ location?: string;
434
+
435
+ /**
436
+ * VMC (Verified Mark Certificate) authority URL
437
+ */
438
+ authority?: string;
439
+
440
+ /**
441
+ * Authentication-Results formatted info
442
+ */
443
+ info: string;
444
+ }
445
+
446
+ /**
447
+ * Parsed Received header information
448
+ */
449
+ export interface ReceivedChainEntry {
450
+ /**
451
+ * Hostname/IP that sent the message
452
+ */
453
+ from?: {
454
+ /**
455
+ * Hostname or IP address
456
+ */
457
+ value: string;
458
+
459
+ /**
460
+ * Additional comment (often contains IP in parentheses)
461
+ */
462
+ comment?: string;
463
+ };
464
+
465
+ /**
466
+ * Hostname that received the message
467
+ */
468
+ by?: {
469
+ /**
470
+ * Receiving hostname
471
+ */
472
+ value: string;
473
+
474
+ /**
475
+ * Additional comment
476
+ */
477
+ comment?: string;
478
+ };
479
+
480
+ /**
481
+ * Protocol used for transmission (e.g., 'SMTP', 'ESMTP', 'ESMTPS')
482
+ */
483
+ with?: {
484
+ value: string;
485
+ };
486
+
487
+ /**
488
+ * Message ID assigned by the receiving server
489
+ */
490
+ id?: {
491
+ value: string;
492
+ };
493
+
494
+ /**
495
+ * Recipient address
496
+ */
497
+ for?: {
498
+ value: string;
499
+ };
500
+
501
+ /**
502
+ * Envelope sender address from MAIL FROM
503
+ */
504
+ 'envelope-from'?: {
505
+ value: string;
506
+ };
507
+
508
+ /**
509
+ * Timestamp when the message was received
510
+ */
511
+ date?: Date;
512
+
513
+ /**
514
+ * Additional parsed Received header fields
515
+ */
516
+ [key: string]: any;
517
+ }
518
+
519
+ /**
520
+ * Result from authenticate() function
521
+ */
522
+ export interface AuthenticateResult {
523
+ /**
524
+ * DKIM verification results
525
+ */
526
+ dkim: DKIMVerifyResult;
527
+
528
+ /**
529
+ * SPF verification result
530
+ */
531
+ spf: SPFResult | false;
532
+
533
+ /**
534
+ * DMARC verification result
535
+ */
536
+ dmarc: DMARCResult | false;
537
+
538
+ /**
539
+ * ARC verification result
540
+ */
541
+ arc: ARCResult | false;
542
+
543
+ /**
544
+ * BIMI verification result
545
+ */
546
+ bimi: BIMIResult | false;
547
+
548
+ /**
549
+ * Parsed Received header chain
550
+ */
551
+ receivedChain?: ReceivedChainEntry[];
552
+
553
+ /**
554
+ * Combined authentication headers to prepend to message
555
+ */
556
+ headers: string;
557
+ }
558
+
559
+ /**
560
+ * Verifies DKIM, SPF, DMARC, ARC, and BIMI for an email message
561
+ *
562
+ * @param input - RFC822 formatted message (stream, buffer, or string)
563
+ * @param opts - Authentication options
564
+ * @returns Authentication results including all protocol checks
565
+ */
566
+ export function authenticate(input: MessageInput, opts?: AuthenticateOptions): Promise<AuthenticateResult>;
567
+
568
+ // ============================================================================
569
+ // DKIM Sign
570
+ // ============================================================================
571
+
572
+ /**
573
+ * DKIM signing options
574
+ */
575
+ export interface DKIMSignOptions {
576
+ /**
577
+ * Signing domain (d= tag)
578
+ */
579
+ signingDomain: string;
580
+
581
+ /**
582
+ * Key selector (s= tag)
583
+ */
584
+ selector: string;
585
+
586
+ /**
587
+ * Private key for signing (PEM format)
588
+ */
589
+ privateKey: string | Buffer;
590
+
591
+ /**
592
+ * Canonicalization algorithm (default: 'relaxed/relaxed')
593
+ * Format: 'header/body' where each can be 'simple' or 'relaxed'
594
+ */
595
+ canonicalization?: string;
596
+
597
+ /**
598
+ * Signing algorithm (default: 'rsa-sha256')
599
+ * Supported: 'rsa-sha256', 'rsa-sha1', 'ed25519-sha256'
600
+ */
601
+ algorithm?: string;
602
+
603
+ /**
604
+ * List of header fields to sign
605
+ * Default includes From, Subject, Date, To, etc.
606
+ */
607
+ headerList?: string[];
608
+
609
+ /**
610
+ * Signing timestamp (defaults to current time)
611
+ */
612
+ signTime?: Date | string | number;
613
+
614
+ /**
615
+ * Signature expiration time
616
+ */
617
+ expires?: Date | string | number;
618
+
619
+ /**
620
+ * Maximum body length to sign (l= tag)
621
+ */
622
+ maxBodyLength?: number;
623
+
624
+ /**
625
+ * Identity (i= tag)
626
+ */
627
+ identity?: string;
628
+
629
+ /**
630
+ * Multiple signature configurations
631
+ */
632
+ signatureData?: DKIMSignOptions[];
633
+ }
634
+
635
+ /**
636
+ * Parsed DKIM/ARC header tag-value pair
637
+ */
638
+ export interface ParsedHeaderValue {
639
+ /**
640
+ * Tag name
641
+ */
642
+ key?: string;
643
+
644
+ /**
645
+ * Tag value
646
+ */
647
+ value?: string | number;
648
+ }
649
+
650
+ /**
651
+ * Parsed DKIM/ARC header structure
652
+ */
653
+ export interface ParsedHeader {
654
+ /**
655
+ * Original header line
656
+ */
657
+ original?: string;
658
+
659
+ /**
660
+ * Parsed tag-value pairs
661
+ */
662
+ parsed?: {
663
+ /**
664
+ * Instance number (i= tag for ARC)
665
+ */
666
+ i?: ParsedHeaderValue;
667
+
668
+ /**
669
+ * Algorithm (a= tag)
670
+ */
671
+ a?: ParsedHeaderValue;
672
+
673
+ /**
674
+ * Signature data (b= tag)
675
+ */
676
+ b?: ParsedHeaderValue;
677
+
678
+ /**
679
+ * Body hash (bh= tag)
680
+ */
681
+ bh?: ParsedHeaderValue;
682
+
683
+ /**
684
+ * Canonicalization (c= tag)
685
+ */
686
+ c?: ParsedHeaderValue;
687
+
688
+ /**
689
+ * Signing domain (d= tag)
690
+ */
691
+ d?: ParsedHeaderValue;
692
+
693
+ /**
694
+ * Selector (s= tag)
695
+ */
696
+ s?: ParsedHeaderValue;
697
+
698
+ /**
699
+ * Signed headers (h= tag)
700
+ */
701
+ h?: ParsedHeaderValue;
702
+
703
+ /**
704
+ * Chain validation result (cv= tag for ARC-Seal)
705
+ */
706
+ cv?: ParsedHeaderValue;
707
+
708
+ /**
709
+ * Timestamp (t= tag)
710
+ */
711
+ t?: ParsedHeaderValue;
712
+
713
+ /**
714
+ * Additional parsed properties
715
+ */
716
+ [key: string]: ParsedHeaderValue | undefined;
717
+ };
718
+
719
+ /**
720
+ * Signing algorithm type (e.g., 'rsa', 'ed25519')
721
+ */
722
+ signAlgo?: string;
723
+
724
+ /**
725
+ * Full algorithm (e.g., 'rsa-sha256')
726
+ */
727
+ algorithm?: string;
728
+ }
729
+
730
+ /**
731
+ * ARC chain entry representing a single ARC set (i=N)
732
+ */
733
+ export interface ARCChainEntry {
734
+ /**
735
+ * ARC instance number
736
+ */
737
+ i: number;
738
+
739
+ /**
740
+ * ARC-Seal header
741
+ */
742
+ 'arc-seal'?: ParsedHeader;
743
+
744
+ /**
745
+ * ARC-Message-Signature header
746
+ */
747
+ 'arc-message-signature'?: ParsedHeader;
748
+
749
+ /**
750
+ * ARC-Authentication-Results header
751
+ */
752
+ 'arc-authentication-results'?: ParsedHeader;
753
+
754
+ /**
755
+ * Message signature verification result (for last entry)
756
+ */
757
+ messageSignature?: DKIMResult;
758
+ }
759
+
760
+ /**
761
+ * ARC signing data returned from DKIM signing
762
+ */
763
+ export interface ARCSigningData {
764
+ /**
765
+ * ARC chain from message headers (false if no chain found)
766
+ */
767
+ chain: ARCChainEntry[] | false;
768
+
769
+ /**
770
+ * Last entry in the ARC chain
771
+ */
772
+ lastEntry?: ARCChainEntry;
773
+
774
+ /**
775
+ * ARC instance number for signing
776
+ */
777
+ instance?: number;
778
+
779
+ /**
780
+ * Generated ARC-Message-Signature header
781
+ */
782
+ messageSignature?: string;
783
+
784
+ /**
785
+ * Error encountered during ARC processing
786
+ */
787
+ error?: Error;
788
+
789
+ /**
790
+ * ARC signing domain (from options)
791
+ */
792
+ signingDomain?: string;
793
+
794
+ /**
795
+ * ARC key selector (from options)
796
+ */
797
+ selector?: string;
798
+
799
+ /**
800
+ * ARC private key (from options)
801
+ */
802
+ privateKey?: string | Buffer;
803
+ }
804
+
805
+ /**
806
+ * DKIM signing result
807
+ */
808
+ export interface DKIMSignResult {
809
+ /**
810
+ * DKIM-Signature header(s) to prepend to message
811
+ */
812
+ signatures: string;
813
+
814
+ /**
815
+ * ARC chain information (if ARC signing was performed)
816
+ */
817
+ arc?: ARCSigningData;
818
+
819
+ /**
820
+ * Any errors encountered during signing
821
+ */
822
+ errors: Error[];
823
+ }
824
+
825
+ /**
826
+ * Signs an email message with DKIM signature(s)
827
+ *
828
+ * @param input - RFC822 formatted message (stream, buffer, or string)
829
+ * @param options - DKIM signing options
830
+ * @returns DKIM signature header(s) and any errors
831
+ */
832
+ export function dkimSign(input: MessageInput, options: DKIMSignOptions): Promise<DKIMSignResult>;
833
+
834
+ /**
835
+ * Transform stream for DKIM signing
836
+ * Prepends DKIM-Signature header to the message stream
837
+ */
838
+ export class DkimSignStream extends Transform {
839
+ /**
840
+ * Creates a DKIM signing stream
841
+ *
842
+ * @param options - DKIM signing options
843
+ */
844
+ constructor(options: DKIMSignOptions);
845
+
846
+ /**
847
+ * Any errors encountered during signing
848
+ */
849
+ errors: Error[] | null;
850
+ }
851
+
852
+ // ============================================================================
853
+ // DKIM Verify
854
+ // ============================================================================
855
+
856
+ /**
857
+ * DKIM verification options
858
+ */
859
+ export interface DKIMVerifyOptions {
860
+ /**
861
+ * Custom DNS resolver function
862
+ */
863
+ resolver?: DNSResolver;
864
+
865
+ /**
866
+ * Sender address (defaults to Return-Path header)
867
+ */
868
+ sender?: string;
869
+
870
+ /**
871
+ * Minimal allowed public key length in bits (default: 1024)
872
+ */
873
+ minBitLength?: number;
874
+
875
+ /**
876
+ * Current time for signature expiration checks
877
+ */
878
+ curTime?: Date | string | number;
879
+
880
+ /**
881
+ * ARC sealing options (if sealing should be prepared)
882
+ */
883
+ seal?: ARCSealOptions;
884
+ }
885
+
886
+ /**
887
+ * Verifies DKIM signatures in an email message
888
+ *
889
+ * @param input - RFC822 formatted message (stream, buffer, or string)
890
+ * @param options - DKIM verification options
891
+ * @returns DKIM verification results
892
+ */
893
+ export function dkimVerify(input: MessageInput, options?: DKIMVerifyOptions): Promise<DKIMVerifyResult>;
894
+
895
+ // ============================================================================
896
+ // SPF
897
+ // ============================================================================
898
+
899
+ /**
900
+ * SPF verification options
901
+ */
902
+ export interface SPFOptions {
903
+ /**
904
+ * Email address from MAIL FROM
905
+ */
906
+ sender?: string;
907
+
908
+ /**
909
+ * Client IP address
910
+ */
911
+ ip: string;
912
+
913
+ /**
914
+ * Client EHLO/HELO hostname
915
+ */
916
+ helo?: string;
917
+
918
+ /**
919
+ * MTA hostname (defaults to os.hostname())
920
+ */
921
+ mta?: string;
922
+
923
+ /**
924
+ * Maximum DNS lookups allowed (default: 10)
925
+ */
926
+ maxResolveCount?: number;
927
+
928
+ /**
929
+ * Maximum void DNS lookups allowed (default: 2)
930
+ */
931
+ maxVoidCount?: number;
932
+
933
+ /**
934
+ * Custom DNS resolver function
935
+ */
936
+ resolver?: DNSResolver;
937
+ }
938
+
939
+ /**
940
+ * Verifies SPF for a sender
941
+ *
942
+ * @param opts - SPF verification options
943
+ * @returns SPF verification result
944
+ */
945
+ export function spf(opts: SPFOptions): Promise<SPFResult>;
946
+
947
+ // ============================================================================
948
+ // DMARC
949
+ // ============================================================================
950
+
951
+ /**
952
+ * DMARC verification options
953
+ */
954
+ export interface DMARCOptions {
955
+ /**
956
+ * Domain from From header
957
+ */
958
+ headerFrom: string | string[];
959
+
960
+ /**
961
+ * Domains that passed SPF
962
+ */
963
+ spfDomains?: string[];
964
+
965
+ /**
966
+ * Domains and alignment info from DKIM signatures
967
+ */
968
+ dkimDomains?: Array<{
969
+ id?: string;
970
+ domain: string;
971
+ aligned?: boolean;
972
+ underSized?: boolean;
973
+ }>;
974
+
975
+ /**
976
+ * ARC verification result
977
+ */
978
+ arcResult?: ARCResult;
979
+
980
+ /**
981
+ * Custom DNS resolver function
982
+ */
983
+ resolver?: DNSResolver;
984
+ }
985
+
986
+ /**
987
+ * Verifies DMARC policy for a message
988
+ *
989
+ * @param opts - DMARC verification options
990
+ * @returns DMARC verification result
991
+ */
992
+ export function dmarc(opts: DMARCOptions): Promise<DMARCResult | false>;
993
+
994
+ // ============================================================================
995
+ // ARC
996
+ // ============================================================================
997
+
998
+ /**
999
+ * ARC data structure
1000
+ */
1001
+ export interface ARCData {
1002
+ /**
1003
+ * ARC chain entries
1004
+ */
1005
+ chain: ARCChainEntry[];
1006
+
1007
+ /**
1008
+ * Last entry in the ARC chain
1009
+ */
1010
+ lastEntry?: ARCChainEntry;
1011
+
1012
+ /**
1013
+ * Error encountered during ARC chain parsing
1014
+ */
1015
+ error?: Error;
1016
+ }
1017
+
1018
+ /**
1019
+ * ARC verification options
1020
+ */
1021
+ export interface ARCOptions {
1022
+ /**
1023
+ * Custom DNS resolver function
1024
+ */
1025
+ resolver?: DNSResolver;
1026
+
1027
+ /**
1028
+ * Minimal allowed public key length in bits (default: 1024)
1029
+ */
1030
+ minBitLength?: number;
1031
+ }
1032
+
1033
+ /**
1034
+ * Verifies ARC chain in a message
1035
+ *
1036
+ * @param data - ARC chain data
1037
+ * @param opts - ARC verification options
1038
+ * @returns ARC verification result
1039
+ */
1040
+ export function arc(data: ARCData, opts?: ARCOptions): Promise<ARCResult>;
1041
+
1042
+ /**
1043
+ * Seals a message with ARC headers
1044
+ *
1045
+ * @param input - RFC822 formatted message (stream, buffer, or string)
1046
+ * @param seal - ARC sealing options
1047
+ * @returns ARC headers to prepend
1048
+ */
1049
+ export function sealMessage(input: MessageInput, seal: ARCSealOptions): Promise<Buffer>;
1050
+
1051
+ /**
1052
+ * Gets ARC chain from parsed headers
1053
+ *
1054
+ * @param headers - Parsed message headers
1055
+ * @returns ARC chain or false if no chain found
1056
+ */
1057
+ export function getARChain(headers: any): ARCChainEntry[] | false;
1058
+
1059
+ /**
1060
+ * Verifies ARC seal chain
1061
+ *
1062
+ * @param data - ARC chain data
1063
+ * @param opts - ARC verification options
1064
+ * @returns true if chain is valid
1065
+ */
1066
+ export function verifyASChain(data: ARCData, opts: ARCOptions): Promise<boolean>;
1067
+
1068
+ /**
1069
+ * Creates ARC seal headers
1070
+ *
1071
+ * @param input - RFC822 formatted message or false for pre-calculated data
1072
+ * @param data - Seal creation data
1073
+ * @returns Seal headers
1074
+ */
1075
+ export function createSeal(input: MessageInput | false, data: any): Promise<{ headers: string[] }>;
1076
+
1077
+ // ============================================================================
1078
+ // BIMI
1079
+ // ============================================================================
1080
+
1081
+ /**
1082
+ * BIMI lookup options
1083
+ */
1084
+ export interface BIMIOptions {
1085
+ /**
1086
+ * DMARC verification result
1087
+ */
1088
+ dmarc?: DMARCResult;
1089
+
1090
+ /**
1091
+ * Parsed message headers
1092
+ */
1093
+ headers?: any;
1094
+
1095
+ /**
1096
+ * Require aligned DKIM signature
1097
+ */
1098
+ bimiWithAlignedDkim?: boolean;
1099
+
1100
+ /**
1101
+ * Custom DNS resolver function
1102
+ */
1103
+ resolver?: DNSResolver;
1104
+ }
1105
+
1106
+ /**
1107
+ * VMC (Verified Mark Certificate) validation result
1108
+ */
1109
+ export interface VMCValidationResult {
1110
+ /**
1111
+ * Logo file fetch and validation result
1112
+ */
1113
+ location?: {
1114
+ /**
1115
+ * URL the logo was fetched from
1116
+ */
1117
+ url: string;
1118
+
1119
+ /**
1120
+ * Whether the logo was successfully fetched and validated
1121
+ */
1122
+ success: boolean;
1123
+
1124
+ /**
1125
+ * Error information if fetch/validation failed
1126
+ */
1127
+ error?: {
1128
+ /**
1129
+ * Human-readable error message
1130
+ */
1131
+ message: string;
1132
+
1133
+ /**
1134
+ * Error code
1135
+ */
1136
+ code?: string;
1137
+
1138
+ /**
1139
+ * Redirect URL if logo location redirected
1140
+ */
1141
+ redirect?: string;
1142
+ };
1143
+
1144
+ /**
1145
+ * Base64-encoded SVG logo file content
1146
+ */
1147
+ logoFile?: string;
1148
+
1149
+ /**
1150
+ * Hash algorithm used for logo verification (e.g., 'sha256')
1151
+ */
1152
+ hashAlgo?: string;
1153
+
1154
+ /**
1155
+ * Hash value of the logo file
1156
+ */
1157
+ hashValue?: string;
1158
+ };
1159
+
1160
+ /**
1161
+ * VMC certificate fetch and validation result
1162
+ */
1163
+ authority?: {
1164
+ /**
1165
+ * URL the VMC certificate was fetched from
1166
+ */
1167
+ url: string;
1168
+
1169
+ /**
1170
+ * Whether the certificate was successfully fetched and validated
1171
+ */
1172
+ success: boolean;
1173
+
1174
+ /**
1175
+ * Error information if fetch/validation failed
1176
+ */
1177
+ error?: {
1178
+ /**
1179
+ * Human-readable error message
1180
+ */
1181
+ message: string;
1182
+
1183
+ /**
1184
+ * Error code
1185
+ */
1186
+ code?: string;
1187
+
1188
+ /**
1189
+ * Additional error details
1190
+ */
1191
+ details?: any;
1192
+
1193
+ /**
1194
+ * Redirect URL if authority location redirected
1195
+ */
1196
+ redirect?: string;
1197
+ };
1198
+
1199
+ /**
1200
+ * Parsed VMC certificate data
1201
+ */
1202
+ vmc?: any;
1203
+
1204
+ /**
1205
+ * Whether the domain in the certificate matches the sender domain
1206
+ */
1207
+ domainVerified?: boolean;
1208
+
1209
+ /**
1210
+ * Whether the logo hash in the certificate matches the fetched logo
1211
+ */
1212
+ hashMatch?: boolean;
1213
+ };
1214
+ }
1215
+
1216
+ /**
1217
+ * BIMI data for VMC validation
1218
+ */
1219
+ export interface BIMIData extends BIMIResult {
1220
+ locationPath?: Buffer;
1221
+ authorityPath?: Buffer;
1222
+ }
1223
+
1224
+ /**
1225
+ * VMC validation options
1226
+ */
1227
+ export interface VMCValidationOptions {
1228
+ /**
1229
+ * Custom VMC validation options passed to @postalsys/vmc
1230
+ */
1231
+ [key: string]: any;
1232
+ }
1233
+
1234
+ /**
1235
+ * Resolves BIMI record and logo location for a domain
1236
+ *
1237
+ * @param opts - BIMI lookup options
1238
+ * @returns BIMI verification result
1239
+ */
1240
+ export function bimi(opts: BIMIOptions): Promise<BIMIResult | false>;
1241
+
1242
+ /**
1243
+ * Validates BIMI VMC (Verified Mark Certificate) and logo file
1244
+ *
1245
+ * @param bimiData - BIMI data including location and authority URLs
1246
+ * @param opts - VMC validation options
1247
+ * @returns VMC validation result
1248
+ */
1249
+ export function validateBimiVmc(bimiData: BIMIData | null, opts?: VMCValidationOptions): Promise<VMCValidationResult | false>;
1250
+
1251
+ /**
1252
+ * Validates BIMI SVG logo file
1253
+ *
1254
+ * @param logo - SVG logo file buffer
1255
+ * @throws Error if validation fails
1256
+ */
1257
+ export function validateBimiSvg(logo: Buffer): void;
1258
+
1259
+ // ============================================================================
1260
+ // MTA-STS
1261
+ // ============================================================================
1262
+
1263
+ /**
1264
+ * MTA-STS policy
1265
+ */
1266
+ export interface MTASTSPolicy {
1267
+ /**
1268
+ * Policy ID from DNS (undefined when returned from parsePolicy)
1269
+ */
1270
+ id?: string | false;
1271
+
1272
+ /**
1273
+ * Policy version (should be 'STSv1')
1274
+ */
1275
+ version?: string;
1276
+
1277
+ /**
1278
+ * Policy mode ('enforce', 'testing', 'none')
1279
+ */
1280
+ mode: 'enforce' | 'testing' | 'none';
1281
+
1282
+ /**
1283
+ * Maximum age in seconds
1284
+ */
1285
+ maxAge?: number;
1286
+
1287
+ /**
1288
+ * List of allowed MX hostnames (may include wildcards like *.example.com)
1289
+ */
1290
+ mx?: string[];
1291
+
1292
+ /**
1293
+ * Policy expiration timestamp
1294
+ */
1295
+ expires?: string;
1296
+
1297
+ /**
1298
+ * Error encountered during policy fetch
1299
+ */
1300
+ error?: Error;
1301
+ }
1302
+
1303
+ /**
1304
+ * MTA-STS policy fetch result
1305
+ */
1306
+ export interface MTASTSPolicyResult {
1307
+ /**
1308
+ * Fetched or renewed policy
1309
+ */
1310
+ policy: MTASTSPolicy;
1311
+
1312
+ /**
1313
+ * Status of the fetch operation
1314
+ */
1315
+ status: 'found' | 'renewed' | 'not_found' | 'errored';
1316
+ }
1317
+
1318
+ /**
1319
+ * MTA-STS MX validation result
1320
+ */
1321
+ export interface MTASTSValidationResult {
1322
+ /**
1323
+ * Whether the MX hostname is valid according to policy
1324
+ */
1325
+ valid: boolean;
1326
+
1327
+ /**
1328
+ * Policy mode
1329
+ */
1330
+ mode: string;
1331
+
1332
+ /**
1333
+ * Matching policy pattern (if valid)
1334
+ */
1335
+ match?: string;
1336
+
1337
+ /**
1338
+ * Whether policy is in testing mode
1339
+ */
1340
+ testing: boolean;
1341
+ }
1342
+
1343
+ /**
1344
+ * MTA-STS options
1345
+ */
1346
+ export interface MTASTSOptions {
1347
+ /**
1348
+ * Custom DNS resolver function
1349
+ */
1350
+ resolver?: DNSResolver;
1351
+ }
1352
+
1353
+ // Note: MTA-STS functions (resolvePolicy, fetchPolicy, parsePolicy, validateMx, getPolicy)
1354
+ // are not exported from the main module. Import them directly from 'mailauth/lib/mta-sts'.