dmarcator 0.8.0 → 0.9.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.
- checksums.yaml +4 -4
- data/ChangeLog.md +4 -0
- data/README.md +15 -3
- data/lib/dmarcator/query.rb +39 -4
- data/lib/dmarcator/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: f4c6e25ca7a0fc2d77204c72ebb01906fce1ac4b537b1e011e505ed2938dda2b
|
|
4
|
+
data.tar.gz: 36f390d4c0e42c5e938df0345e9d412de2b09aed29da9ca83a424414090b88f1
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8f3db5da3231a84613e3a938d3e294f01da16df7aee2e633ba321e0002a8278ec28755accb08a1db2e6c72f2d0424cb34ea019b3168b32872503f59dddb6eaa4
|
|
7
|
+
data.tar.gz: 28d72632daef6199571fd1cd461c112610ebd14bd45a03b48c6b9127f571e82f8431ad35331e4c05d52482b2b5d085bb973a51aa37a888ede498b8b7a85f4eac
|
data/ChangeLog.md
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
### 0.9.0 / 2026-10-29
|
|
2
|
+
|
|
3
|
+
* Add `DMARCator.txt_records`, which returns the TXT resource records instead of strings, so callers that cache lookups can read each record's `ttl`. `DMARCator.txt` is now defined in terms of it and behaves the same.
|
|
4
|
+
|
|
1
5
|
### 0.8.0 / 2026-10-29
|
|
2
6
|
|
|
3
7
|
* Add `DMARCator.txt`, which returns every TXT record at a name — unfiltered, in response order, with multi-chunk records joined. It accepts service labels such as `_dmarc` and `_domainkey` through a new relaxed `validate_txt_name`, and lets callers detect duplicate DMARC records that `dmarc` deliberately hides.
|
data/README.md
CHANGED
|
@@ -104,6 +104,7 @@ The lookup methods are named after what they return:
|
|
|
104
104
|
|
|
105
105
|
| Method | Returns | Cost |
|
|
106
106
|
|---|---|---|
|
|
107
|
+
| `DMARCator.txt_records(name)` | `Array<Resolv::DNS::Resource::IN::TXT>` — the records themselves | one lookup |
|
|
107
108
|
| `DMARCator.txt(name)` | `Array<String>` — every TXT record at `name` | one lookup |
|
|
108
109
|
| `DMARCator.dmarc(domain)` | `String` — the DMARC record text, or `nil` | one lookup |
|
|
109
110
|
| `DMARCator::Record.lookup(domain)` | `Record` — parsed | one lookup + parse (~0.4 ms) |
|
|
@@ -136,13 +137,24 @@ else :duplicate # more than one DMARC record breaks enforcement
|
|
|
136
137
|
end
|
|
137
138
|
```
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
Use `DMARCator.txt_records` when you need the DNS TTL, for example to cache
|
|
141
|
+
lookups in a database:
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
records = DMARCator.txt_records("_dmarc.#{domain}")
|
|
145
|
+
records.each do |record|
|
|
146
|
+
record.strings.join # the TXT value
|
|
147
|
+
record.ttl # seconds the answer may be cached
|
|
148
|
+
end
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
All of these accept an injected resolver, and an injected resolver keeps its
|
|
152
|
+
own configuration (timeouts are only applied to resolvers the library builds):
|
|
142
153
|
|
|
143
154
|
```ruby
|
|
144
155
|
resolver = DMARCator::Resolver::DoH.new(url: "https://dns.example/dns-query")
|
|
145
156
|
DMARCator.txt("_dmarc.example.com", resolver: resolver)
|
|
157
|
+
DMARCator.txt_records("_dmarc.example.com", resolver: resolver)
|
|
146
158
|
DMARCator.dmarc("example.com", resolver: resolver)
|
|
147
159
|
DMARCator::Record.lookup("example.com", resolver: resolver)
|
|
148
160
|
```
|
data/lib/dmarcator/query.rb
CHANGED
|
@@ -171,6 +171,39 @@ module DMARCator
|
|
|
171
171
|
# @since 0.8.0
|
|
172
172
|
#
|
|
173
173
|
def self.txt(name, resolver: default_resolver)
|
|
174
|
+
txt_records(name, resolver: resolver).map { |record| record.strings.join }
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
#
|
|
178
|
+
# Looks up every TXT record at a DNS name, returning the resource records
|
|
179
|
+
# themselves.
|
|
180
|
+
#
|
|
181
|
+
# Like {txt}, but without flattening to strings. The records expose
|
|
182
|
+
# `strings` and `ttl`, which matters when caching results: use
|
|
183
|
+
# `record.ttl` to decide how long an answer may be reused.
|
|
184
|
+
#
|
|
185
|
+
# @param [String] name
|
|
186
|
+
# The DNS name to look up.
|
|
187
|
+
#
|
|
188
|
+
# @param [Resolv::DNS, Resolver::DoH, Resolver::DoT] resolver
|
|
189
|
+
# The resolver to use. When omitted, one is built from `DMARCATOR_DNS`.
|
|
190
|
+
# An injected resolver keeps its own configuration.
|
|
191
|
+
#
|
|
192
|
+
# @return [Array<Resolv::DNS::Resource::IN::TXT>]
|
|
193
|
+
# The records, or an empty array when the name has none. NXDOMAIN and
|
|
194
|
+
# NODATA are indistinguishable here.
|
|
195
|
+
#
|
|
196
|
+
# @raise [ResolutionError]
|
|
197
|
+
# The lookup failed. A failure is never reported as an empty result.
|
|
198
|
+
#
|
|
199
|
+
# @raise [ArgumentError]
|
|
200
|
+
# The name is not a syntactically valid DNS name.
|
|
201
|
+
#
|
|
202
|
+
# @note Names must be ASCII: pass punycode (A-labels) rather than Unicode.
|
|
203
|
+
#
|
|
204
|
+
# @since 0.9.0
|
|
205
|
+
#
|
|
206
|
+
def self.txt_records(name, resolver: default_resolver)
|
|
174
207
|
lookup_txt(validate_txt_name(name), resolver: resolver)
|
|
175
208
|
end
|
|
176
209
|
|
|
@@ -204,7 +237,9 @@ module DMARCator
|
|
|
204
237
|
|
|
205
238
|
# Per RFC 7489 §6.6.3, use the TXT record beginning with "v=DMARC1".
|
|
206
239
|
# If multiple DMARC records exist, treat the domain as having none.
|
|
207
|
-
dmarc_records = lookup_txt(name, resolver: resolver).
|
|
240
|
+
dmarc_records = lookup_txt(name, resolver: resolver).map do |record|
|
|
241
|
+
record.strings.join
|
|
242
|
+
end.select do |text|
|
|
208
243
|
text.start_with?('v=DMARC1')
|
|
209
244
|
end
|
|
210
245
|
|
|
@@ -224,13 +259,13 @@ module DMARCator
|
|
|
224
259
|
#
|
|
225
260
|
# Looks up the TXT records at an already-validated name.
|
|
226
261
|
#
|
|
227
|
-
# Shared by {txt} and {dmarc} so
|
|
262
|
+
# Shared by {txt}, {txt_records} and {dmarc} so they use one transport path.
|
|
228
263
|
#
|
|
229
264
|
# @param [String] name
|
|
230
265
|
#
|
|
231
266
|
# @param [Resolv::DNS, Resolver::DoH, Resolver::DoT] resolver
|
|
232
267
|
#
|
|
233
|
-
# @return [Array<
|
|
268
|
+
# @return [Array<Resolv::DNS::Resource::IN::TXT>]
|
|
234
269
|
#
|
|
235
270
|
# @raise [ResolutionError]
|
|
236
271
|
#
|
|
@@ -246,7 +281,7 @@ module DMARCator
|
|
|
246
281
|
raise ResolutionError, "DNS TXT lookup failed for #{name}: #{error.message}"
|
|
247
282
|
end
|
|
248
283
|
|
|
249
|
-
records
|
|
284
|
+
records
|
|
250
285
|
end
|
|
251
286
|
private_class_method :lookup_txt
|
|
252
287
|
end
|
data/lib/dmarcator/version.rb
CHANGED