mailauth 7.1.1 → 7.3.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/.c8rc.json +11 -0
- package/.prettierignore +3 -0
- package/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +68 -0
- package/README.md +131 -31
- package/bin/mailauth.js +62 -0
- package/cli.md +150 -8
- package/docs/arc.md +62 -54
- package/docs/bimi.md +153 -54
- package/docs/dkim.md +37 -36
- package/docs/dkim2.md +154 -0
- package/docs/dmarc.md +4 -1
- package/docs/mta-sts.md +12 -9
- package/docs/spf.md +14 -13
- package/index.d.ts +583 -42
- package/lib/arc/index.d.ts +6 -2
- package/lib/arc/index.js +45 -15
- package/lib/bimi/index.js +362 -102
- package/lib/bimi/validate-svg.js +493 -60
- package/lib/commands/dkim2-hash.js +25 -0
- package/lib/commands/dkim2-sign.js +77 -0
- package/lib/commands/dkim2-verify.js +59 -0
- package/lib/commands/report.js +10 -35
- package/lib/commands/resolver.js +51 -0
- package/lib/commands/seal.js +10 -38
- package/lib/commands/spf.js +4 -35
- package/lib/dkim/dkim-signer.js +50 -30
- package/lib/dkim/dkim-verifier.js +79 -27
- package/lib/dkim/header/simple.js +2 -2
- package/lib/dkim/sign.js +7 -2
- package/lib/dkim/syntax.js +11 -0
- package/lib/dkim/verify.js +1 -0
- package/lib/dkim2/dkim2-parser.js +52 -0
- package/lib/dkim2/dkim2-signer.js +334 -0
- package/lib/dkim2/dkim2-verifier.js +572 -0
- package/lib/dkim2/fields.js +570 -0
- package/lib/dkim2/hash.d.ts +3 -0
- package/lib/dkim2/hash.js +51 -0
- package/lib/dkim2/key.js +203 -0
- package/lib/dkim2/message-state.js +181 -0
- package/lib/dkim2/recipe.js +134 -0
- package/lib/dkim2/sign.d.ts +3 -0
- package/lib/dkim2/sign.js +38 -0
- package/lib/dkim2/verify.d.ts +3 -0
- package/lib/dkim2/verify.js +19 -0
- package/lib/dmarc/author-domain.js +270 -5
- package/lib/dmarc/get-dmarc-record.js +24 -11
- package/lib/dmarc/verify.js +7 -3
- package/lib/mailauth.js +57 -14
- package/lib/mta-sts.js +37 -11
- package/lib/parse-received.js +214 -25
- package/lib/spf/index.js +21 -4
- package/lib/spf/macro.js +5 -3
- package/lib/spf/spf-verify.js +14 -5
- package/lib/spf/syntax.js +5 -0
- package/lib/tools.js +160 -21
- package/package.json +15 -6
- package/stryker.config.json +16 -0
package/index.d.ts
CHANGED
|
@@ -109,6 +109,24 @@ export interface AuthenticateOptions {
|
|
|
109
109
|
* `warnings` array of the affected result. It is never written into the headers
|
|
110
110
|
*/
|
|
111
111
|
strict?: boolean;
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Verify DKIM2 header fields as well (default: false). Experimental, built against
|
|
115
|
+
* draft-ietf-dkim-dkim2-spec-06. The result is added to Authentication-Results with the
|
|
116
|
+
* `dkim2` method of draft-gondwana-dkim2-authres-00 and does not take part in DMARC
|
|
117
|
+
*/
|
|
118
|
+
dkim2?: boolean;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* RCPT TO addresses of the delivery, checked against the rt= tag of the highest
|
|
122
|
+
* DKIM2-Signature. `sender` is checked against its mf= tag
|
|
123
|
+
*/
|
|
124
|
+
rcptTo?: string | string[];
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Extra DKIM2 verifier options
|
|
128
|
+
*/
|
|
129
|
+
dkim2Options?: Pick<DKIM2VerifyOptions, 'curTime' | 'maxSignatureAge' | 'maxFutureTime' | 'maxInstances' | 'checkReplay'>;
|
|
112
130
|
}
|
|
113
131
|
|
|
114
132
|
/**
|
|
@@ -144,20 +162,22 @@ export interface ARCSealOptions {
|
|
|
144
162
|
/**
|
|
145
163
|
* Chain validation status for the ARC-Seal cv= tag: 'none', 'pass' or 'fail' (compared
|
|
146
164
|
* case-insensitively). Defaults to 'none' for the first set and is required for any later
|
|
147
|
-
* set. `authenticate()` sets it from the ARC validation result
|
|
165
|
+
* set. `authenticate()` always sets it from the ARC validation result and ignores this value
|
|
148
166
|
*/
|
|
149
167
|
cv?: 'none' | 'pass' | 'fail' | string;
|
|
150
168
|
|
|
151
169
|
/**
|
|
152
170
|
* ARC instance (i= tag), 1 to 50. Defaults to one more than the highest instance on the
|
|
153
171
|
* message. An instance that already exists is refused, and one that leaves a gap is
|
|
154
|
-
* refused in strict mode (the default mode seals it and adds an `arc-instance-gap` warning)
|
|
172
|
+
* refused in strict mode (the default mode seals it and adds an `arc-instance-gap` warning).
|
|
173
|
+
* `authenticate()` ignores it and always uses the next instance
|
|
155
174
|
*/
|
|
156
175
|
i?: number;
|
|
157
176
|
|
|
158
177
|
/**
|
|
159
178
|
* Authentication-Results payload for the ARC-Authentication-Results header (the part after
|
|
160
|
-
* "i=N;").
|
|
179
|
+
* "i=N;"). Required, and a line break is only allowed as folding (CRLF followed by a space or
|
|
180
|
+
* tab). `authenticate()` always sets it from its own results and ignores this value
|
|
161
181
|
*/
|
|
162
182
|
authResults?: string;
|
|
163
183
|
|
|
@@ -218,16 +238,20 @@ export interface AuthStatus {
|
|
|
218
238
|
*
|
|
219
239
|
* - `rsa-sha1`: the signature uses rsa-sha1 (RFC 8301 section 3.1)
|
|
220
240
|
* - `tag-syntax`: the signature is not valid tag-list syntax (duplicate tags, upper case tag
|
|
221
|
-
* names, a malformed t=, x= or l= value,
|
|
241
|
+
* names, a malformed c=, t=, x= or l= value, an l= larger than the canonicalized body, or a d=
|
|
242
|
+
* or s= that is not a domain name)
|
|
222
243
|
* - `missing-v`, `missing-h` (and the other `missing-*`): a required tag is missing
|
|
223
244
|
* - `invalid-v`: v= is not "1"
|
|
224
245
|
* - `identity-domain`: the i= domain is not d= or its subdomain, or it is a subdomain while
|
|
225
246
|
* the key has t=s
|
|
226
247
|
* - `invalid-expiration`: x= is equal to t=
|
|
227
248
|
* - `query-method`: q= does not list dns/txt
|
|
228
|
-
* - `key-syntax`: the key record is not valid tag-list syntax
|
|
249
|
+
* - `key-syntax`: the key record is not valid tag-list syntax, or a k=, s= or t= value has
|
|
250
|
+
* whitespace inside it
|
|
229
251
|
* - `key-v-syntax`: the key record v= is not the first tag, or not exactly "DKIM1"
|
|
230
252
|
* - `key-type-inferred`: an ed25519 key was found from its length, without k=ed25519
|
|
253
|
+
* - `key-ed25519-spki`: an ed25519 key was published as a SubjectPublicKeyInfo structure, not
|
|
254
|
+
* as the bare 32 octet key of RFC 8463 section 4.2
|
|
231
255
|
*/
|
|
232
256
|
export type DKIMWarning =
|
|
233
257
|
| 'rsa-sha1'
|
|
@@ -245,7 +269,8 @@ export type DKIMWarning =
|
|
|
245
269
|
| 'query-method'
|
|
246
270
|
| 'key-syntax'
|
|
247
271
|
| 'key-v-syntax'
|
|
248
|
-
| 'key-type-inferred'
|
|
272
|
+
| 'key-type-inferred'
|
|
273
|
+
| 'key-ed25519-spki';
|
|
249
274
|
|
|
250
275
|
/**
|
|
251
276
|
* DKIM verification result for a single signature
|
|
@@ -307,7 +332,8 @@ export interface DKIMResult {
|
|
|
307
332
|
/**
|
|
308
333
|
* Signing domain if it aligns with the From domain, false otherwise. For a passing
|
|
309
334
|
* signature this follows the DMARC verdict once DMARC found a record, before that it
|
|
310
|
-
* only guesses relaxed alignment from the Public Suffix List.
|
|
335
|
+
* only guesses relaxed alignment from the Public Suffix List. Always false when the From
|
|
336
|
+
* header field does not yield a single Author Domain, as DMARC requires.
|
|
311
337
|
*/
|
|
312
338
|
aligned?: string | false;
|
|
313
339
|
|
|
@@ -430,6 +456,14 @@ export interface DKIMVerifyResult {
|
|
|
430
456
|
*/
|
|
431
457
|
fromFields: number;
|
|
432
458
|
|
|
459
|
+
/**
|
|
460
|
+
* Syntax of the From header fields: "valid" (RFC 5322), "lax" (accepted only by the lenient
|
|
461
|
+
* parsing, such as an unquoted comma in a display name) or "invalid" (no reliable addresses,
|
|
462
|
+
* for example text after the angle-addr). DMARC is not evaluated for an "invalid" field, nor
|
|
463
|
+
* for a "lax" one in strict mode
|
|
464
|
+
*/
|
|
465
|
+
fromSyntax: 'valid' | 'lax' | 'invalid';
|
|
466
|
+
|
|
433
467
|
/**
|
|
434
468
|
* Domain from Return-Path header
|
|
435
469
|
*/
|
|
@@ -542,6 +576,10 @@ export interface ARCResult {
|
|
|
542
576
|
* Verification status
|
|
543
577
|
*/
|
|
544
578
|
status: AuthStatus & {
|
|
579
|
+
/**
|
|
580
|
+
* Set for a failed chain: whether it is sealed with cv=fail, false when the newest
|
|
581
|
+
* ARC-Seal on the message already says cv=fail (RFC 8617 section 5.1 step 2)
|
|
582
|
+
*/
|
|
545
583
|
shouldSeal?: boolean;
|
|
546
584
|
};
|
|
547
585
|
|
|
@@ -600,9 +638,11 @@ export interface DMARCResult {
|
|
|
600
638
|
|
|
601
639
|
/**
|
|
602
640
|
* Effective DMARC policy ('none', 'quarantine', 'reject'): p for the author domain's own
|
|
603
|
-
* record, np or sp for an inherited one, one level lower with t=y
|
|
641
|
+
* record, np or sp for an inherited one, one level lower with t=y. Like p, sp, testMode and
|
|
642
|
+
* alignment, only set when a policy record was applied, not for a none result or a
|
|
643
|
+
* temperror before a record was found
|
|
604
644
|
*/
|
|
605
|
-
policy
|
|
645
|
+
policy?: string;
|
|
606
646
|
|
|
607
647
|
/**
|
|
608
648
|
* Domain whose DMARC record the policy was taken from
|
|
@@ -612,12 +652,12 @@ export interface DMARCResult {
|
|
|
612
652
|
/**
|
|
613
653
|
* Policy for organizational domain
|
|
614
654
|
*/
|
|
615
|
-
p
|
|
655
|
+
p?: string;
|
|
616
656
|
|
|
617
657
|
/**
|
|
618
658
|
* Policy for subdomains
|
|
619
659
|
*/
|
|
620
|
-
sp
|
|
660
|
+
sp?: string;
|
|
621
661
|
|
|
622
662
|
/**
|
|
623
663
|
* Policy for non-existent subdomains, if published
|
|
@@ -627,7 +667,7 @@ export interface DMARCResult {
|
|
|
627
667
|
/**
|
|
628
668
|
* True when the record has t=y, in which case policy is one level below the published one
|
|
629
669
|
*/
|
|
630
|
-
testMode
|
|
670
|
+
testMode?: boolean;
|
|
631
671
|
|
|
632
672
|
/**
|
|
633
673
|
* DMARC DNS record
|
|
@@ -640,7 +680,7 @@ export interface DMARCResult {
|
|
|
640
680
|
status: AuthStatus & {
|
|
641
681
|
header?: {
|
|
642
682
|
/**
|
|
643
|
-
* Author Domain
|
|
683
|
+
* Author Domain (RFC 9989 section 9.1 header.from)
|
|
644
684
|
*/
|
|
645
685
|
from?: string;
|
|
646
686
|
|
|
@@ -652,16 +692,16 @@ export interface DMARCResult {
|
|
|
652
692
|
|
|
653
693
|
policy?: {
|
|
654
694
|
/**
|
|
655
|
-
* The policy that was applied (RFC
|
|
695
|
+
* The policy that was applied (RFC 9989 section 9.1 policy.dmarc)
|
|
656
696
|
*/
|
|
657
697
|
dmarc?: string;
|
|
658
698
|
};
|
|
659
699
|
};
|
|
660
700
|
|
|
661
701
|
/**
|
|
662
|
-
* Alignment results
|
|
702
|
+
* Alignment results, set when a policy record was applied
|
|
663
703
|
*/
|
|
664
|
-
alignment
|
|
704
|
+
alignment?: {
|
|
665
705
|
spf: {
|
|
666
706
|
/**
|
|
667
707
|
* Aligned SPF domain, or undefined if no domain aligned
|
|
@@ -729,6 +769,18 @@ export interface BIMIResult {
|
|
|
729
769
|
*/
|
|
730
770
|
authority?: string;
|
|
731
771
|
|
|
772
|
+
/**
|
|
773
|
+
* Avatar preference from the avp= tag, set only for the valid values
|
|
774
|
+
*/
|
|
775
|
+
preference?: 'personal' | 'brand';
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Assertion Record and BIMI-Selector syntax deviations that were accepted because `strict` was not set:
|
|
779
|
+
* 'record-version-case', 'record-tag-case', 'record-syntax', 'uri-comma', 'location-format',
|
|
780
|
+
* 'selector-version-case', 'selector-syntax'
|
|
781
|
+
*/
|
|
782
|
+
warnings?: string[];
|
|
783
|
+
|
|
732
784
|
/**
|
|
733
785
|
* Authentication-Results formatted info
|
|
734
786
|
*/
|
|
@@ -818,6 +870,11 @@ export interface AuthenticateResult {
|
|
|
818
870
|
*/
|
|
819
871
|
dkim: DKIMVerifyResult;
|
|
820
872
|
|
|
873
|
+
/**
|
|
874
|
+
* DKIM2 verification result, false unless the `dkim2` option is set
|
|
875
|
+
*/
|
|
876
|
+
dkim2: DKIM2VerifyResult | false;
|
|
877
|
+
|
|
821
878
|
/**
|
|
822
879
|
* SPF verification result
|
|
823
880
|
*/
|
|
@@ -870,9 +927,9 @@ export function authenticate(input: MessageInput, opts?: AuthenticateOptions): P
|
|
|
870
927
|
// ============================================================================
|
|
871
928
|
|
|
872
929
|
/**
|
|
873
|
-
* DKIM
|
|
930
|
+
* A single DKIM signature to create, an entry of `DKIMSignOptions.signatureData`
|
|
874
931
|
*/
|
|
875
|
-
export interface
|
|
932
|
+
export interface DKIMSignatureData {
|
|
876
933
|
/**
|
|
877
934
|
* Signing domain (d= tag)
|
|
878
935
|
*/
|
|
@@ -884,10 +941,44 @@ export interface DKIMSignOptions {
|
|
|
884
941
|
selector: string;
|
|
885
942
|
|
|
886
943
|
/**
|
|
887
|
-
* Private key for signing (PEM format)
|
|
944
|
+
* Private key for signing (PEM format). An entry without a key is not signed and gets an
|
|
945
|
+
* `ENOKEY` error
|
|
888
946
|
*/
|
|
889
947
|
privateKey: string | Buffer;
|
|
890
948
|
|
|
949
|
+
/**
|
|
950
|
+
* Overrides the shared `canonicalization`
|
|
951
|
+
*/
|
|
952
|
+
canonicalization?: string;
|
|
953
|
+
|
|
954
|
+
/**
|
|
955
|
+
* Overrides the shared `algorithm`
|
|
956
|
+
*/
|
|
957
|
+
algorithm?: string;
|
|
958
|
+
|
|
959
|
+
/**
|
|
960
|
+
* Overrides the shared `headerList`
|
|
961
|
+
*/
|
|
962
|
+
headerList?: string[] | string;
|
|
963
|
+
|
|
964
|
+
/**
|
|
965
|
+
* Maximum body length to sign (l= tag)
|
|
966
|
+
*/
|
|
967
|
+
maxBodyLength?: number;
|
|
968
|
+
|
|
969
|
+
/**
|
|
970
|
+
* Identity (i= tag), an address whose domain is the signing domain or its subdomain.
|
|
971
|
+
* Given unencoded, it is written as dkim-quoted-printable (`jõgi@example.com` as
|
|
972
|
+
* `i=j=C3=B5gi@example.com`)
|
|
973
|
+
*/
|
|
974
|
+
identity?: string;
|
|
975
|
+
}
|
|
976
|
+
|
|
977
|
+
/**
|
|
978
|
+
* DKIM signing options. The values of each signature are set in `signatureData`, the other
|
|
979
|
+
* options apply to all of them
|
|
980
|
+
*/
|
|
981
|
+
export interface DKIMSignOptions {
|
|
891
982
|
/**
|
|
892
983
|
* Canonicalization algorithm (default: 'relaxed/relaxed')
|
|
893
984
|
* Format: 'header/body' where each can be 'simple' or 'relaxed'
|
|
@@ -903,7 +994,9 @@ export interface DKIMSignOptions {
|
|
|
903
994
|
|
|
904
995
|
/**
|
|
905
996
|
* Header fields to sign, as an array or a colon separated string. Default includes
|
|
906
|
-
* From, Subject, Date, To, etc. Set per signature in `signatureData` or for all of them
|
|
997
|
+
* From, Subject, Date, To, etc. Set per signature in `signatureData` or for all of them.
|
|
998
|
+
* A name listed more than once is over-signed: it appears in h= as many times as it is
|
|
999
|
+
* listed or as the message has that field, whichever is more (`'From:From'`)
|
|
907
1000
|
*/
|
|
908
1001
|
headerList?: string[] | string;
|
|
909
1002
|
|
|
@@ -918,19 +1011,10 @@ export interface DKIMSignOptions {
|
|
|
918
1011
|
expires?: Date | string | number;
|
|
919
1012
|
|
|
920
1013
|
/**
|
|
921
|
-
*
|
|
1014
|
+
* The signatures to create. Without any, nothing is signed and `errors` holds an
|
|
1015
|
+
* `ENOSIGNATURE` error
|
|
922
1016
|
*/
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
/**
|
|
926
|
-
* Identity (i= tag), an address whose domain is the signing domain or its subdomain
|
|
927
|
-
*/
|
|
928
|
-
identity?: string;
|
|
929
|
-
|
|
930
|
-
/**
|
|
931
|
-
* Multiple signature configurations
|
|
932
|
-
*/
|
|
933
|
-
signatureData?: DKIMSignOptions[];
|
|
1017
|
+
signatureData: DKIMSignatureData[];
|
|
934
1018
|
|
|
935
1019
|
/**
|
|
936
1020
|
* Follow the RFCs exactly (default: false). Strict mode refuses rsa-sha1, RSA keys
|
|
@@ -1119,7 +1203,7 @@ export interface DKIMSignError {
|
|
|
1119
1203
|
/**
|
|
1120
1204
|
* Why the signature was not created. `err.code` is eg. 'ENOFROM', 'EINVALIDALGO',
|
|
1121
1205
|
* 'EINVALIDTYPE', 'ESHORTKEY', 'EINVALIDDOMAIN', 'EINVALIDSELECTOR', 'EINVALIDIDENTITY',
|
|
1122
|
-
* 'EINVALIDTIME', 'EINVALIDCANON' or '
|
|
1206
|
+
* 'EINVALIDTIME', 'EINVALIDCANON', 'EINVALIDINSTANCE', 'ENOKEY' or 'ENOSIGNATURE'
|
|
1123
1207
|
*/
|
|
1124
1208
|
err: Error & { code?: string };
|
|
1125
1209
|
|
|
@@ -1138,9 +1222,11 @@ export interface DKIMSignError {
|
|
|
1138
1222
|
* - `invalid-expiration`: the expiration is not after the signing time, or does not fit into x=
|
|
1139
1223
|
* - `invalid-signtime`: the signing time does not fit into t=, which was left out
|
|
1140
1224
|
* - `d-syntax`, `s-syntax`: d= or s= is not valid RFC 6376 syntax
|
|
1225
|
+
* - `identity-syntax`: the identity is not valid RFC 6376 i= syntax
|
|
1141
1226
|
* - `identity-domain`: the identity domain is not the signing domain or its subdomain
|
|
1142
1227
|
*/
|
|
1143
|
-
export type DKIMSignWarning =
|
|
1228
|
+
export type DKIMSignWarning =
|
|
1229
|
+
'rsa-sha1' | 'weak-key' | 'invalid-expiration' | 'invalid-signtime' | 'd-syntax' | 's-syntax' | 'identity-syntax' | 'identity-domain';
|
|
1144
1230
|
|
|
1145
1231
|
/**
|
|
1146
1232
|
* DKIM signing result
|
|
@@ -1255,6 +1341,342 @@ export interface DKIMVerifyOptions {
|
|
|
1255
1341
|
*/
|
|
1256
1342
|
export function dkimVerify(input: MessageInput, options?: DKIMVerifyOptions): Promise<DKIMVerifyResult>;
|
|
1257
1343
|
|
|
1344
|
+
// ============================================================================
|
|
1345
|
+
// DKIM2 (experimental, draft-ietf-dkim-dkim2-spec-06, draft-ietf-dkim-dkim2-dns-00)
|
|
1346
|
+
// ============================================================================
|
|
1347
|
+
|
|
1348
|
+
/**
|
|
1349
|
+
* A DKIM2 Recipe (draft-ietf-dkim-dkim2-spec-06 section 5). Each step either copies a range of
|
|
1350
|
+
* header fields (numbered from the bottom) or body lines (numbered from the top), or emits data
|
|
1351
|
+
*/
|
|
1352
|
+
export type DKIM2RecipeStep = { c: [number, number] } | { d: string[] };
|
|
1353
|
+
|
|
1354
|
+
export interface DKIM2Recipe {
|
|
1355
|
+
/**
|
|
1356
|
+
* Steps per lower case header field name. An empty array removes every field of that name
|
|
1357
|
+
*/
|
|
1358
|
+
h?: Record<string, DKIM2RecipeStep[]>;
|
|
1359
|
+
|
|
1360
|
+
/**
|
|
1361
|
+
* Steps for the body, or null when the previous body can not be recreated
|
|
1362
|
+
*/
|
|
1363
|
+
b?: DKIM2RecipeStep[] | null;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
export interface DKIM2SignatureKey {
|
|
1367
|
+
/**
|
|
1368
|
+
* Key selector
|
|
1369
|
+
*/
|
|
1370
|
+
selector: string;
|
|
1371
|
+
|
|
1372
|
+
/**
|
|
1373
|
+
* Private key, PEM or a raw 32 byte Ed25519 key
|
|
1374
|
+
*/
|
|
1375
|
+
privateKey: string | Buffer;
|
|
1376
|
+
|
|
1377
|
+
/**
|
|
1378
|
+
* "rsa-sha256" or "ed25519-sha256", follows the key type when not set
|
|
1379
|
+
*/
|
|
1380
|
+
algorithm?: 'rsa-sha256' | 'ed25519-sha256';
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
/**
|
|
1384
|
+
* DKIM2 signing options
|
|
1385
|
+
*/
|
|
1386
|
+
export interface DKIM2SignOptions {
|
|
1387
|
+
/**
|
|
1388
|
+
* Signing domain (d= tag)
|
|
1389
|
+
*/
|
|
1390
|
+
signingDomain: string;
|
|
1391
|
+
|
|
1392
|
+
/**
|
|
1393
|
+
* Signing keys. At most two keys per algorithm, each with its own selector
|
|
1394
|
+
*/
|
|
1395
|
+
signatureData?: DKIM2SignatureKey[];
|
|
1396
|
+
|
|
1397
|
+
/**
|
|
1398
|
+
* Selector of a single key, used with `privateKey` when `signatureData` is not set
|
|
1399
|
+
*/
|
|
1400
|
+
selector?: string;
|
|
1401
|
+
|
|
1402
|
+
/**
|
|
1403
|
+
* A single private key, used with `selector` when `signatureData` is not set
|
|
1404
|
+
*/
|
|
1405
|
+
privateKey?: string | Buffer;
|
|
1406
|
+
|
|
1407
|
+
/**
|
|
1408
|
+
* Algorithm of the single key
|
|
1409
|
+
*/
|
|
1410
|
+
algorithm?: 'rsa-sha256' | 'ed25519-sha256';
|
|
1411
|
+
|
|
1412
|
+
/**
|
|
1413
|
+
* SMTP MAIL FROM the message is sent with (mf= tag), "" or "<>" for the null sender.
|
|
1414
|
+
* Required unless `nextDomain` is set
|
|
1415
|
+
*/
|
|
1416
|
+
mailFrom?: string;
|
|
1417
|
+
|
|
1418
|
+
/**
|
|
1419
|
+
* SMTP RCPT TO addresses the message is sent to (rt= tag). Required unless `nextDomain` is set
|
|
1420
|
+
*/
|
|
1421
|
+
rcptTo?: string | string[];
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* Domain of the next DKIM2-Signature for an imaginary hop (nd= tag), instead of mailFrom and rcptTo
|
|
1425
|
+
*/
|
|
1426
|
+
nextDomain?: string;
|
|
1427
|
+
|
|
1428
|
+
/**
|
|
1429
|
+
* Nonce (n= tag), at most 64 printable ASCII characters without ";"
|
|
1430
|
+
*/
|
|
1431
|
+
nonce?: string;
|
|
1432
|
+
|
|
1433
|
+
/**
|
|
1434
|
+
* Flags (f= tag), such as "donotmodify", "donotexplode", "exploded", "feedback" or "feedhere"
|
|
1435
|
+
*/
|
|
1436
|
+
flags?: string[];
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* Hash algorithms of a new Message-Instance (default: ["sha256"])
|
|
1440
|
+
*/
|
|
1441
|
+
hashAlgorithms?: ('sha256' | 'sha512')[];
|
|
1442
|
+
|
|
1443
|
+
/**
|
|
1444
|
+
* Recipe that recreates the previous instance of a message that was changed since its
|
|
1445
|
+
* highest Message-Instance. It is checked against that instance before signing
|
|
1446
|
+
*/
|
|
1447
|
+
recipe?: DKIM2Recipe;
|
|
1448
|
+
|
|
1449
|
+
/**
|
|
1450
|
+
* Signing time (t= tag), defaults to now
|
|
1451
|
+
*/
|
|
1452
|
+
signTime?: Date | string | number;
|
|
1453
|
+
}
|
|
1454
|
+
|
|
1455
|
+
/**
|
|
1456
|
+
* DKIM2 signing result
|
|
1457
|
+
*/
|
|
1458
|
+
export interface DKIM2SignResult {
|
|
1459
|
+
/**
|
|
1460
|
+
* Header fields to prepend to the message, each ending with CRLF
|
|
1461
|
+
*/
|
|
1462
|
+
signatures: string;
|
|
1463
|
+
|
|
1464
|
+
/**
|
|
1465
|
+
* The new DKIM2-Signature header field
|
|
1466
|
+
*/
|
|
1467
|
+
signature: string;
|
|
1468
|
+
|
|
1469
|
+
/**
|
|
1470
|
+
* The new Message-Instance header field, null when the message did not change
|
|
1471
|
+
*/
|
|
1472
|
+
messageInstance: string | null;
|
|
1473
|
+
|
|
1474
|
+
/**
|
|
1475
|
+
* i= of the new signature
|
|
1476
|
+
*/
|
|
1477
|
+
i: number;
|
|
1478
|
+
|
|
1479
|
+
/**
|
|
1480
|
+
* m= of the new signature
|
|
1481
|
+
*/
|
|
1482
|
+
m: number;
|
|
1483
|
+
}
|
|
1484
|
+
|
|
1485
|
+
/**
|
|
1486
|
+
* Signs a message with DKIM2. Rejects for invalid options, an invalid DKIM2 chain on the
|
|
1487
|
+
* message, or a recipe that does not recreate the previous instance
|
|
1488
|
+
*/
|
|
1489
|
+
export function dkim2Sign(input: MessageInput, options: DKIM2SignOptions): Promise<DKIM2SignResult>;
|
|
1490
|
+
|
|
1491
|
+
/**
|
|
1492
|
+
* Transform stream that prepends the DKIM2 header fields to the message
|
|
1493
|
+
*/
|
|
1494
|
+
export class Dkim2SignStream extends Transform {
|
|
1495
|
+
constructor(options: DKIM2SignOptions);
|
|
1496
|
+
}
|
|
1497
|
+
|
|
1498
|
+
/**
|
|
1499
|
+
* DKIM2 verification options
|
|
1500
|
+
*/
|
|
1501
|
+
export interface DKIM2VerifyOptions {
|
|
1502
|
+
/**
|
|
1503
|
+
* Custom DNS resolver function
|
|
1504
|
+
*/
|
|
1505
|
+
resolver?: DNSResolver;
|
|
1506
|
+
|
|
1507
|
+
/**
|
|
1508
|
+
* SMTP MAIL FROM of the delivery, "" for the null sender. Compared with mf= of the highest
|
|
1509
|
+
* DKIM2-Signature when set
|
|
1510
|
+
*/
|
|
1511
|
+
mailFrom?: string;
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* SMTP RCPT TO addresses of the delivery, each of which has to be listed in rt= of the highest
|
|
1515
|
+
* DKIM2-Signature
|
|
1516
|
+
*/
|
|
1517
|
+
rcptTo?: string | string[];
|
|
1518
|
+
|
|
1519
|
+
/**
|
|
1520
|
+
* Seconds after t= when a signature expires (default: 1209600, 14 days), false to not check
|
|
1521
|
+
*/
|
|
1522
|
+
maxSignatureAge?: number | false;
|
|
1523
|
+
|
|
1524
|
+
/**
|
|
1525
|
+
* Seconds a t= may be ahead of the current time (default: 300), false to not check. Section 8.4
|
|
1526
|
+
* allows ignoring signatures from the future
|
|
1527
|
+
*/
|
|
1528
|
+
maxFutureTime?: number | false;
|
|
1529
|
+
|
|
1530
|
+
/**
|
|
1531
|
+
* Time to verify against (default: now)
|
|
1532
|
+
*/
|
|
1533
|
+
curTime?: Date | string | number;
|
|
1534
|
+
|
|
1535
|
+
/**
|
|
1536
|
+
* Most Message-Instance, and most DKIM2-Signature, header fields processed (default: 20)
|
|
1537
|
+
*/
|
|
1538
|
+
maxInstances?: number;
|
|
1539
|
+
|
|
1540
|
+
/**
|
|
1541
|
+
* Called with the replay key (the m=1 hashes) of the message. Return true when a message with
|
|
1542
|
+
* the same key was seen before; without an exploded flag the result is then FAIL
|
|
1543
|
+
*/
|
|
1544
|
+
checkReplay?: (replay: { key: string; exploded: boolean }) => Promise<boolean> | boolean;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
export type DKIM2Result = 'pass' | 'fail' | 'permerror' | 'temperror';
|
|
1548
|
+
|
|
1549
|
+
export type DKIM2Warning = 'mail-from-not-checked' | 'rcpt-to-not-checked';
|
|
1550
|
+
|
|
1551
|
+
export interface DKIM2Error {
|
|
1552
|
+
result: DKIM2Result;
|
|
1553
|
+
|
|
1554
|
+
/**
|
|
1555
|
+
* Human-readable string of draft-ietf-dkim-dkim2-spec-06 section 11
|
|
1556
|
+
*/
|
|
1557
|
+
message: string;
|
|
1558
|
+
|
|
1559
|
+
/**
|
|
1560
|
+
* i= of the DKIM2-Signature the error is reported against
|
|
1561
|
+
*/
|
|
1562
|
+
i?: number;
|
|
1563
|
+
|
|
1564
|
+
/**
|
|
1565
|
+
* m= of the Message-Instance the error is about
|
|
1566
|
+
*/
|
|
1567
|
+
m?: number;
|
|
1568
|
+
}
|
|
1569
|
+
|
|
1570
|
+
export interface DKIM2InstanceResult {
|
|
1571
|
+
m: number;
|
|
1572
|
+
hashes: { algorithm: string; header: 'pass' | 'fail'; body: 'pass' | 'fail' | 'unknown' }[];
|
|
1573
|
+
recipe?: { headers: string[]; body: 'unchanged' | 'recipe' | 'unrecoverable' };
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
export interface DKIM2SignatureValueResult {
|
|
1577
|
+
selector: string;
|
|
1578
|
+
algorithm: string;
|
|
1579
|
+
|
|
1580
|
+
/**
|
|
1581
|
+
* "none" for an algorithm that is not supported and ignored
|
|
1582
|
+
*/
|
|
1583
|
+
result?: DKIM2Result | 'none';
|
|
1584
|
+
comment?: string;
|
|
1585
|
+
rr?: string;
|
|
1586
|
+
modulusLength?: number;
|
|
1587
|
+
|
|
1588
|
+
/**
|
|
1589
|
+
* The key record has the t=y testing flag
|
|
1590
|
+
*/
|
|
1591
|
+
testing?: boolean;
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
export interface DKIM2SignatureResult {
|
|
1595
|
+
i: number;
|
|
1596
|
+
m: number;
|
|
1597
|
+
signingDomain: string;
|
|
1598
|
+
timestamp: number;
|
|
1599
|
+
signTime: string;
|
|
1600
|
+
flags: string[];
|
|
1601
|
+
mailFrom?: string;
|
|
1602
|
+
rcptTo?: string[];
|
|
1603
|
+
nextDomain?: string;
|
|
1604
|
+
nonce?: string;
|
|
1605
|
+
status: { result: DKIM2Result | 'skipped'; comment?: string };
|
|
1606
|
+
values: DKIM2SignatureValueResult[];
|
|
1607
|
+
}
|
|
1608
|
+
|
|
1609
|
+
/**
|
|
1610
|
+
* DKIM2 verification result
|
|
1611
|
+
*/
|
|
1612
|
+
export interface DKIM2VerifyResult {
|
|
1613
|
+
status: {
|
|
1614
|
+
result: DKIM2Result | 'none';
|
|
1615
|
+
|
|
1616
|
+
/**
|
|
1617
|
+
* The human-readable string of the reported failure
|
|
1618
|
+
*/
|
|
1619
|
+
comment?: string;
|
|
1620
|
+
header?: { d?: string; i?: number };
|
|
1621
|
+
|
|
1622
|
+
/**
|
|
1623
|
+
* The parts of the SMTP envelope that were not given, so the highest DKIM2-Signature was
|
|
1624
|
+
* not compared with them and an unchanged copy sent to someone else would pass as well.
|
|
1625
|
+
* Only present when there is something to report, never written into `info`
|
|
1626
|
+
*/
|
|
1627
|
+
warnings?: DKIM2Warning[];
|
|
1628
|
+
};
|
|
1629
|
+
|
|
1630
|
+
/**
|
|
1631
|
+
* Authentication-Results resinfo
|
|
1632
|
+
*/
|
|
1633
|
+
info: string;
|
|
1634
|
+
errors: DKIM2Error[];
|
|
1635
|
+
instances: DKIM2InstanceResult[];
|
|
1636
|
+
signatures: DKIM2SignatureResult[];
|
|
1637
|
+
|
|
1638
|
+
/**
|
|
1639
|
+
* The key for replay detection and whether a signature allows copies
|
|
1640
|
+
*/
|
|
1641
|
+
replay?: { key: string; exploded: boolean };
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
/**
|
|
1645
|
+
* DKIM2 hashing options
|
|
1646
|
+
*/
|
|
1647
|
+
export interface DKIM2HashOptions {
|
|
1648
|
+
/**
|
|
1649
|
+
* Hash algorithms (default: ["sha256"])
|
|
1650
|
+
*/
|
|
1651
|
+
algorithms?: ('sha256' | 'sha512')[];
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
/**
|
|
1655
|
+
* DKIM2 hashes of a message
|
|
1656
|
+
*/
|
|
1657
|
+
export interface DKIM2HashResult {
|
|
1658
|
+
/**
|
|
1659
|
+
* Names of the hashed header fields, in the order they are hashed
|
|
1660
|
+
*/
|
|
1661
|
+
headers: string[];
|
|
1662
|
+
|
|
1663
|
+
/**
|
|
1664
|
+
* The hash-sets of the h= tag of a Message-Instance
|
|
1665
|
+
*/
|
|
1666
|
+
hashes: { algorithm: 'sha256' | 'sha512'; headerHash: string; bodyHash: string }[];
|
|
1667
|
+
}
|
|
1668
|
+
|
|
1669
|
+
/**
|
|
1670
|
+
* Computes the DKIM2 header and body hashes of a message, as they go into the h= tag of a
|
|
1671
|
+
* Message-Instance header field. Rejects for an unsupported hash algorithm
|
|
1672
|
+
*/
|
|
1673
|
+
export function dkim2Hash(input: MessageInput, options?: DKIM2HashOptions): Promise<DKIM2HashResult>;
|
|
1674
|
+
|
|
1675
|
+
/**
|
|
1676
|
+
* Verifies the DKIM2 header fields of a message
|
|
1677
|
+
*/
|
|
1678
|
+
export function dkim2Verify(input: MessageInput, options?: DKIM2VerifyOptions): Promise<DKIM2VerifyResult>;
|
|
1679
|
+
|
|
1258
1680
|
// ============================================================================
|
|
1259
1681
|
// SPF
|
|
1260
1682
|
// ============================================================================
|
|
@@ -1337,6 +1759,13 @@ export interface DMARCOptions {
|
|
|
1337
1759
|
*/
|
|
1338
1760
|
fromFields?: number;
|
|
1339
1761
|
|
|
1762
|
+
/**
|
|
1763
|
+
* Syntax of the From header field the addresses came from (see DKIMVerifyResult.fromSyntax).
|
|
1764
|
+
* With "invalid", or "lax" in strict mode, DMARC validation is not possible (reason
|
|
1765
|
+
* "invalid-author-domain"). "lax" adds the "from-syntax" warning in the default mode
|
|
1766
|
+
*/
|
|
1767
|
+
fromSyntax?: 'valid' | 'lax' | 'invalid';
|
|
1768
|
+
|
|
1340
1769
|
/**
|
|
1341
1770
|
* Domains that passed SPF
|
|
1342
1771
|
*/
|
|
@@ -1398,6 +1827,13 @@ export interface ARCData {
|
|
|
1398
1827
|
* Error encountered during ARC chain parsing
|
|
1399
1828
|
*/
|
|
1400
1829
|
error?: Error;
|
|
1830
|
+
|
|
1831
|
+
/**
|
|
1832
|
+
* The lower case cv= of the newest ARC-Seal in the header fields, or false if there is
|
|
1833
|
+
* none, set by the DKIM verifier. Read from the header fields even when the chain could not
|
|
1834
|
+
* be parsed, to decide whether a failed chain is sealed with cv=fail
|
|
1835
|
+
*/
|
|
1836
|
+
latestCv?: string | false;
|
|
1401
1837
|
}
|
|
1402
1838
|
|
|
1403
1839
|
/**
|
|
@@ -1409,7 +1845,9 @@ export interface ARCSealError {
|
|
|
1409
1845
|
* instance out of 1-50, a chain that already has 50 sets, one that already exists, or in
|
|
1410
1846
|
* strict mode one that leaves a gap),
|
|
1411
1847
|
* EARCCHAINFAILED (the newest ARC-Seal already has cv=fail, RFC 8617 section 5.1 step 2),
|
|
1412
|
-
* EINVALIDALGO and EINVALIDTYPE (an algorithm that is not supported or does not match the key)
|
|
1848
|
+
* EINVALIDALGO and EINVALIDTYPE (an algorithm that is not supported or does not match the key),
|
|
1849
|
+
* EINVALIDAUTHRESULTS (a missing or empty authResults, or one with a line break that is not
|
|
1850
|
+
* CRLF folding)
|
|
1413
1851
|
*/
|
|
1414
1852
|
err: Error & { code?: string };
|
|
1415
1853
|
type?: string;
|
|
@@ -1516,11 +1954,14 @@ export function verifyASChain(data: ARCData, opts: ARCOptions & { warnings?: str
|
|
|
1516
1954
|
*
|
|
1517
1955
|
* @param input - RFC822 formatted message or false for pre-calculated data
|
|
1518
1956
|
* @param data - Seal creation data
|
|
1519
|
-
* @returns Seal headers (empty when no set was created), the errors that say why,
|
|
1957
|
+
* @returns Seal headers (empty when no set was created), the errors that say why, what the
|
|
1520
1958
|
* default mode sealed that strict mode would have refused ('arc-instance-gap',
|
|
1521
|
-
* 'arc-cv-instance', and the DKIM signing warnings)
|
|
1959
|
+
* 'arc-cv-instance', and the DKIM signing warnings), and the instance (i=) of a created set
|
|
1522
1960
|
*/
|
|
1523
|
-
export function createSeal(
|
|
1961
|
+
export function createSeal(
|
|
1962
|
+
input: MessageInput | false,
|
|
1963
|
+
data: ARCCreateSealData
|
|
1964
|
+
): Promise<{ headers: string[]; errors: ARCSealError[]; warnings: string[]; instance?: number }>;
|
|
1524
1965
|
|
|
1525
1966
|
// ============================================================================
|
|
1526
1967
|
// BIMI
|
|
@@ -1551,8 +1992,10 @@ export interface BIMIOptions {
|
|
|
1551
1992
|
resolver?: DNSResolver;
|
|
1552
1993
|
|
|
1553
1994
|
/**
|
|
1554
|
-
*
|
|
1555
|
-
*
|
|
1995
|
+
* Parse the Assertion Record exactly (default: false): `v=BIMI1` and the tag names are
|
|
1996
|
+
* case-sensitive, syntax errors such as duplicate tags fail the record, and so do an `l=` URI with
|
|
1997
|
+
* another image format suffix and unencoded commas in URIs. Without it these are accepted and
|
|
1998
|
+
* reported in `warnings`. Also formats the Authentication-Results entry in the RFC 8601 section 2.2 form
|
|
1556
1999
|
*/
|
|
1557
2000
|
strict?: boolean;
|
|
1558
2001
|
}
|
|
@@ -1589,6 +2032,11 @@ export interface VMCValidationResult {
|
|
|
1589
2032
|
*/
|
|
1590
2033
|
code?: string;
|
|
1591
2034
|
|
|
2035
|
+
/**
|
|
2036
|
+
* Additional error details, for `SVG_VALIDATION_FAILED` the message and code of the SVG validation error
|
|
2037
|
+
*/
|
|
2038
|
+
details?: any;
|
|
2039
|
+
|
|
1592
2040
|
/**
|
|
1593
2041
|
* Redirect URL if logo location redirected
|
|
1594
2042
|
*/
|
|
@@ -1596,7 +2044,8 @@ export interface VMCValidationResult {
|
|
|
1596
2044
|
};
|
|
1597
2045
|
|
|
1598
2046
|
/**
|
|
1599
|
-
* Base64-encoded SVG logo file content
|
|
2047
|
+
* Base64-encoded SVG logo file content, uncompressed if the file was SVGZ. Set only when the
|
|
2048
|
+
* file passed SVG validation
|
|
1600
2049
|
*/
|
|
1601
2050
|
logoFile?: string;
|
|
1602
2051
|
|
|
@@ -1665,6 +2114,44 @@ export interface VMCValidationResult {
|
|
|
1665
2114
|
*/
|
|
1666
2115
|
hashMatch?: boolean;
|
|
1667
2116
|
};
|
|
2117
|
+
|
|
2118
|
+
/**
|
|
2119
|
+
* The BIMI status of `bimiData` updated with the validation results (7.7): `fail` with a comment
|
|
2120
|
+
* when the indicator or the evidence document failed, `policy.authority` set to `pass` or `fail`
|
|
2121
|
+
* when an evidence document was checked. Set only when `bimiData.status.result` was `pass`
|
|
2122
|
+
*/
|
|
2123
|
+
status?: BIMIResult['status'];
|
|
2124
|
+
|
|
2125
|
+
/**
|
|
2126
|
+
* Authentication-Results entry for the updated status, use it instead of the `info` of `bimi()`
|
|
2127
|
+
*/
|
|
2128
|
+
info?: string;
|
|
2129
|
+
|
|
2130
|
+
/**
|
|
2131
|
+
* SVG Tiny PS profile deviations of the logo files that were accepted because `strict` was not set,
|
|
2132
|
+
* for example 'svg-version'
|
|
2133
|
+
*/
|
|
2134
|
+
warnings?: string[];
|
|
2135
|
+
|
|
2136
|
+
/**
|
|
2137
|
+
* BIMI headers for the message, set only when the logo and the evidence document (if any) validated
|
|
2138
|
+
*/
|
|
2139
|
+
headers?: {
|
|
2140
|
+
/**
|
|
2141
|
+
* BIMI-Indicator header with the base64-encoded SVG logo
|
|
2142
|
+
*/
|
|
2143
|
+
indicator: string;
|
|
2144
|
+
|
|
2145
|
+
/**
|
|
2146
|
+
* BIMI-Location header, with a= when the evidence document was verified
|
|
2147
|
+
*/
|
|
2148
|
+
location: string;
|
|
2149
|
+
|
|
2150
|
+
/**
|
|
2151
|
+
* BIMI-Logo-Preference header
|
|
2152
|
+
*/
|
|
2153
|
+
preference?: string;
|
|
2154
|
+
};
|
|
1668
2155
|
}
|
|
1669
2156
|
|
|
1670
2157
|
/**
|
|
@@ -1679,6 +2166,33 @@ export interface BIMIData extends BIMIResult {
|
|
|
1679
2166
|
* VMC validation options
|
|
1680
2167
|
*/
|
|
1681
2168
|
export interface VMCValidationOptions {
|
|
2169
|
+
/**
|
|
2170
|
+
* Validate the logo files exactly against the SVG Tiny PS profile (default: false). Without it,
|
|
2171
|
+
* the deviations that do not make a logo unsafe are accepted and listed in `warnings`. Also
|
|
2172
|
+
* formats `info` in the RFC 8601 section 2.2 form
|
|
2173
|
+
*/
|
|
2174
|
+
strict?: boolean;
|
|
2175
|
+
|
|
2176
|
+
/**
|
|
2177
|
+
* Maximum size of the logo file in bytes, also applied to an uncompressed SVGZ file (default: 65536)
|
|
2178
|
+
*/
|
|
2179
|
+
maxLogoSize?: number;
|
|
2180
|
+
|
|
2181
|
+
/**
|
|
2182
|
+
* Maximum size of the evidence document in bytes (default: 262144)
|
|
2183
|
+
*/
|
|
2184
|
+
maxEvidenceSize?: number;
|
|
2185
|
+
|
|
2186
|
+
/**
|
|
2187
|
+
* Time limit for each download in milliseconds, including redirects and the body (default: 30000)
|
|
2188
|
+
*/
|
|
2189
|
+
timeout?: number;
|
|
2190
|
+
|
|
2191
|
+
/**
|
|
2192
|
+
* undici Dispatcher used for the downloads
|
|
2193
|
+
*/
|
|
2194
|
+
dispatcher?: any;
|
|
2195
|
+
|
|
1682
2196
|
/**
|
|
1683
2197
|
* Custom VMC validation options passed to @postalsys/vmc
|
|
1684
2198
|
*/
|
|
@@ -1702,13 +2216,30 @@ export function bimi(opts: BIMIOptions): Promise<BIMIResult | false>;
|
|
|
1702
2216
|
*/
|
|
1703
2217
|
export function validateBimiVmc(bimiData: BIMIData | null, opts?: VMCValidationOptions): Promise<VMCValidationResult | false>;
|
|
1704
2218
|
|
|
2219
|
+
/**
|
|
2220
|
+
* SVG logo validation options
|
|
2221
|
+
*/
|
|
2222
|
+
export interface BIMISvgValidationOptions {
|
|
2223
|
+
/**
|
|
2224
|
+
* Apply the SVG Tiny PS profile exactly (default: false)
|
|
2225
|
+
*/
|
|
2226
|
+
strict?: boolean;
|
|
2227
|
+
|
|
2228
|
+
/**
|
|
2229
|
+
* Markers of the accepted profile deviations are added to this array when `strict` is not set
|
|
2230
|
+
*/
|
|
2231
|
+
warnings?: string[];
|
|
2232
|
+
}
|
|
2233
|
+
|
|
1705
2234
|
/**
|
|
1706
2235
|
* Validates BIMI SVG logo file
|
|
1707
2236
|
*
|
|
1708
2237
|
* @param logo - SVG logo file buffer
|
|
2238
|
+
* @param opts - validation options
|
|
2239
|
+
* @returns true
|
|
1709
2240
|
* @throws Error if validation fails
|
|
1710
2241
|
*/
|
|
1711
|
-
export function validateBimiSvg(logo: Buffer):
|
|
2242
|
+
export function validateBimiSvg(logo: Buffer | string, opts?: BIMISvgValidationOptions): true;
|
|
1712
2243
|
|
|
1713
2244
|
// ============================================================================
|
|
1714
2245
|
// MTA-STS
|
|
@@ -1752,6 +2283,16 @@ export interface MTASTSPolicy {
|
|
|
1752
2283
|
* Error encountered during policy fetch
|
|
1753
2284
|
*/
|
|
1754
2285
|
error?: Error;
|
|
2286
|
+
|
|
2287
|
+
/**
|
|
2288
|
+
* Policy ID from DNS that could not be fetched, set on a cached policy that is kept in use instead
|
|
2289
|
+
*/
|
|
2290
|
+
retryId?: string;
|
|
2291
|
+
|
|
2292
|
+
/**
|
|
2293
|
+
* ISO 8601 timestamp before which the policy for `retryId` is not fetched again (RFC 8461 3.3)
|
|
2294
|
+
*/
|
|
2295
|
+
retryAfter?: string;
|
|
1755
2296
|
}
|
|
1756
2297
|
|
|
1757
2298
|
/**
|