validators 3.3.0 → 3.4.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/.github/FUNDING.yml +1 -0
- data/.rubocop.yml +2 -0
- data/Rakefile +0 -1
- data/lib/validators.rb +1 -1
- data/lib/validators/disposable_domains.rb +19 -0
- data/lib/validators/disposable_emails.rb +7 -3
- data/lib/validators/tld.rb +9 -5
- data/lib/validators/validates_email_format_of.rb +1 -1
- data/lib/validators/version.rb +1 -1
- data/test/test_helper.rb +1 -2
- data/test/validators/validates_url_format_of/with_tld_validation_test.rb +18 -0
- data/test/validators/validates_url_format_of/without_tld_validation_test.rb +18 -0
- data/validators.gemspec +2 -0
- metadata +20 -13
- data/bin/sync-disposable-hostnames +0 -230
- data/bin/sync-tld +0 -20
- data/data/country_tlds.txt +0 -235
- data/data/disposable_domains.txt +0 -110996
- data/data/disposable_emails.txt +0 -38
- data/data/tld.txt +0 -1508
- data/lib/validators/disposable_hostnames.rb +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 49077fb99da3c1c92a3b981cdfd0354acb5a62a9b433512658bfc5c1e4df649b
|
4
|
+
data.tar.gz: 9d48b1cf25f3782afeaa00c0fa7f51ecf5581ea7e6bb49ebd5796ab914aecb50
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b307ad09f0e26c9e1db7766a15512aab5c87eb5cbd6217e9da489a45abce98bad30c4c320d0042d46fbf92d1d2c061487736f45d723d569a04cf26fb27bc453
|
7
|
+
data.tar.gz: b72f412e65628ac2d4b1e14160e2fcc855383ff3e40641d78e77cfa99f3f9b781e82d9cc4ca269ecd45493f4b199d918102b713d7860c99bf73e88b73ab6e060
|
data/.github/FUNDING.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
github: [fnando]
|
data/.rubocop.yml
CHANGED
data/Rakefile
CHANGED
data/lib/validators.rb
CHANGED
@@ -7,7 +7,7 @@ module Validators
|
|
7
7
|
require "validators/ip"
|
8
8
|
require "validators/tld"
|
9
9
|
require "validators/hostname"
|
10
|
-
require "validators/
|
10
|
+
require "validators/disposable_domains"
|
11
11
|
require "validators/disposable_emails"
|
12
12
|
require "validators/reserved_subdomains"
|
13
13
|
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Validators
|
4
|
+
class DisposableDomains
|
5
|
+
def self.all
|
6
|
+
@all ||=
|
7
|
+
begin
|
8
|
+
require "email_data"
|
9
|
+
EmailData.disposable_domains
|
10
|
+
rescue LoadError
|
11
|
+
raise "email_data is not part of the bundle. Add it to Gemfile."
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.include?(domain)
|
16
|
+
all.include?(domain)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module Validators
|
4
4
|
class DisposableEmails
|
5
|
-
FILE_PATH = File.expand_path("../../data/disposable_emails.txt", __dir__)
|
6
|
-
|
7
5
|
def self.all
|
8
|
-
@all ||=
|
6
|
+
@all ||=
|
7
|
+
begin
|
8
|
+
require "email_data"
|
9
|
+
EmailData.disposable_emails
|
10
|
+
rescue LoadError
|
11
|
+
raise "email_data is not part of the bundle. Add it to Gemfile."
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.include?(email)
|
data/lib/validators/tld.rb
CHANGED
@@ -2,10 +2,14 @@
|
|
2
2
|
|
3
3
|
module Validators
|
4
4
|
class TLD
|
5
|
-
FILE_PATH = File.expand_path("../../data/tld.txt", __dir__)
|
6
|
-
|
7
5
|
def self.all
|
8
|
-
@all ||=
|
6
|
+
@all ||=
|
7
|
+
begin
|
8
|
+
require "email_data"
|
9
|
+
EmailData.tlds
|
10
|
+
rescue LoadError
|
11
|
+
raise "email_data is not part of the bundle. Add it to Gemfile."
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
def self.host_with_valid_tld?(host)
|
@@ -13,10 +17,10 @@ module Validators
|
|
13
17
|
|
14
18
|
return false if host.split(".").size == 1
|
15
19
|
|
16
|
-
|
20
|
+
include?(host[/\.([^.]+)$/, 1].to_s.downcase)
|
17
21
|
end
|
18
22
|
|
19
|
-
def self.
|
23
|
+
def self.include?(tld)
|
20
24
|
all.include?(tld)
|
21
25
|
end
|
22
26
|
end
|
@@ -50,7 +50,7 @@ module ActiveModel
|
|
50
50
|
hostname = value.to_s.split(AT_SIGN).last.to_s.downcase
|
51
51
|
root_domain = RootDomain.call(hostname)
|
52
52
|
|
53
|
-
return unless Validators::
|
53
|
+
return unless Validators::DisposableDomains.include?(root_domain)
|
54
54
|
|
55
55
|
record.errors.add(
|
56
56
|
attribute,
|
data/lib/validators/version.rb
CHANGED
data/test/test_helper.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
$VERBOSE = nil
|
4
4
|
|
5
5
|
require "simplecov"
|
6
|
-
SimpleCov.start
|
7
6
|
|
8
7
|
SimpleCov.start do
|
9
8
|
add_filter "test/support"
|
@@ -31,7 +30,7 @@ end
|
|
31
30
|
|
32
31
|
Time.zone = "America/Sao_Paulo"
|
33
32
|
TLDs = Validators::TLD.all.sample(10)
|
34
|
-
DISPOSABLE_DOMAINS = Validators::
|
33
|
+
DISPOSABLE_DOMAINS = Validators::DisposableDomains.all.sample(10)
|
35
34
|
DISPOSABLE_EMAILS = Validators::DisposableEmails.all +
|
36
35
|
Validators::DisposableEmails.all.sample(10).map {|email| build_email_with_filter(email) } +
|
37
36
|
Validators::DisposableEmails.all.sample(10).map {|email| build_email_with_dots(email) } +
|
@@ -14,4 +14,22 @@ class ValidatesurlFormatUrlWithTldValidationTest < Minitest::Test
|
|
14
14
|
assert user.valid?
|
15
15
|
end
|
16
16
|
end
|
17
|
+
|
18
|
+
test "rejects invalid TLD (alternative syntax)" do
|
19
|
+
user_model = Class.new do
|
20
|
+
include ActiveModel::Validations
|
21
|
+
attr_accessor :site_url
|
22
|
+
|
23
|
+
def self.name
|
24
|
+
"User"
|
25
|
+
end
|
26
|
+
|
27
|
+
validates :site_url, url: {tld: true}
|
28
|
+
end
|
29
|
+
|
30
|
+
user = user_model.new
|
31
|
+
user.site_url = "https://example.xy"
|
32
|
+
|
33
|
+
refute user.valid?
|
34
|
+
end
|
17
35
|
end
|
@@ -47,4 +47,22 @@ class ValidatesurlFormatUrlWithoutTldValidationTest < Minitest::Test
|
|
47
47
|
user = User.new(url: "")
|
48
48
|
refute user.valid?
|
49
49
|
end
|
50
|
+
|
51
|
+
test "accepts invalid TLD (alternative syntax)" do
|
52
|
+
user_model = Class.new do
|
53
|
+
include ActiveModel::Validations
|
54
|
+
attr_accessor :site_url
|
55
|
+
|
56
|
+
def self.name
|
57
|
+
"User"
|
58
|
+
end
|
59
|
+
|
60
|
+
validates :site_url, url: {tld: false}
|
61
|
+
end
|
62
|
+
|
63
|
+
user = user_model.new
|
64
|
+
user.site_url = "https://example.xy"
|
65
|
+
|
66
|
+
assert user.valid?
|
67
|
+
end
|
50
68
|
end
|
data/validators.gemspec
CHANGED
@@ -12,6 +12,7 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.summary = "Add some nice ActiveModel/ActiveRecord validators."
|
13
13
|
s.description = s.summary
|
14
14
|
s.license = "MIT"
|
15
|
+
s.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
|
15
16
|
|
16
17
|
s.files = `git ls-files`.split("\n")
|
17
18
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
@@ -23,6 +24,7 @@ Gem::Specification.new do |s|
|
|
23
24
|
s.add_development_dependency "activerecord"
|
24
25
|
s.add_development_dependency "aitch"
|
25
26
|
s.add_development_dependency "cpf_cnpj"
|
27
|
+
s.add_development_dependency "email_data"
|
26
28
|
s.add_development_dependency "minitest-utils"
|
27
29
|
s.add_development_dependency "mocha"
|
28
30
|
s.add_development_dependency "nokogiri"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: validators
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -52,6 +52,20 @@ dependencies:
|
|
52
52
|
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: email_data
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: minitest-utils
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -265,29 +279,22 @@ dependencies:
|
|
265
279
|
description: Add some nice ActiveModel/ActiveRecord validators.
|
266
280
|
email:
|
267
281
|
- fnando.vieira@gmail.com
|
268
|
-
executables:
|
269
|
-
- sync-disposable-hostnames
|
270
|
-
- sync-tld
|
282
|
+
executables: []
|
271
283
|
extensions: []
|
272
284
|
extra_rdoc_files: []
|
273
285
|
files:
|
286
|
+
- ".github/FUNDING.yml"
|
274
287
|
- ".gitignore"
|
275
288
|
- ".rubocop.yml"
|
276
289
|
- ".travis.yml"
|
277
290
|
- Gemfile
|
278
291
|
- README.md
|
279
292
|
- Rakefile
|
280
|
-
- bin/sync-disposable-hostnames
|
281
|
-
- bin/sync-tld
|
282
|
-
- data/country_tlds.txt
|
283
|
-
- data/disposable_domains.txt
|
284
|
-
- data/disposable_emails.txt
|
285
293
|
- data/reserved_subdomains.txt
|
286
|
-
- data/tld.txt
|
287
294
|
- lib/validators.rb
|
288
295
|
- lib/validators/constants.rb
|
296
|
+
- lib/validators/disposable_domains.rb
|
289
297
|
- lib/validators/disposable_emails.rb
|
290
|
-
- lib/validators/disposable_hostnames.rb
|
291
298
|
- lib/validators/hostname.rb
|
292
299
|
- lib/validators/ip.rb
|
293
300
|
- lib/validators/locale/en.yml
|
@@ -351,7 +358,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
351
358
|
requirements:
|
352
359
|
- - ">="
|
353
360
|
- !ruby/object:Gem::Version
|
354
|
-
version:
|
361
|
+
version: 2.3.0
|
355
362
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
356
363
|
requirements:
|
357
364
|
- - ">="
|
@@ -1,230 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative "helpers"
|
5
|
-
|
6
|
-
def ten_minute_mail
|
7
|
-
path = "disposable/10minutemail.txt"
|
8
|
-
url = "https://10minutemail.com/session/address"
|
9
|
-
|
10
|
-
20.times do
|
11
|
-
refresh_list(url: url, path: path) do |response|
|
12
|
-
_account, host = response.data.fetch("address").split("@")
|
13
|
-
|
14
|
-
[host]
|
15
|
-
end
|
16
|
-
|
17
|
-
sleep random_timeout
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def temp_mail
|
22
|
-
path = "disposable/tempmail.txt"
|
23
|
-
url = "https://api4.temp-mail.org/request/domains/format/json"
|
24
|
-
|
25
|
-
refresh_list(url: url, path: path) do |response|
|
26
|
-
response.data.map {|domain| domain.tr("@", "") }
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def temp_mail_address
|
31
|
-
path = "disposable/tempmailaddress.txt"
|
32
|
-
url = "https://www.tempmailaddress.com/index/index"
|
33
|
-
|
34
|
-
refresh_list(url: url, path: path) do |response|
|
35
|
-
data = JSON.parse(
|
36
|
-
response.body.gsub(/[^-,:\w@.{}"]/, ""),
|
37
|
-
symbolize_names: true
|
38
|
-
)
|
39
|
-
[data[:email].split("@").last]
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
def tempmail_io
|
44
|
-
path = "disposable/tempmail_io.txt"
|
45
|
-
url = "https://api.internal.temp-mail.io/api/v2/domains"
|
46
|
-
|
47
|
-
refresh_list(url: url, path: path) do |response|
|
48
|
-
response.data["domains"]
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def gmailnator
|
53
|
-
emails = []
|
54
|
-
|
55
|
-
5.times do
|
56
|
-
url = "https://gmailnator.com/bulk-emails"
|
57
|
-
default_headers = {"user-agent" => USER_AGENT.sample}
|
58
|
-
|
59
|
-
response = Aitch.get(url: url, headers: default_headers)
|
60
|
-
|
61
|
-
throw "Received #{response.status} when getting CSRF token" unless response.ok?
|
62
|
-
|
63
|
-
cookie_header = response.headers["set-cookie"]
|
64
|
-
attr = response.data.css("#csrf_token").first
|
65
|
-
csrf_token = attr[:value]
|
66
|
-
csrf_field = attr[:name]
|
67
|
-
|
68
|
-
response = Aitch.post(
|
69
|
-
url: url,
|
70
|
-
params: {email_list: "1000", email: [3], csrf_field => csrf_token},
|
71
|
-
headers: default_headers.merge({"cookie" => cookie_header})
|
72
|
-
)
|
73
|
-
|
74
|
-
throw "Received #{response.status} when fetching list" unless response.ok?
|
75
|
-
|
76
|
-
emails += response.data.css("#email-list-message a").map do |node|
|
77
|
-
mailbox, domain = node.text.gsub(/\+[^@]+/, "").split("@")
|
78
|
-
mailbox = mailbox.gsub(/\./m, "")
|
79
|
-
"#{mailbox}@#{domain}"
|
80
|
-
end
|
81
|
-
|
82
|
-
sleep random_timeout
|
83
|
-
end
|
84
|
-
|
85
|
-
append_to_file("disposable/gmailnator.txt", emails)
|
86
|
-
end
|
87
|
-
|
88
|
-
def domain_scraping(name, url, selector)
|
89
|
-
timeout(10) do
|
90
|
-
puts "=> Scraping #{url}"
|
91
|
-
|
92
|
-
selector, value_selector = selector.split("::")
|
93
|
-
path = "disposable/#{name}.txt"
|
94
|
-
host_regex = /@?(.*?(\.[^.]+)+)/
|
95
|
-
|
96
|
-
refresh_list(url: url, path: path) do |response|
|
97
|
-
new_domains = response
|
98
|
-
.data
|
99
|
-
.css(selector)
|
100
|
-
.map {|element| process_scraping(element, value_selector) }
|
101
|
-
|
102
|
-
new_domains = new_domains
|
103
|
-
.map(&:squish)
|
104
|
-
.reject(&:empty?)
|
105
|
-
.map {|domain| domain[host_regex, 1]&.squish&.tr("@", "") }
|
106
|
-
.reject(&:nil?)
|
107
|
-
.reject(&:empty?)
|
108
|
-
.map {|domain| domain.gsub(/\s*\((.*?)\)/, "") }
|
109
|
-
|
110
|
-
raise "No #{name} hosts found" if new_domains.empty?
|
111
|
-
|
112
|
-
new_domains
|
113
|
-
end
|
114
|
-
end
|
115
|
-
rescue StandardError => error
|
116
|
-
puts "=> [ERROR] Unable to scrape #{url}; #{error.class}: #{error.message}"
|
117
|
-
[]
|
118
|
-
end
|
119
|
-
|
120
|
-
def process_scraping(element, value_selector)
|
121
|
-
value = nil
|
122
|
-
|
123
|
-
case value_selector
|
124
|
-
when "text()"
|
125
|
-
value = element.text
|
126
|
-
when /^attr\((.*?)\)/
|
127
|
-
value = element[Regexp.last_match(1)]
|
128
|
-
else
|
129
|
-
element.attributes.each do |_name, attr|
|
130
|
-
attr = attr.value.to_s
|
131
|
-
value = attr if attr =~ host_regex
|
132
|
-
end
|
133
|
-
end
|
134
|
-
|
135
|
-
raise "no value found: #{element} (value_selector: #{value_selector})" unless value
|
136
|
-
|
137
|
-
value
|
138
|
-
end
|
139
|
-
|
140
|
-
def load_github_url(url)
|
141
|
-
puts "=> Fetching #{url}"
|
142
|
-
|
143
|
-
basename = URI.parse(url).path[%r{/([^/]+/[^/]+)}, 1].tr("/", "_").tr("-", "_")
|
144
|
-
path = "disposable/#{basename}.txt"
|
145
|
-
domains = load_file(path)
|
146
|
-
|
147
|
-
ext = File.extname(url)
|
148
|
-
|
149
|
-
domains += case ext
|
150
|
-
when ".json"
|
151
|
-
JSON.parse(http_request(:get, url).body)
|
152
|
-
when ".txt"
|
153
|
-
http_request(:get, url).body.lines.map(&:chomp)
|
154
|
-
else
|
155
|
-
raise "Unknown extension"
|
156
|
-
end
|
157
|
-
|
158
|
-
append_to_file(path, domains)
|
159
|
-
domains
|
160
|
-
rescue StandardError => error
|
161
|
-
puts "=> Unable to load #{url}; #{error.class}: #{error.message}"
|
162
|
-
[]
|
163
|
-
end
|
164
|
-
|
165
|
-
threads = []
|
166
|
-
|
167
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/ivolo/disposable-email-domains/master/index.json") }
|
168
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/andreis/disposable-email-domains/master/domains.json") }
|
169
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/FGRibreau/mailchecker/master/list.txt") }
|
170
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/willwhite/freemail/master/data/disposable.txt") }
|
171
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/maxmalysh/disposable-emails/master/disposable_emails/data/domains.txt") }
|
172
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/jespernissen/disposable-maildomain-list/master/disposable-maildomain-list.txt") }
|
173
|
-
threads << thread { load_github_url("https://raw.githubusercontent.com/wesbos/burner-email-providers/master/emails.txt") }
|
174
|
-
threads << thread { load_github_url("https://gist.github.com/fnando/dafe542cac13f831bbf5521a55248116/raw/disposable.txt") }
|
175
|
-
threads << thread { ten_minute_mail }
|
176
|
-
threads << thread { temp_mail }
|
177
|
-
threads << thread { temp_mail_address }
|
178
|
-
threads << thread { tempmail_io }
|
179
|
-
threads << thread { load_file("disposable/disposable_manually_added.txt") }
|
180
|
-
threads << thread { domain_scraping("guerrillamail", "https://www.guerrillamail.com/", "select option::attr(value)") }
|
181
|
-
threads << thread { domain_scraping("moakt", "https://www.moakt.com", "select option::attr(value)") }
|
182
|
-
threads << thread { domain_scraping("tempr", "https://tempr.email/", "select[name=DomainId] option::text()") }
|
183
|
-
threads << thread { domain_scraping("yepmail", "https://yepmail.co/", "select[name=domain] option::text()") }
|
184
|
-
threads << thread { domain_scraping("fake_email_generator", "https://fakemailgenerator.net", "[data-mailhost]::attr(data-mailhost)") }
|
185
|
-
threads << thread { domain_scraping("tempemails", "https://www.tempemails.net/", "select[name=domain] option::attr(value)") }
|
186
|
-
threads << thread { domain_scraping("clipmails", "https://clipmails.com/", "select[name=domain] option::attr(value)") }
|
187
|
-
threads << thread { domain_scraping("1secmail", "https://www.1secmail.com/", "select[id=domain] option::attr(value)") }
|
188
|
-
threads << thread { domain_scraping("emailfake", "https://generator.email", ".tt-suggestion p::text()") }
|
189
|
-
threads << thread { domain_scraping("emailfake", "https://emailfake.com/", ".tt-suggestion p::text()") }
|
190
|
-
threads << thread { domain_scraping("emailfake", "https://email-fake.com/", ".tt-suggestion p::text()") }
|
191
|
-
threads << thread { domain_scraping("receivemail", "https://www.receivemail.org/", "select[name=domain] option::text()") }
|
192
|
-
threads << thread { domain_scraping("itemp", "https://itemp.email", "select[name=domain] option::text()") }
|
193
|
-
threads << thread { domain_scraping("cs", "https://www.cs.email", "select[id=gm-host-select] option::text()") }
|
194
|
-
threads << thread { domain_scraping("tempmail", "https://tempmail.io/settings/", "select[id=domain] option::text()") }
|
195
|
-
threads << thread { domain_scraping("tempemail", "https://tempemail.co", "select[name=email_domain] option::text()") }
|
196
|
-
threads << thread { domain_scraping("tmail", "https://mytemp-email.com/", "a.domain-selector::text()") }
|
197
|
-
|
198
|
-
threads.each_slice(5) do |slice|
|
199
|
-
slice.each(&:join)
|
200
|
-
end
|
201
|
-
|
202
|
-
threads.clear
|
203
|
-
|
204
|
-
domains = []
|
205
|
-
|
206
|
-
puts "=> Loading disposable_domains.txt"
|
207
|
-
domains += File.read("#{__dir__}/../data/disposable_domains.txt").lines.map(&:chomp)
|
208
|
-
|
209
|
-
puts "=> Loading disposable/*.txt"
|
210
|
-
Dir["./data/disposable/**/*.txt"].map do |file|
|
211
|
-
file = File.expand_path(file)
|
212
|
-
domains += File.read(file).lines.map(&:chomp).flatten.compact
|
213
|
-
end
|
214
|
-
|
215
|
-
ignore_domains = %w[gmail.com hotmail.com]
|
216
|
-
|
217
|
-
puts "=> Normalize domains (count: #{domains.size})"
|
218
|
-
domains = domains
|
219
|
-
.uniq
|
220
|
-
.map {|domain| RootDomain.call(domain.split("@").last.downcase) }
|
221
|
-
.compact
|
222
|
-
.uniq
|
223
|
-
.reject {|domain| ignore_domains.include?(domain) }
|
224
|
-
|
225
|
-
puts "=> Saving domains (count: #{domains.size})"
|
226
|
-
save_file("disposable_domains.txt", domains)
|
227
|
-
|
228
|
-
emails = gmailnator
|
229
|
-
puts "=> Saving email proxies (count: #{emails.size})"
|
230
|
-
save_file("disposable_emails.txt", emails)
|