mailauth 4.13.1 → 4.13.3
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/.release-please-manifest.json +1 -1
- package/CHANGELOG.md +14 -0
- package/CLAUDE.md +66 -0
- package/docs/arc.md +89 -89
- package/docs/bimi.md +154 -153
- package/docs/dkim.md +137 -137
- package/docs/dmarc.md +128 -128
- package/docs/mta-sts.md +90 -97
- package/docs/spf.md +122 -122
- package/lib/dkim/body/relaxed.js +2 -2
- package/package.json +10 -10
package/docs/bimi.md
CHANGED
|
@@ -18,73 +18,73 @@ const { bimi } = await authenticate(message, {
|
|
|
18
18
|
|
|
19
19
|
## Result Object Fields
|
|
20
20
|
|
|
21
|
-
| Field
|
|
22
|
-
|
|
23
|
-
| `status`
|
|
24
|
-
| `location`
|
|
25
|
-
| `authority`
|
|
26
|
-
| `preference` | `string` | When `p=` present | Logo preference value from DNS record
|
|
27
|
-
| `rr`
|
|
28
|
-
| `info`
|
|
21
|
+
| Field | Type | Presence | Description |
|
|
22
|
+
| ------------ | -------- | ----------------- | ----------------------------------------------------- |
|
|
23
|
+
| `status` | `object` | Always | Resolution status object (see below) |
|
|
24
|
+
| `location` | `string` | Found | HTTPS URL for the logo SVG file (from `l=` tag) |
|
|
25
|
+
| `authority` | `string` | Found | HTTPS URL for the VMC/CMC certificate (from `a=` tag) |
|
|
26
|
+
| `preference` | `string` | When `p=` present | Logo preference value from DNS record |
|
|
27
|
+
| `rr` | `string` | Found | Raw BIMI DNS TXT record |
|
|
28
|
+
| `info` | `string` | Always | Formatted Authentication-Results header value |
|
|
29
29
|
|
|
30
30
|
## status Object
|
|
31
31
|
|
|
32
|
-
| Field
|
|
33
|
-
|
|
34
|
-
| `result`
|
|
35
|
-
| `comment` | `string` | On skip/fail | Reason for skip or failure
|
|
36
|
-
| `header`
|
|
37
|
-
| `policy`
|
|
32
|
+
| Field | Type | Presence | Description |
|
|
33
|
+
| --------- | -------- | ------------ | ---------------------------- |
|
|
34
|
+
| `result` | `string` | Always | BIMI result code (see below) |
|
|
35
|
+
| `comment` | `string` | On skip/fail | Reason for skip or failure |
|
|
36
|
+
| `header` | `object` | Always | Header information |
|
|
37
|
+
| `policy` | `object` | VMC found | Authority policy details |
|
|
38
38
|
|
|
39
39
|
### status.header Object
|
|
40
40
|
|
|
41
|
-
| Field
|
|
42
|
-
|
|
41
|
+
| Field | Type | Presence | Description |
|
|
42
|
+
| ---------- | -------- | ------------ | -------------------------------------- |
|
|
43
43
|
| `selector` | `string` | Record found | BIMI selector used (e.g., `"default"`) |
|
|
44
|
-
| `d`
|
|
44
|
+
| `d` | `string` | Record found | Domain where BIMI record was found |
|
|
45
45
|
|
|
46
46
|
### status.policy Object
|
|
47
47
|
|
|
48
|
-
| Field
|
|
49
|
-
|
|
50
|
-
| `authority`
|
|
51
|
-
| `authority-uri` | `string` | URL of the authority evidence document
|
|
48
|
+
| Field | Type | Description |
|
|
49
|
+
| --------------- | -------- | -------------------------------------------------- |
|
|
50
|
+
| `authority` | `string` | VMC validation status (`"none"` before validation) |
|
|
51
|
+
| `authority-uri` | `string` | URL of the authority evidence document |
|
|
52
52
|
|
|
53
53
|
## Result Values
|
|
54
54
|
|
|
55
|
-
| Result
|
|
56
|
-
|
|
57
|
-
| `pass`
|
|
55
|
+
| Result | Description |
|
|
56
|
+
| --------- | -------------------------------------------- |
|
|
57
|
+
| `pass` | BIMI record found and valid |
|
|
58
58
|
| `skipped` | BIMI lookup skipped (see skip reasons below) |
|
|
59
|
-
| `fail`
|
|
60
|
-
| `none`
|
|
61
|
-
| `temperr` | Temporary error during DNS lookup
|
|
59
|
+
| `fail` | BIMI record found but invalid |
|
|
60
|
+
| `none` | No BIMI record found |
|
|
61
|
+
| `temperr` | Temporary error during DNS lookup |
|
|
62
62
|
|
|
63
63
|
## Skip Reasons
|
|
64
64
|
|
|
65
65
|
The `status.comment` field explains why BIMI was skipped:
|
|
66
66
|
|
|
67
|
-
| Comment
|
|
68
|
-
|
|
69
|
-
| `"DMARC not enabled"`
|
|
70
|
-
| `"message failed DMARC"`
|
|
71
|
-
| `"too lax DMARC policy"`
|
|
72
|
-
| `"Aligned DKIM signature required"` | `bimiWithAlignedDkim` option set but no aligned DKIM
|
|
73
|
-
| `"undersized DKIM signature"`
|
|
74
|
-
| `"could not determine domain"`
|
|
67
|
+
| Comment | Description |
|
|
68
|
+
| ----------------------------------- | -------------------------------------------------------- |
|
|
69
|
+
| `"DMARC not enabled"` | DMARC result was `none` |
|
|
70
|
+
| `"message failed DMARC"` | DMARC result was not `pass` |
|
|
71
|
+
| `"too lax DMARC policy"` | DMARC policy is `none` or `quarantine` with `pct < 100` |
|
|
72
|
+
| `"Aligned DKIM signature required"` | `bimiWithAlignedDkim` option set but no aligned DKIM |
|
|
73
|
+
| `"undersized DKIM signature"` | DKIM signature has unsigned body bytes (due to `l=` tag) |
|
|
74
|
+
| `"could not determine domain"` | Unable to extract domain from headers |
|
|
75
75
|
|
|
76
76
|
## Fail Reasons
|
|
77
77
|
|
|
78
|
-
| Comment
|
|
79
|
-
|
|
80
|
-
| `"multiple BIMI-Selector headers"`
|
|
81
|
-
| `"missing bimi version in selector header"` | BIMI-Selector header missing `v=BIMI1`
|
|
82
|
-
| `"missing bimi version in dns record"`
|
|
83
|
-
| `"missing location value in dns record"`
|
|
84
|
-
| `"invalid location value in dns record"`
|
|
85
|
-
| `"invalid authority value in dns record"`
|
|
86
|
-
| `"failed to resolve {domain}"`
|
|
87
|
-
| `"invalid BIMI response for {domain}"`
|
|
78
|
+
| Comment | Description |
|
|
79
|
+
| ------------------------------------------- | ---------------------------------------------- |
|
|
80
|
+
| `"multiple BIMI-Selector headers"` | Message has more than one BIMI-Selector header |
|
|
81
|
+
| `"missing bimi version in selector header"` | BIMI-Selector header missing `v=BIMI1` |
|
|
82
|
+
| `"missing bimi version in dns record"` | DNS record missing `v=BIMI1` |
|
|
83
|
+
| `"missing location value in dns record"` | Record has neither `l=` nor `a=` tag |
|
|
84
|
+
| `"invalid location value in dns record"` | `l=` value is not a valid HTTPS URL |
|
|
85
|
+
| `"invalid authority value in dns record"` | `a=` value is not a valid HTTPS URL |
|
|
86
|
+
| `"failed to resolve {domain}"` | DNS lookup error |
|
|
87
|
+
| `"invalid BIMI response for {domain}"` | DNS response format invalid |
|
|
88
88
|
|
|
89
89
|
## VMC Validation Result
|
|
90
90
|
|
|
@@ -99,58 +99,59 @@ const vmcResult = await validateVMC(bimiResult, options);
|
|
|
99
99
|
|
|
100
100
|
### VMC Result Object
|
|
101
101
|
|
|
102
|
-
| Field
|
|
103
|
-
|
|
104
|
-
| `location`
|
|
105
|
-
| `authority` | `object` | VMC/CMC fetch and validation result
|
|
106
|
-
| `headers`
|
|
102
|
+
| Field | Type | Description |
|
|
103
|
+
| ----------- | -------- | ------------------------------------------------------- |
|
|
104
|
+
| `location` | `object` | Logo file fetch result |
|
|
105
|
+
| `authority` | `object` | VMC/CMC fetch and validation result |
|
|
106
|
+
| `headers` | `object` | Ready-to-use email headers (only on validation success) |
|
|
107
107
|
|
|
108
108
|
### location Object
|
|
109
109
|
|
|
110
|
-
| Field
|
|
111
|
-
|
|
112
|
-
| `url`
|
|
113
|
-
| `success`
|
|
114
|
-
| `logoFile`
|
|
115
|
-
| `error`
|
|
116
|
-
| `hashAlgo`
|
|
117
|
-
| `hashValue` | `string`
|
|
110
|
+
| Field | Type | Description |
|
|
111
|
+
| ----------- | --------- | ------------------------------------ |
|
|
112
|
+
| `url` | `string` | Logo URL |
|
|
113
|
+
| `success` | `boolean` | Whether fetch succeeded |
|
|
114
|
+
| `logoFile` | `string` | Base64-encoded logo SVG (on success) |
|
|
115
|
+
| `error` | `object` | Error details (on failure) |
|
|
116
|
+
| `hashAlgo` | `string` | Hash algorithm used for verification |
|
|
117
|
+
| `hashValue` | `string` | Calculated hash of the logo file |
|
|
118
118
|
|
|
119
119
|
### authority Object
|
|
120
120
|
|
|
121
|
-
| Field
|
|
122
|
-
|
|
123
|
-
| `url`
|
|
124
|
-
| `success`
|
|
125
|
-
| `vmc`
|
|
126
|
-
| `domainVerified` | `boolean` | Whether domain matches certificate
|
|
127
|
-
| `hashMatch`
|
|
128
|
-
| `error`
|
|
121
|
+
| Field | Type | Description |
|
|
122
|
+
| ---------------- | --------- | -------------------------------------- |
|
|
123
|
+
| `url` | `string` | VMC/CMC URL |
|
|
124
|
+
| `success` | `boolean` | Whether fetch and validation succeeded |
|
|
125
|
+
| `vmc` | `object` | Parsed VMC data (on success) |
|
|
126
|
+
| `domainVerified` | `boolean` | Whether domain matches certificate |
|
|
127
|
+
| `hashMatch` | `boolean` | Whether logo hash matches certificate |
|
|
128
|
+
| `error` | `object` | Error details (on failure) |
|
|
129
129
|
|
|
130
130
|
### headers Object
|
|
131
131
|
|
|
132
132
|
Present only when VMC validation succeeds. Contains ready-to-use email headers.
|
|
133
133
|
|
|
134
|
-
| Field
|
|
135
|
-
|
|
136
|
-
| `indicator`
|
|
137
|
-
| `location`
|
|
138
|
-
| `preference` | `string` | `p=` tag present | BIMI-Logo-Preference header
|
|
134
|
+
| Field | Type | Presence | Description |
|
|
135
|
+
| ------------ | -------- | ---------------- | -------------------------------------------------- |
|
|
136
|
+
| `indicator` | `string` | Always | BIMI-Indicator header with base64-encoded SVG logo |
|
|
137
|
+
| `location` | `string` | Always | BIMI-Location header with logo URL |
|
|
138
|
+
| `preference` | `string` | `p=` tag present | BIMI-Logo-Preference header |
|
|
139
139
|
|
|
140
140
|
These headers should be added to messages after successful BIMI validation. The MTA should:
|
|
141
|
-
|
|
141
|
+
|
|
142
|
+
1. Remove any existing BIMI-\* headers from incoming messages
|
|
142
143
|
2. Add these headers after successful validation
|
|
143
144
|
|
|
144
145
|
### VMC Error Codes
|
|
145
146
|
|
|
146
|
-
| Code
|
|
147
|
-
|
|
148
|
-
| `HTTP_REQUEST_FAILED`
|
|
149
|
-
| `MISSING_VMC_LOGO`
|
|
150
|
-
| `INVALID_MEDIATYPE`
|
|
151
|
-
| `INVALID_LOGO_HASH`
|
|
152
|
-
| `SVG_VALIDATION_FAILED` | SVG file failed validation
|
|
153
|
-
| `VMC_DOMAIN_MISMATCH`
|
|
147
|
+
| Code | Description |
|
|
148
|
+
| ----------------------- | -------------------------------------- |
|
|
149
|
+
| `HTTP_REQUEST_FAILED` | HTTP request failed |
|
|
150
|
+
| `MISSING_VMC_LOGO` | VMC does not contain a logo file |
|
|
151
|
+
| `INVALID_MEDIATYPE` | Logo media type is not `image/svg+xml` |
|
|
152
|
+
| `INVALID_LOGO_HASH` | Logo hash does not match certificate |
|
|
153
|
+
| `SVG_VALIDATION_FAILED` | SVG file failed validation |
|
|
154
|
+
| `VMC_DOMAIN_MISMATCH` | Domain not found in certificate SAN |
|
|
154
155
|
|
|
155
156
|
## Example Output
|
|
156
157
|
|
|
@@ -158,22 +159,22 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
158
159
|
|
|
159
160
|
```json
|
|
160
161
|
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
"status": {
|
|
163
|
+
"result": "pass",
|
|
164
|
+
"header": {
|
|
165
|
+
"selector": "default",
|
|
166
|
+
"d": "example.com"
|
|
167
|
+
},
|
|
168
|
+
"policy": {
|
|
169
|
+
"authority": "none",
|
|
170
|
+
"authority-uri": "https://example.com/bimi/vmc.pem"
|
|
171
|
+
}
|
|
166
172
|
},
|
|
167
|
-
"
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
"location": "https://example.com/bimi/logo.svg",
|
|
173
|
-
"authority": "https://example.com/bimi/vmc.pem",
|
|
174
|
-
"preference": "self",
|
|
175
|
-
"rr": "v=BIMI1; l=https://example.com/bimi/logo.svg; a=https://example.com/bimi/vmc.pem; p=self",
|
|
176
|
-
"info": "bimi=pass header.selector=default header.d=example.com policy.authority=none policy.authority-uri=https://example.com/bimi/vmc.pem"
|
|
173
|
+
"location": "https://example.com/bimi/logo.svg",
|
|
174
|
+
"authority": "https://example.com/bimi/vmc.pem",
|
|
175
|
+
"preference": "self",
|
|
176
|
+
"rr": "v=BIMI1; l=https://example.com/bimi/logo.svg; a=https://example.com/bimi/vmc.pem; p=self",
|
|
177
|
+
"info": "bimi=pass header.selector=default header.d=example.com policy.authority=none policy.authority-uri=https://example.com/bimi/vmc.pem"
|
|
177
178
|
}
|
|
178
179
|
```
|
|
179
180
|
|
|
@@ -181,12 +182,12 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
181
182
|
|
|
182
183
|
```json
|
|
183
184
|
{
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
185
|
+
"status": {
|
|
186
|
+
"result": "skipped",
|
|
187
|
+
"comment": "message failed DMARC",
|
|
188
|
+
"header": {}
|
|
189
|
+
},
|
|
190
|
+
"info": "bimi=skipped (message failed DMARC)"
|
|
190
191
|
}
|
|
191
192
|
```
|
|
192
193
|
|
|
@@ -194,12 +195,12 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
194
195
|
|
|
195
196
|
```json
|
|
196
197
|
{
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
198
|
+
"status": {
|
|
199
|
+
"result": "skipped",
|
|
200
|
+
"comment": "too lax DMARC policy",
|
|
201
|
+
"header": {}
|
|
202
|
+
},
|
|
203
|
+
"info": "bimi=skipped (too lax DMARC policy)"
|
|
203
204
|
}
|
|
204
205
|
```
|
|
205
206
|
|
|
@@ -207,14 +208,14 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
207
208
|
|
|
208
209
|
```json
|
|
209
210
|
{
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
211
|
+
"status": {
|
|
212
|
+
"result": "none",
|
|
213
|
+
"header": {
|
|
214
|
+
"selector": "default",
|
|
215
|
+
"d": "example.com"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"info": "bimi=none header.selector=default header.d=example.com"
|
|
218
219
|
}
|
|
219
220
|
```
|
|
220
221
|
|
|
@@ -222,16 +223,16 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
222
223
|
|
|
223
224
|
```json
|
|
224
225
|
{
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
226
|
+
"status": {
|
|
227
|
+
"result": "fail",
|
|
228
|
+
"comment": "missing location value in dns record",
|
|
229
|
+
"header": {
|
|
230
|
+
"selector": "default",
|
|
231
|
+
"d": "example.com"
|
|
232
|
+
}
|
|
233
|
+
},
|
|
234
|
+
"rr": "v=BIMI1;",
|
|
235
|
+
"info": "bimi=fail (missing location value in dns record) header.selector=default header.d=example.com"
|
|
235
236
|
}
|
|
236
237
|
```
|
|
237
238
|
|
|
@@ -239,34 +240,34 @@ These headers should be added to messages after successful BIMI validation. The
|
|
|
239
240
|
|
|
240
241
|
```json
|
|
241
242
|
{
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
243
|
+
"location": {
|
|
244
|
+
"url": "https://example.com/bimi/logo.svg",
|
|
245
|
+
"success": true,
|
|
246
|
+
"logoFile": "PHN2ZyB4bWxucz0i...",
|
|
247
|
+
"hashAlgo": "sha256",
|
|
248
|
+
"hashValue": "abc123..."
|
|
249
|
+
},
|
|
250
|
+
"authority": {
|
|
251
|
+
"url": "https://example.com/bimi/vmc.pem",
|
|
252
|
+
"success": true,
|
|
253
|
+
"domainVerified": true,
|
|
254
|
+
"hashMatch": true,
|
|
255
|
+
"vmc": {
|
|
256
|
+
"type": "VMC",
|
|
257
|
+
"mediaType": "image/svg+xml",
|
|
258
|
+
"logoFile": "PHN2ZyB4bWxucz0i...",
|
|
259
|
+
"hashAlgo": "sha256",
|
|
260
|
+
"hashValue": "abc123...",
|
|
261
|
+
"validHash": true,
|
|
262
|
+
"certificate": {
|
|
263
|
+
"subjectAltName": ["example.com", "*.example.com"]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
},
|
|
267
|
+
"headers": {
|
|
268
|
+
"indicator": "BIMI-Indicator: PHN2ZyB4bWxucz0i...",
|
|
269
|
+
"location": "BIMI-Location: v=BIMI1; l=https://example.com/bimi/logo.svg",
|
|
270
|
+
"preference": "BIMI-Logo-Preference: self"
|
|
264
271
|
}
|
|
265
|
-
},
|
|
266
|
-
"headers": {
|
|
267
|
-
"indicator": "BIMI-Indicator: PHN2ZyB4bWxucz0i...",
|
|
268
|
-
"location": "BIMI-Location: v=BIMI1; l=https://example.com/bimi/logo.svg",
|
|
269
|
-
"preference": "BIMI-Logo-Preference: self"
|
|
270
|
-
}
|
|
271
272
|
}
|
|
272
273
|
```
|