validators 3.3.0 → 3.4.2
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 +3 -18
- data/README.md +29 -24
- data/Rakefile +0 -1
- data/bin/sync-reserved-subdomains +96 -0
- data/data/reserved_subdomains.txt +4 -22
- data/lib/validators/disposable_domains.rb +18 -0
- data/lib/validators/disposable_emails.rb +7 -4
- data/lib/validators/ip.rb +6 -6
- data/lib/validators/locale/en.yml +5 -4
- data/lib/validators/locale/pt-BR.yml +7 -3
- data/lib/validators/tld.rb +7 -5
- data/lib/validators/validates_cnpj_format_of.rb +1 -2
- data/lib/validators/validates_cpf_format_of.rb +1 -2
- data/lib/validators/validates_datetime.rb +3 -2
- data/lib/validators/validates_email_format_of.rb +5 -5
- data/lib/validators/validates_ssh_private_key.rb +1 -3
- data/lib/validators/validates_ssh_public_key.rb +1 -3
- data/lib/validators/version.rb +2 -2
- data/lib/validators.rb +8 -1
- data/test/test_helper.rb +1 -2
- data/test/validators/disposable_email_test.rb +0 -2
- data/test/validators/validates_cnpj_format_of_test.rb +3 -3
- data/test/validators/validates_cpf_format_of_test.rb +3 -3
- data/test/validators/validates_email_format_of_test.rb +23 -0
- data/test/validators/validates_ssh_private_key/common_test.rb +3 -3
- data/test/validators/validates_ssh_public_key_test.rb +3 -3
- 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 +3 -1
- metadata +25 -46
- 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
@@ -25,10 +25,8 @@ module ActiveModel
|
|
25
25
|
# end
|
26
26
|
#
|
27
27
|
def validates_ssh_public_key(*attr_names)
|
28
|
-
|
28
|
+
Validators.require_dependency! "sshkey"
|
29
29
|
validates_with SshPublicKeyValidator, _merge_attributes(attr_names)
|
30
|
-
rescue LoadError
|
31
|
-
raise "sshkey is not part of the bundle. Add it to Gemfile."
|
32
30
|
end
|
33
31
|
end
|
34
32
|
end
|
data/lib/validators/version.rb
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
|
|
@@ -25,4 +25,11 @@ module Validators
|
|
25
25
|
require "validators/validates_username"
|
26
26
|
|
27
27
|
I18n.load_path += Dir[File.join(__dir__, "validators/locale/*.yml")]
|
28
|
+
|
29
|
+
def self.require_dependency!(dep)
|
30
|
+
require dep
|
31
|
+
rescue LoadError
|
32
|
+
raise "#{dep} is not part of the bundle. " \
|
33
|
+
"Add it to your project's Gemfile."
|
34
|
+
end
|
28
35
|
end
|
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) } +
|
@@ -13,9 +13,7 @@ class DisposableEmailTest < Minitest::Test
|
|
13
13
|
assert_includes user.errors[:email],
|
14
14
|
I18n.t("activerecord.errors.messages.disposable_domain")
|
15
15
|
end
|
16
|
-
end
|
17
16
|
|
18
|
-
DISPOSABLE_DOMAINS.each do |domain|
|
19
17
|
test "rejects disposable e-mail with subdomain (custom.#{domain})" do
|
20
18
|
User.validates_email_format_of :email
|
21
19
|
|
@@ -15,10 +15,10 @@ class ValidatesCnpjFormatOfTest < Minitest::Test
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
test "fails when
|
19
|
-
assert_raises do
|
18
|
+
test "fails when cpf_cnpj is not available" do
|
19
|
+
assert_raises(StandardError, /cpf_cnpj is not part of the bundle/) do
|
20
20
|
Class.new do
|
21
|
-
expects(:require).with("
|
21
|
+
Validators.expects(:require).with("cpf_cnpj").raises(LoadError, "-- cpf_cnpj")
|
22
22
|
|
23
23
|
include ActiveModel::Model
|
24
24
|
validates_cnpj_format_of :document
|
@@ -15,10 +15,10 @@ class ValidatesCpfFormatOfTest < Minitest::Test
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
test "fails when
|
19
|
-
assert_raises do
|
18
|
+
test "fails when cpf_cnpj is not available" do
|
19
|
+
assert_raises(StandardError, /cpf_cnpj is not part of the bundle/) do
|
20
20
|
Class.new do
|
21
|
-
expects(:require).with("
|
21
|
+
Validators.expects(:require).with("cpf_cnpj").raises(LoadError, "-- cpf_cnpj")
|
22
22
|
|
23
23
|
include ActiveModel::Model
|
24
24
|
validates_cpf_format_of :document
|
@@ -9,6 +9,29 @@ class ValidatesEmailFormatOfTest < Minitest::Test
|
|
9
9
|
Person.validates :email, email: true
|
10
10
|
end
|
11
11
|
|
12
|
+
test "fails when email_data is not available" do
|
13
|
+
assert_raises(StandardError, /email_data is not part of the bundle/) do
|
14
|
+
Class.new do
|
15
|
+
Validators.expects(:require).with("root_domain")
|
16
|
+
Validators.expects(:require).with("email_data").raises(LoadError, "-- email_data")
|
17
|
+
|
18
|
+
include ActiveModel::Model
|
19
|
+
validates_email :email
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
test "fails when root_domain is not available" do
|
25
|
+
assert_raises(StandardError, /root_domain is not part of the bundle/) do
|
26
|
+
Class.new do
|
27
|
+
Validators.expects(:require).with("root_domain").raises(LoadError, "-- root_domain")
|
28
|
+
|
29
|
+
include ActiveModel::Model
|
30
|
+
validates_email :email
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
12
35
|
VALID_EMAILS.each do |email|
|
13
36
|
test "accepts #{email.inspect} as a valid email" do
|
14
37
|
user = User.new(email: email, corporate_email: email)
|
@@ -15,10 +15,10 @@ class ValidatesSshPrivateKeyCommonTest < Minitest::Test
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
test "fails when
|
19
|
-
assert_raises do
|
18
|
+
test "fails when sshkey is not available" do
|
19
|
+
assert_raises(StandardError, /sshkey is not part of the bundle/) do
|
20
20
|
Class.new do
|
21
|
-
expects(:require).with("sshkey").raises(LoadError)
|
21
|
+
Validators.expects(:require).with("sshkey").raises(LoadError.new("-- sshkey"))
|
22
22
|
|
23
23
|
include ActiveModel::Model
|
24
24
|
validates_ssh_private_key :key
|
@@ -15,10 +15,10 @@ class ValidatesSsshPublicKeyCommonTest < Minitest::Test
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
-
test "fails when
|
19
|
-
assert_raises do
|
18
|
+
test "fails when sshkey is not available" do
|
19
|
+
assert_raises(StandardError, /sshkey is not part of the bundle/) do
|
20
20
|
Class.new do
|
21
|
-
expects(:require).with("sshkey").raises(LoadError)
|
21
|
+
Validators.expects(:require).with("sshkey").raises(LoadError, "-- sshkey")
|
22
22
|
|
23
23
|
include ActiveModel::Model
|
24
24
|
validates_ssh_public_key :key
|
@@ -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,9 +12,10 @@ 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.5.0")
|
16
|
+
s.metadata = {"rubygems_mfa_required" => "true"}
|
15
17
|
|
16
18
|
s.files = `git ls-files`.split("\n")
|
17
|
-
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
19
|
s.executables = `git ls-files -- bin/*`
|
19
20
|
.split("\n")
|
20
21
|
.map {|f| File.basename(f) }
|
@@ -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.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nando Vieira
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-22 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
|
@@ -266,28 +280,23 @@ description: Add some nice ActiveModel/ActiveRecord validators.
|
|
266
280
|
email:
|
267
281
|
- fnando.vieira@gmail.com
|
268
282
|
executables:
|
269
|
-
- sync-
|
270
|
-
- sync-tld
|
283
|
+
- sync-reserved-subdomains
|
271
284
|
extensions: []
|
272
285
|
extra_rdoc_files: []
|
273
286
|
files:
|
287
|
+
- ".github/FUNDING.yml"
|
274
288
|
- ".gitignore"
|
275
289
|
- ".rubocop.yml"
|
276
290
|
- ".travis.yml"
|
277
291
|
- Gemfile
|
278
292
|
- README.md
|
279
293
|
- Rakefile
|
280
|
-
- bin/sync-
|
281
|
-
- bin/sync-tld
|
282
|
-
- data/country_tlds.txt
|
283
|
-
- data/disposable_domains.txt
|
284
|
-
- data/disposable_emails.txt
|
294
|
+
- bin/sync-reserved-subdomains
|
285
295
|
- data/reserved_subdomains.txt
|
286
|
-
- data/tld.txt
|
287
296
|
- lib/validators.rb
|
288
297
|
- lib/validators/constants.rb
|
298
|
+
- lib/validators/disposable_domains.rb
|
289
299
|
- lib/validators/disposable_emails.rb
|
290
|
-
- lib/validators/disposable_hostnames.rb
|
291
300
|
- lib/validators/hostname.rb
|
292
301
|
- lib/validators/ip.rb
|
293
302
|
- lib/validators/locale/en.yml
|
@@ -342,7 +351,8 @@ files:
|
|
342
351
|
homepage: http://rubygems.org/gems/validators
|
343
352
|
licenses:
|
344
353
|
- MIT
|
345
|
-
metadata:
|
354
|
+
metadata:
|
355
|
+
rubygems_mfa_required: 'true'
|
346
356
|
post_install_message:
|
347
357
|
rdoc_options: []
|
348
358
|
require_paths:
|
@@ -351,46 +361,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
351
361
|
requirements:
|
352
362
|
- - ">="
|
353
363
|
- !ruby/object:Gem::Version
|
354
|
-
version:
|
364
|
+
version: 2.5.0
|
355
365
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
356
366
|
requirements:
|
357
367
|
- - ">="
|
358
368
|
- !ruby/object:Gem::Version
|
359
369
|
version: '0'
|
360
370
|
requirements: []
|
361
|
-
rubygems_version: 3.
|
371
|
+
rubygems_version: 3.3.7
|
362
372
|
signing_key:
|
363
373
|
specification_version: 4
|
364
374
|
summary: Add some nice ActiveModel/ActiveRecord validators.
|
365
|
-
test_files:
|
366
|
-
- test/schema.rb
|
367
|
-
- test/support/dates.rb
|
368
|
-
- test/support/emails.rb
|
369
|
-
- test/support/hostnames.rb
|
370
|
-
- test/support/ips.rb
|
371
|
-
- test/support/models.rb
|
372
|
-
- test/support/urls.rb
|
373
|
-
- test/test_helper.rb
|
374
|
-
- test/validators/disposable_email_test.rb
|
375
|
-
- test/validators/ip_test.rb
|
376
|
-
- test/validators/validates_cnpj_format_of_test.rb
|
377
|
-
- test/validators/validates_cpf_format_of_test.rb
|
378
|
-
- test/validators/validates_datetime/after_option_test.rb
|
379
|
-
- test/validators/validates_datetime/before_option_test.rb
|
380
|
-
- test/validators/validates_datetime/defaults_test.rb
|
381
|
-
- test/validators/validates_email_format_of_test.rb
|
382
|
-
- test/validators/validates_hostname_format_of/with_tld_validation_test.rb
|
383
|
-
- test/validators/validates_hostname_format_of/without_tld_validation_test.rb
|
384
|
-
- test/validators/validates_ip_address/ipv4_test.rb
|
385
|
-
- test/validators/validates_ip_address/ipv6_test.rb
|
386
|
-
- test/validators/validates_ip_address_test.rb
|
387
|
-
- test/validators/validates_ownership_of_test.rb
|
388
|
-
- test/validators/validates_ssh_private_key/bits_test.rb
|
389
|
-
- test/validators/validates_ssh_private_key/common_test.rb
|
390
|
-
- test/validators/validates_ssh_private_key/dsa_test.rb
|
391
|
-
- test/validators/validates_ssh_private_key/rsa_test.rb
|
392
|
-
- test/validators/validates_ssh_public_key_test.rb
|
393
|
-
- test/validators/validates_subdomain_test.rb
|
394
|
-
- test/validators/validates_url_format_of/with_tld_validation_test.rb
|
395
|
-
- test/validators/validates_url_format_of/without_tld_validation_test.rb
|
396
|
-
- test/validators/validates_username_test.rb
|
375
|
+
test_files: []
|
@@ -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)
|
data/bin/sync-tld
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
|
4
|
-
require_relative "helpers"
|
5
|
-
|
6
|
-
tlds = http_request(:get, "https://data.iana.org/TLD/tlds-alpha-by-domain.txt").body.lines
|
7
|
-
tlds.shift # remove update notice
|
8
|
-
|
9
|
-
tlds.map!(&:downcase)
|
10
|
-
tlds.map!(&:strip)
|
11
|
-
tlds.map! {|tld| SimpleIDN.to_ascii(tld) }
|
12
|
-
|
13
|
-
save_file("tld.txt", tlds)
|
14
|
-
|
15
|
-
country_tlds = JSON.parse(http_request(:get, "https://github.com/samayo/country-json/raw/master/src/country-by-domain-tld.json").body, symbolize_names: true)
|
16
|
-
country_tlds = country_tlds
|
17
|
-
.reject {|info| info[:tld].nil? }
|
18
|
-
.map {|info| info[:tld].gsub(/^\./, "") }
|
19
|
-
|
20
|
-
save_file("country_tlds.txt", country_tlds)
|