dmarcator 0.9.0 → 0.10.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f4c6e25ca7a0fc2d77204c72ebb01906fce1ac4b537b1e011e505ed2938dda2b
4
- data.tar.gz: 36f390d4c0e42c5e938df0345e9d412de2b09aed29da9ca83a424414090b88f1
3
+ metadata.gz: a1bd93bc4b534e2b9613241e920dd4a71c41e564c92c10ab8abaf6be7294feb8
4
+ data.tar.gz: fb95401f394f53189a0db431f7d31bc4ffe8c25c87ce87f825f18a99962dadba
5
5
  SHA512:
6
- metadata.gz: 8f3db5da3231a84613e3a938d3e294f01da16df7aee2e633ba321e0002a8278ec28755accb08a1db2e6c72f2d0424cb34ea019b3168b32872503f59dddb6eaa4
7
- data.tar.gz: 28d72632daef6199571fd1cd461c112610ebd14bd45a03b48c6b9127f571e82f8431ad35331e4c05d52482b2b5d085bb973a51aa37a888ede498b8b7a85f4eac
6
+ metadata.gz: c94318c4ac8a5f7089276f5d6bf91ae90ab8cf576f6367acf418e86adba5fe4bb5e28f7df4a478f8783d134b82bd9390555b3af48c713ca869fd276be4cfe08b
7
+ data.tar.gz: 6b10b30dfc64acd1cdef7427c4a475d7d9fa90b4c9d387cbc1e2293e8b693e66d3fa4bc23d80d254d92a5a4137ab65b1fe98adfc0e28e573bafc8342274e7995
data/ChangeLog.md CHANGED
@@ -1,3 +1,21 @@
1
+ ### 0.10.0 / 2026-10-29
2
+
3
+ Breaking changes, taken before 1.0 so the release does not carry them:
4
+
5
+ * Add `DMARCator::Error` as the base class for every error the library raises. `InvalidRecord`, `InvalidReport` and `ResolutionError` inherit from it, so one `rescue DMARCator::Error` catches all three.
6
+ * `InvalidRecord` no longer inherits from `Parslet::ParseFailed`, removing the parser implementation from the public exception contract. Parse failures still expose the underlying parser error as their `cause`.
7
+ * Remove the deprecated `DMARCator.query` and `DMARCator::Record.query` aliases. Use `DMARCator.dmarc` and `DMARCator::Record.lookup`.
8
+ * Rename `DMARCator::Report::Record` to `DMARCator::Report::Row`, so aggregate rows are not confused with `DMARCator::Record`, the parsed DMARC TXT record.
9
+
10
+ Migration:
11
+
12
+ | Before | After |
13
+ |---|---|
14
+ | `DMARCator.query(domain)` | `DMARCator.dmarc(domain)` |
15
+ | `DMARCator::Record.query(domain)` | `DMARCator::Record.lookup(domain)` |
16
+ | `DMARCator::Report::Record` | `DMARCator::Report::Row` |
17
+ | `rescue Parslet::ParseFailed` | `rescue DMARCator::Error` |
18
+
1
19
  ### 0.9.0 / 2026-10-29
2
20
 
3
21
  * 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.
data/README.md CHANGED
@@ -177,6 +177,22 @@ more than the lookup on a fast resolver); `Resolv::DNS` does not lock per query,
177
177
  so use one resolver per thread when parallelising; and DoT/DoH open a new TLS
178
178
  connection per lookup, so plaintext is the better choice for bulk work.
179
179
 
180
+ ### SPF and DKIM
181
+
182
+ The TXT primitives also cover the other two records a checker needs. There is
183
+ no record-type-specific API, because the semantics belong to the caller:
184
+
185
+ ```ruby
186
+ DMARCator.txt("example.com") # SPF (RFC 7208)
187
+ DMARCator.txt("s1._domainkey.example.com") # DKIM (RFC 6376)
188
+ ```
189
+
190
+ Both need the raw list rather than a single value: more than one SPF record is
191
+ a `permerror`, and DKIM keys can be duplicated, rotated or revoked (`p=`). A
192
+ helper returning "the" record would hide exactly those conditions. DKIM is also
193
+ per-selector and selectors cannot be enumerated, so any convenience method would
194
+ have to take a selector and would only build the name above.
195
+
180
196
  ## Strict parsing
181
197
 
182
198
  By default, unknown tags and tags with invalid values are ignored. Pass
@@ -1,30 +1,41 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'parslet'
4
-
5
3
  module DMARCator
4
+ #
5
+ # Base class for every error raised by this library.
6
+ #
7
+ # Rescuing this catches parse failures, report failures and DNS lookup
8
+ # failures alike.
9
+ #
10
+ # @since 0.10.0
11
+ #
12
+ class Error < StandardError
13
+ end
14
+
6
15
  #
