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/dmarc.md
CHANGED
|
@@ -18,72 +18,72 @@ const { dmarc } = await authenticate(message, {
|
|
|
18
18
|
|
|
19
19
|
## Result Object Fields
|
|
20
20
|
|
|
21
|
-
| Field
|
|
22
|
-
|
|
23
|
-
| `status`
|
|
24
|
-
| `domain`
|
|
25
|
-
| `policy`
|
|
26
|
-
| `p`
|
|
27
|
-
| `sp`
|
|
28
|
-
| `pct`
|
|
29
|
-
| `rr`
|
|
30
|
-
| `alignment` | `object` | Record found | SPF and DKIM alignment details (see below)
|
|
31
|
-
| `error`
|
|
32
|
-
| `info`
|
|
21
|
+
| Field | Type | Presence | Description |
|
|
22
|
+
| ----------- | -------- | ------------ | ---------------------------------------------------------- |
|
|
23
|
+
| `status` | `object` | Always | Verification status object (see below) |
|
|
24
|
+
| `domain` | `string` | Always | Organizational domain used for DMARC lookup |
|
|
25
|
+
| `policy` | `string` | Record found | Effective policy (`"reject"`, `"quarantine"`, or `"none"`) |
|
|
26
|
+
| `p` | `string` | Record found | Policy from `p=` tag |
|
|
27
|
+
| `sp` | `string` | Record found | Subdomain policy from `sp=` tag (defaults to `p` value) |
|
|
28
|
+
| `pct` | `number` | Record found | Percentage of messages to apply policy (0-100) |
|
|
29
|
+
| `rr` | `string` | Record found | Raw DMARC DNS TXT record |
|
|
30
|
+
| `alignment` | `object` | Record found | SPF and DKIM alignment details (see below) |
|
|
31
|
+
| `error` | `string` | On temperror | Error message |
|
|
32
|
+
| `info` | `string` | Always | Formatted Authentication-Results header value |
|
|
33
33
|
|
|
34
34
|
## status Object
|
|
35
35
|
|
|
36
|
-
| Field
|
|
37
|
-
|
|
38
|
-
| `result`
|
|
39
|
-
| `header`
|
|
40
|
-
| `comment` | `string` | Policy and ARC information
|
|
36
|
+
| Field | Type | Description |
|
|
37
|
+
| --------- | -------- | ----------------------------- |
|
|
38
|
+
| `result` | `string` | DMARC result code (see below) |
|
|
39
|
+
| `header` | `object` | Header information |
|
|
40
|
+
| `comment` | `string` | Policy and ARC information |
|
|
41
41
|
|
|
42
42
|
### status.header Object
|
|
43
43
|
|
|
44
|
-
| Field
|
|
45
|
-
|
|
44
|
+
| Field | Type | Description |
|
|
45
|
+
| ------ | -------- | ------------------------------------------ |
|
|
46
46
|
| `from` | `string` | Organizational domain from the From header |
|
|
47
|
-
| `d`
|
|
47
|
+
| `d` | `string` | Domain where DMARC record was found |
|
|
48
48
|
|
|
49
49
|
## alignment Object
|
|
50
50
|
|
|
51
|
-
| Field
|
|
52
|
-
|
|
53
|
-
| `spf`
|
|
51
|
+
| Field | Type | Description |
|
|
52
|
+
| ------ | -------- | ---------------------- |
|
|
53
|
+
| `spf` | `object` | SPF alignment details |
|
|
54
54
|
| `dkim` | `object` | DKIM alignment details |
|
|
55
55
|
|
|
56
56
|
### alignment.spf Object
|
|
57
57
|
|
|
58
|
-
| Field
|
|
59
|
-
|
|
58
|
+
| Field | Type | Description |
|
|
59
|
+
| -------- | --------------- | ----------------------------------------------------------- |
|
|
60
60
|
| `result` | `string\|false` | Aligned domain if SPF passed and aligned, otherwise `false` |
|
|
61
|
-
| `strict` | `boolean`
|
|
61
|
+
| `strict` | `boolean` | Whether strict alignment is required (`aspf=s`) |
|
|
62
62
|
|
|
63
63
|
### alignment.dkim Object
|
|
64
64
|
|
|
65
|
-
| Field
|
|
66
|
-
|
|
67
|
-
| `result`
|
|
68
|
-
| `strict`
|
|
69
|
-
| `underSized` | `number`
|
|
65
|
+
| Field | Type | Description |
|
|
66
|
+
| ------------ | --------------- | ------------------------------------------------------------ |
|
|
67
|
+
| `result` | `string\|false` | Aligned domain if DKIM passed and aligned, otherwise `false` |
|
|
68
|
+
| `strict` | `boolean` | Whether strict alignment is required (`adkim=s`) |
|
|
69
|
+
| `underSized` | `number` | Number of unsigned body bytes (if `l=` tag limited body) |
|
|
70
70
|
|
|
71
71
|
## Result Values
|
|
72
72
|
|
|
73
|
-
| Result
|
|
74
|
-
|
|
75
|
-
| `pass`
|
|
76
|
-
| `fail`
|
|
77
|
-
| `none`
|
|
78
|
-
| `temperror` | Temporary error during DNS lookup
|
|
73
|
+
| Result | Description |
|
|
74
|
+
| ----------- | ----------------------------------------------------- |
|
|
75
|
+
| `pass` | Message passed DMARC (SPF or DKIM aligned and passed) |
|
|
76
|
+
| `fail` | Message failed DMARC (neither SPF nor DKIM aligned) |
|
|
77
|
+
| `none` | No DMARC record found |
|
|
78
|
+
| `temperror` | Temporary error during DNS lookup |
|
|
79
79
|
|
|
80
80
|
## Policy Values
|
|
81
81
|
|
|
82
|
-
| Policy
|
|
83
|
-
|
|
84
|
-
| `none`
|
|
85
|
-
| `quarantine` | Suspicious messages should be quarantined
|
|
86
|
-
| `reject`
|
|
82
|
+
| Policy | Description |
|
|
83
|
+
| ------------ | ------------------------------------------- |
|
|
84
|
+
| `none` | No specific action requested (monitor mode) |
|
|
85
|
+
| `quarantine` | Suspicious messages should be quarantined |
|
|
86
|
+
| `reject` | Failed messages should be rejected |
|
|
87
87
|
|
|
88
88
|
## Comment Format
|
|
89
89
|
|
|
@@ -101,31 +101,31 @@ For example: `"p=REJECT sp=REJECT arc=pass"`
|
|
|
101
101
|
|
|
102
102
|
```json
|
|
103
103
|
{
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
104
|
+
"status": {
|
|
105
|
+
"result": "pass",
|
|
106
|
+
"header": {
|
|
107
|
+
"from": "example.com",
|
|
108
|
+
"d": "example.com"
|
|
109
|
+
},
|
|
110
|
+
"comment": "p=REJECT arc=none"
|
|
109
111
|
},
|
|
110
|
-
"
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
112
|
+
"domain": "example.com",
|
|
113
|
+
"policy": "reject",
|
|
114
|
+
"p": "reject",
|
|
115
|
+
"sp": "reject",
|
|
116
|
+
"pct": 100,
|
|
117
|
+
"rr": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
|
|
118
|
+
"alignment": {
|
|
119
|
+
"spf": {
|
|
120
|
+
"result": false,
|
|
121
|
+
"strict": false
|
|
122
|
+
},
|
|
123
|
+
"dkim": {
|
|
124
|
+
"result": "example.com",
|
|
125
|
+
"strict": false
|
|
126
|
+
}
|
|
122
127
|
},
|
|
123
|
-
"
|
|
124
|
-
"result": "example.com",
|
|
125
|
-
"strict": false
|
|
126
|
-
}
|
|
127
|
-
},
|
|
128
|
-
"info": "dmarc=pass (p=REJECT arc=none) header.from=example.com"
|
|
128
|
+
"info": "dmarc=pass (p=REJECT arc=none) header.from=example.com"
|
|
129
129
|
}
|
|
130
130
|
```
|
|
131
131
|
|
|
@@ -133,31 +133,31 @@ For example: `"p=REJECT sp=REJECT arc=pass"`
|
|
|
133
133
|
|
|
134
134
|
```json
|
|
135
135
|
{
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
136
|
+
"status": {
|
|
137
|
+
"result": "fail",
|
|
138
|
+
"header": {
|
|
139
|
+
"from": "example.com",
|
|
140
|
+
"d": "example.com"
|
|
141
|
+
},
|
|
142
|
+
"comment": "p=REJECT"
|
|
141
143
|
},
|
|
142
|
-
"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
144
|
+
"domain": "example.com",
|
|
145
|
+
"policy": "reject",
|
|
146
|
+
"p": "reject",
|
|
147
|
+
"sp": "reject",
|
|
148
|
+
"pct": 100,
|
|
149
|
+
"rr": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com",
|
|
150
|
+
"alignment": {
|
|
151
|
+
"spf": {
|
|
152
|
+
"result": false,
|
|
153
|
+
"strict": false
|
|
154
|
+
},
|
|
155
|
+
"dkim": {
|
|
156
|
+
"result": false,
|
|
157
|
+
"strict": false
|
|
158
|
+
}
|
|
154
159
|
},
|
|
155
|
-
"
|
|
156
|
-
"result": false,
|
|
157
|
-
"strict": false
|
|
158
|
-
}
|
|
159
|
-
},
|
|
160
|
-
"info": "dmarc=fail (p=REJECT) header.from=example.com"
|
|
160
|
+
"info": "dmarc=fail (p=REJECT) header.from=example.com"
|
|
161
161
|
}
|
|
162
162
|
```
|
|
163
163
|
|
|
@@ -165,14 +165,14 @@ For example: `"p=REJECT sp=REJECT arc=pass"`
|
|
|
165
165
|
|
|
166
166
|
```json
|
|
167
167
|
{
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
"status": {
|
|
169
|
+
"result": "none",
|
|
170
|
+
"header": {
|
|
171
|
+
"from": "no-dmarc.example.com"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
"domain": "no-dmarc.example.com",
|
|
175
|
+
"info": "dmarc=none header.from=no-dmarc.example.com"
|
|
176
176
|
}
|
|
177
177
|
```
|
|
178
178
|
|
|
@@ -180,31 +180,31 @@ For example: `"p=REJECT sp=REJECT arc=pass"`
|
|
|
180
180
|
|
|
181
181
|
```json
|
|
182
182
|
{
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
183
|
+
"status": {
|
|
184
|
+
"result": "pass",
|
|
185
|
+
"header": {
|
|
186
|
+
"from": "example.com",
|
|
187
|
+
"d": "sub.example.com"
|
|
188
|
+
},
|
|
189
|
+
"comment": "p=NONE sp=QUARANTINE"
|
|
188
190
|
},
|
|
189
|
-
"
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
191
|
+
"domain": "example.com",
|
|
192
|
+
"policy": "quarantine",
|
|
193
|
+
"p": "none",
|
|
194
|
+
"sp": "quarantine",
|
|
195
|
+
"pct": 100,
|
|
196
|
+
"rr": "v=DMARC1; p=none; sp=quarantine; rua=mailto:dmarc@example.com",
|
|
197
|
+
"alignment": {
|
|
198
|
+
"spf": {
|
|
199
|
+
"result": "example.com",
|
|
200
|
+
"strict": false
|
|
201
|
+
},
|
|
202
|
+
"dkim": {
|
|
203
|
+
"result": false,
|
|
204
|
+
"strict": false
|
|
205
|
+
}
|
|
201
206
|
},
|
|
202
|
-
"
|
|
203
|
-
"result": false,
|
|
204
|
-
"strict": false
|
|
205
|
-
}
|
|
206
|
-
},
|
|
207
|
-
"info": "dmarc=pass (p=NONE sp=QUARANTINE) header.from=example.com"
|
|
207
|
+
"info": "dmarc=pass (p=NONE sp=QUARANTINE) header.from=example.com"
|
|
208
208
|
}
|
|
209
209
|
```
|
|
210
210
|
|
|
@@ -212,14 +212,14 @@ For example: `"p=REJECT sp=REJECT arc=pass"`
|
|
|
212
212
|
|
|
213
213
|
```json
|
|
214
214
|
{
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
215
|
+
"status": {
|
|
216
|
+
"result": "temperror",
|
|
217
|
+
"header": {
|
|
218
|
+
"from": "example.com"
|
|
219
|
+
}
|
|
220
|
+
},
|
|
221
|
+
"domain": "example.com",
|
|
222
|
+
"error": "DNS timeout",
|
|
223
|
+
"info": "dmarc=temperror header.from=example.com"
|
|
224
224
|
}
|
|
225
225
|
```
|
package/docs/mta-sts.md
CHANGED
|
@@ -20,39 +20,39 @@ const { policy, status } = await getPolicy('example.com', knownPolicy);
|
|
|
20
20
|
|
|
21
21
|
### Result Object Fields
|
|
22
22
|
|
|
23
|
-
| Field
|
|
24
|
-
|
|
23
|
+
| Field | Type | Description |
|
|
24
|
+
| -------- | -------- | ------------------------------------- |
|
|
25
25
|
| `policy` | `object` | The MTA-STS policy object (see below) |
|
|
26
|
-
| `status` | `string` | Policy retrieval status (see below)
|
|
26
|
+
| `status` | `string` | Policy retrieval status (see below) |
|
|
27
27
|
|
|
28
28
|
### Status Values
|
|
29
29
|
|
|
30
|
-
| Status
|
|
31
|
-
|
|
32
|
-
| `found`
|
|
33
|
-
| `not_found` | No MTA-STS policy exists for the domain
|
|
34
|
-
| `renewed`
|
|
35
|
-
| `errored`
|
|
30
|
+
| Status | Description |
|
|
31
|
+
| ----------- | ---------------------------------------------------------- |
|
|
32
|
+
| `found` | New or updated policy was fetched successfully |
|
|
33
|
+
| `not_found` | No MTA-STS policy exists for the domain |
|
|
34
|
+
| `renewed` | Existing policy is still valid (ID unchanged, not expired) |
|
|
35
|
+
| `errored` | Policy discovery failed due to an error |
|
|
36
36
|
|
|
37
37
|
### Policy Object Fields
|
|
38
38
|
|
|
39
|
-
| Field
|
|
40
|
-
|
|
41
|
-
| `id`
|
|
42
|
-
| `version` | `string`
|
|
43
|
-
| `mode`
|
|
44
|
-
| `mx`
|
|
45
|
-
| `maxAge`
|
|
46
|
-
| `expires` | `string`
|
|
47
|
-
| `error`
|
|
39
|
+
| Field | Type | Presence | Description |
|
|
40
|
+
| --------- | --------------- | --------------- | ------------------------------------------------------ |
|
|
41
|
+
| `id` | `string\|false` | Always | Policy ID from DNS TXT record, or `false` if not found |
|
|
42
|
+
| `version` | `string` | Policy found | Always `"STSv1"` for valid policies |
|
|
43
|
+
| `mode` | `string` | Always | Policy mode (see below) |
|
|
44
|
+
| `mx` | `string[]` | Mode not "none" | Array of allowed MX hostnames (may include wildcards) |
|
|
45
|
+
| `maxAge` | `number` | Policy found | Policy validity period in seconds |
|
|
46
|
+
| `expires` | `string` | Policy found | ISO 8601 expiration timestamp |
|
|
47
|
+
| `error` | `Error` | On error | Error object if discovery failed |
|
|
48
48
|
|
|
49
49
|
### Mode Values
|
|
50
50
|
|
|
51
|
-
| Mode
|
|
52
|
-
|
|
51
|
+
| Mode | Description |
|
|
52
|
+
| --------- | ----------------------------------------------------------- |
|
|
53
53
|
| `testing` | Policy is in test mode; report violations but don't enforce |
|
|
54
|
-
| `enforce` | Strictly enforce TLS and MX restrictions
|
|
55
|
-
| `none`
|
|
54
|
+
| `enforce` | Strictly enforce TLS and MX restrictions |
|
|
55
|
+
| `none` | No policy in effect |
|
|
56
56
|
|
|
57
57
|
## validateMx Result
|
|
58
58
|
|
|
@@ -64,12 +64,12 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
64
64
|
|
|
65
65
|
### Result Object Fields
|
|
66
66
|
|
|
67
|
-
| Field
|
|
68
|
-
|
|
69
|
-
| `valid`
|
|
70
|
-
| `mode`
|
|
71
|
-
| `match`
|
|
72
|
-
| `testing` | `boolean` | Always
|
|
67
|
+
| Field | Type | Presence | Description |
|
|
68
|
+
| --------- | --------- | ----------- | ----------------------------------------------------- |
|
|
69
|
+
| `valid` | `boolean` | Always | Whether the MX hostname is allowed |
|
|
70
|
+
| `mode` | `string` | Always | Policy mode (`"testing"`, `"enforce"`, or `"none"`) |
|
|
71
|
+
| `match` | `string` | Valid match | The pattern that matched (exact hostname or wildcard) |
|
|
72
|
+
| `testing` | `boolean` | Always | Whether policy is in testing mode |
|
|
73
73
|
|
|
74
74
|
## Example Output
|
|
75
75
|
|
|
@@ -77,19 +77,15 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
77
77
|
|
|
78
78
|
```json
|
|
79
79
|
{
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
"maxAge": 86400,
|
|
90
|
-
"expires": "2024-01-16T12:00:00.000Z"
|
|
91
|
-
},
|
|
92
|
-
"status": "found"
|
|
80
|
+
"policy": {
|
|
81
|
+
"id": "20240115T120000",
|
|
82
|
+
"version": "STSv1",
|
|
83
|
+
"mode": "enforce",
|
|
84
|
+
"mx": ["mx1.example.com", "mx2.example.com", "*.mail.example.com"],
|
|
85
|
+
"maxAge": 86400,
|
|
86
|
+
"expires": "2024-01-16T12:00:00.000Z"
|
|
87
|
+
},
|
|
88
|
+
"status": "found"
|
|
93
89
|
}
|
|
94
90
|
```
|
|
95
91
|
|
|
@@ -97,11 +93,11 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
97
93
|
|
|
98
94
|
```json
|
|
99
95
|
{
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
96
|
+
"policy": {
|
|
97
|
+
"id": false,
|
|
98
|
+
"mode": "none"
|
|
99
|
+
},
|
|
100
|
+
"status": "not_found"
|
|
105
101
|
}
|
|
106
102
|
```
|
|
107
103
|
|
|
@@ -109,18 +105,15 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
109
105
|
|
|
110
106
|
```json
|
|
111
107
|
{
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"
|
|
121
|
-
"expires": "2024-01-16T12:00:00.000Z"
|
|
122
|
-
},
|
|
123
|
-
"status": "renewed"
|
|
108
|
+
"policy": {
|
|
109
|
+
"id": "20240115T120000",
|
|
110
|
+
"version": "STSv1",
|
|
111
|
+
"mode": "enforce",
|
|
112
|
+
"mx": ["mx1.example.com", "mx2.example.com"],
|
|
113
|
+
"maxAge": 86400,
|
|
114
|
+
"expires": "2024-01-16T12:00:00.000Z"
|
|
115
|
+
},
|
|
116
|
+
"status": "renewed"
|
|
124
117
|
}
|
|
125
118
|
```
|
|
126
119
|
|
|
@@ -128,16 +121,16 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
128
121
|
|
|
129
122
|
```json
|
|
130
123
|
{
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
124
|
+
"policy": {
|
|
125
|
+
"id": "20240115T120000",
|
|
126
|
+
"mode": "none",
|
|
127
|
+
"expires": "2024-01-15T13:00:00.000Z",
|
|
128
|
+
"error": {
|
|
129
|
+
"message": "Request timeout for https://mta-sts.example.com/.well-known/mta-sts.txt",
|
|
130
|
+
"code": "HTTP_SOCKET_TIMEOUT"
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
"status": "errored"
|
|
141
134
|
}
|
|
142
135
|
```
|
|
143
136
|
|
|
@@ -145,10 +138,10 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
145
138
|
|
|
146
139
|
```json
|
|
147
140
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
141
|
+
"valid": true,
|
|
142
|
+
"mode": "enforce",
|
|
143
|
+
"match": "mx1.example.com",
|
|
144
|
+
"testing": false
|
|
152
145
|
}
|
|
153
146
|
```
|
|
154
147
|
|
|
@@ -156,10 +149,10 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
156
149
|
|
|
157
150
|
```json
|
|
158
151
|
{
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
152
|
+
"valid": true,
|
|
153
|
+
"mode": "enforce",
|
|
154
|
+
"match": ".mail.example.com",
|
|
155
|
+
"testing": false
|
|
163
156
|
}
|
|
164
157
|
```
|
|
165
158
|
|
|
@@ -167,9 +160,9 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
167
160
|
|
|
168
161
|
```json
|
|
169
162
|
{
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
163
|
+
"valid": false,
|
|
164
|
+
"mode": "enforce",
|
|
165
|
+
"testing": false
|
|
173
166
|
}
|
|
174
167
|
```
|
|
175
168
|
|
|
@@ -177,10 +170,10 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
177
170
|
|
|
178
171
|
```json
|
|
179
172
|
{
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
173
|
+
"valid": true,
|
|
174
|
+
"mode": "testing",
|
|
175
|
+
"match": "mx1.example.com",
|
|
176
|
+
"testing": true
|
|
184
177
|
}
|
|
185
178
|
```
|
|
186
179
|
|
|
@@ -188,9 +181,9 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
188
181
|
|
|
189
182
|
```json
|
|
190
183
|
{
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
184
|
+
"valid": true,
|
|
185
|
+
"mode": "none",
|
|
186
|
+
"testing": false
|
|
194
187
|
}
|
|
195
188
|
```
|
|
196
189
|
|
|
@@ -198,17 +191,17 @@ const result = validateMx('alt1.mx.example.com', policy);
|
|
|
198
191
|
|
|
199
192
|
Errors that may appear in `policy.error`:
|
|
200
193
|
|
|
201
|
-
| Code
|
|
202
|
-
|
|
203
|
-
| `multi_sts_records`
|
|
204
|
-
| `invalid_sts_version` | Policy file has invalid or missing version field
|
|
205
|
-
| `invalid_sts_mode`
|
|
206
|
-
| `invalid_sts_max_age` | Policy file has invalid max_age value
|
|
207
|
-
| `invalid_sts_mx`
|
|
208
|
-
| `HTTP_SOCKET_TIMEOUT` | HTTP request timed out
|
|
209
|
-
| `http_status_{code}`
|
|
210
|
-
| `ENOTFOUND`
|
|
211
|
-
| `ENODATA`
|
|
194
|
+
| Code | Description |
|
|
195
|
+
| --------------------- | ---------------------------------------------------- |
|
|
196
|
+
| `multi_sts_records` | Multiple TXT records found for `_mta-sts.{domain}` |
|
|
197
|
+
| `invalid_sts_version` | Policy file has invalid or missing version field |
|
|
198
|
+
| `invalid_sts_mode` | Policy file has invalid mode value |
|
|
199
|
+
| `invalid_sts_max_age` | Policy file has invalid max_age value |
|
|
200
|
+
| `invalid_sts_mx` | Policy file missing mx field in enforce/testing mode |
|
|
201
|
+
| `HTTP_SOCKET_TIMEOUT` | HTTP request timed out |
|
|
202
|
+
| `http_status_{code}` | HTTP request returned non-2xx status |
|
|
203
|
+
| `ENOTFOUND` | DNS lookup failed (domain not found) |
|
|
204
|
+
| `ENODATA` | DNS lookup returned no data |
|
|
212
205
|
|
|
213
206
|
## Usage Example
|
|
214
207
|
|