Class: Nondisposable::DisposableDomain
- Inherits:
-
ApplicationRecord
- Object
- ApplicationRecord
- Nondisposable::DisposableDomain
- Defined in:
- app/models/nondisposable/disposable_domain.rb
Constant Summary collapse
- PARENT_MATCH_DEPTH =
How many leading labels the parent-domain walk strips when check_parent_domains is enabled: user@a.b.c.tempmail.com is checked as a.b.c.tempmail.com, b.c.tempmail.com, c.tempmail.com and tempmail.com.
Trade-off (documented instead of pulling in a full public-suffix-list dependency): the walk never queries single-label suffixes (bare TLDs like "com"), but without a PSL it cannot tell that multi-label suffixes like "co.uk" are public — those candidates are harmless unless a public suffix is deliberately added to the list. Conversely, a throwaway address nested more than 3 labels below a listed domain escapes the walk; blocklisted domains are registrable domains, so 3 levels covers practical abuse.
3
Class Method Summary collapse
- .disposable?(domain) ⇒ Boolean
-
.match_candidates(domain) ⇒ Object
The exact domain plus up to PARENT_MATCH_DEPTH parent domains, never descending below two labels (bare TLDs are never candidates).
Class Method Details
.disposable?(domain) ⇒ Boolean
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# File 'app/models/nondisposable/disposable_domain.rb', line 21 def disposable?(domain) return false if domain.blank? domain = domain.to_s.downcase config = Nondisposable.configuration candidates = match_candidates(domain) additional = config.additional_domains.map { |d| d.to_s.downcase } return true if (candidates & additional).any? # rubocop compat: Array#intersect? needs Ruby >= 3.1, gem supports 3.0 excluded = config.excluded_domains.map { |d| d.to_s.downcase } # An exact exclusion always wins, so a specific subdomain can be # allowlisted even when a parent domain is on the list. return false if excluded.include?(domain) where(name: candidates - excluded).exists? end |
.match_candidates(domain) ⇒ Object
The exact domain plus up to PARENT_MATCH_DEPTH parent domains, never descending below two labels (bare TLDs are never candidates).
41 42 43 44 45 46 47 48 49 50 51 52 53 |
# File 'app/models/nondisposable/disposable_domain.rb', line 41 def match_candidates(domain) return [domain] unless Nondisposable.configuration.check_parent_domains labels = domain.split('.') candidates = [domain] 1.upto(PARENT_MATCH_DEPTH) do |depth| parent = labels.drop(depth) break if parent.size < 2 candidates << parent.join('.') end candidates end |