7
16
  # Raised when a DMARC record cannot be parsed.
8
17
  #
9
18
  # @since 0.2.0
10
19
  #
11
- class InvalidRecord < Parslet::ParseFailed
20
+ class InvalidRecord < Error
12
21
  end
13
22
 
14
23
  #
15
24
  # Raised when a DMARC XML report cannot be parsed.
16
25
  #
17
- class InvalidReport < StandardError
26
+ # @since 0.3.0
27
+ #
28
+ class InvalidReport < Error
18
29
  end
19
30
 
20
31
  #
21
- # Raised when an encrypted DNS transport fails to return a usable answer.
32
+ # Raised when a DNS transport fails to return a usable answer.
22
33
  #
23
34
  # This is deliberately distinct from a missing record: a failed lookup must
24
35
  # not be mistaken for a domain without a DMARC policy.
25
36
  #
26
37
  # @since 0.6.0
27
38
  #
28
- class ResolutionError < StandardError
39
+ class ResolutionError < Error
29
40
  end
30
41
  end
@@ -246,16 +246,6 @@ module DMARCator
246
246
  dmarc_records.first if dmarc_records.one?
247
247
  end
248
248
 
249
- #
250
- # @deprecated Use {dmarc}, which names what it returns. Kept for
251
- # compatibility; it will be removed in a future release.
252
- #
253
- # @see dmarc
254
- #
255
- def self.query(domain,resolver=default_resolver)
256
- dmarc(domain, resolver: resolver)
257
- end
258
-
259
249
  #
260
250
  # Looks up the TXT records at an already-validated name.
261
251
  #
@@ -285,7 +285,8 @@ module DMARCator
285
285
 
286
286
  new(attributes)
287
287
  rescue Parslet::ParseFailed => error
288
- raise InvalidRecord.new(truncate_error_message(error.message), error.cause)
288
+ # Raising inside the rescue sets this error as the cause automatically.
289
+ raise InvalidRecord, truncate_error_message(error.message)
289
290
  end
290
291
 
291
292
  # Maximum length of error messages echoed from parsing untrusted input.
@@ -342,16 +343,6 @@ module DMARCator
342
343
  end
343
344
  end
344
345
 
345
- #
346
- # @deprecated Use {lookup}, which names what it returns. Kept for
347
- # compatibility; it will be removed in a future release.
348
- #
349
- # @see lookup
350
- #
351
- def self.query(domain,resolver=DMARCator.default_resolver)
352
- lookup(domain, resolver: resolver)
353
- end
354
-
355
346
  #
356
347
  # Converts the record to a Hash.
357
348
  #
@@ -9,7 +9,10 @@ module DMARCator
9
9
  #
10
10
  # Represents a single `record` element of a DMARC XML report.
11
11
  #
12
- class Record
12
+ # Named `Row` so it is not confused with {DMARCator::Record}, the parsed
13
+ # DMARC TXT record.
14
+ #
15
+ class Row
13
16
  include XmlHelper
14
17
 
15
18
  # Attribute names exposed by this class.
@@ -8,7 +8,7 @@ require_relative 'xml_helper'
8
8
  require_relative 'exceptions'
9
9
  require_relative 'report/metadata'
10
10
  require_relative 'report/policy'
11
- require_relative 'report/record'
11
+ require_relative 'report/row'
12
12
 
13
13
  module DMARCator
14
14
  #
@@ -114,11 +114,11 @@ module DMARCator
114
114
  #
115
115
  # The report records.
116
116
  #
117
- # @return [Array<Report::Record>]
117
+ # @return [Array<Report::Row>]
118
118
  #
119
119
  def records
120
120
  @records ||= @node.xpath('feedback/record').map do |node|
121
- Record.new(node)
121
+ Row.new(node)
122
122
  end
123
123
  end
124
124
  end
@@ -2,5 +2,5 @@
2
2
 
3
3
  module DMARCator
4
4
  # dmarcator version
5
- VERSION = '0.9.0'
5
+ VERSION = '0.10.0'
6
6
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dmarcator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.0
4
+ version: 0.10.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Noah Berman
@@ -78,7 +78,7 @@ files:
78
78
  - lib/dmarcator/report/metadata.rb
79
79
  - lib/dmarcator/report/policy.rb
80
80
  - lib/dmarcator/report/reason.rb
81
- - lib/dmarcator/report/record.rb
81
+ - lib/dmarcator/report/row.rb
82
82
  - lib/dmarcator/resolver.rb
83
83
  - lib/dmarcator/resolver/doh.rb
84
84
  - lib/dmarcator/resolver/dot.rb