mailauth 4.11.0 → 4.12.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/.ncurc.js +0 -1
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +19 -0
- package/README.md +3 -0
- package/cli.md +3 -0
- package/eslint.config.js +7 -4
- package/index.d.ts +1354 -0
- package/lib/arc/index.d.ts +47 -0
- package/lib/bimi/index.d.ts +20 -0
- package/lib/dkim/sign.d.ts +33 -0
- package/lib/dkim/verify.d.ts +12 -0
- package/lib/dmarc/index.d.ts +11 -0
- package/lib/mailauth.js +13 -3
- package/lib/mta-sts.d.ts +52 -0
- package/lib/mta-sts.js +1 -1
- package/lib/spf/index.d.ts +11 -0
- package/package.json +13 -12
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'.
|