validators 3.2.1 → 3.3.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/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/README.md +4 -4
- data/bin/sync-disposable-hostnames +120 -110
- data/bin/sync-tld +2 -2
- data/data/country_tlds.txt +235 -0
- data/data/disposable_domains.txt +110996 -0
- data/data/disposable_emails.txt +38 -0
- data/data/reserved_subdomains.txt +2830 -0
- data/data/tld.txt +1508 -0
- data/lib/validators.rb +1 -0
- data/lib/validators/constants.rb +1 -1
- data/lib/validators/disposable_emails.rb +19 -0
- data/lib/validators/disposable_hostnames.rb +2 -2
- data/lib/validators/locale/en.yml +2 -1
- data/lib/validators/locale/pt-BR.yml +1 -0
- data/lib/validators/reserved_subdomains.rb +2 -4
- data/lib/validators/tld.rb +2 -2
- data/lib/validators/validates_email_format_of.rb +19 -4
- data/lib/validators/version.rb +2 -2
- data/test/test_helper.rb +17 -1
- data/test/validators/disposable_email_test.rb +18 -5
- data/test/validators/validates_email_format_of_test.rb +4 -2
- data/validators.gemspec +3 -0
- metadata +53 -43
- data/data/country_tlds.json +0 -237
- data/data/disposable.json +0 -128
- data/data/disposable/10minutemail.json +0 -3
- data/data/disposable/1secmail.json +0 -5
- data/data/disposable/FGRibreau_mailchecker.json +0 -33602
- data/data/disposable/andreis_disposable_email_domains.json +0 -48320
- data/data/disposable/clipmails.json +0 -27
- data/data/disposable/cs.json +0 -15
- data/data/disposable/emailfake.json +0 -128
- data/data/disposable/fake_email_generator.json +0 -11
- data/data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json +0 -20
- data/data/disposable/gmailnator.json +0 -3
- data/data/disposable/guerrillamail.json +0 -13
- data/data/disposable/ically.json +0 -28
- data/data/disposable/itemp.json +0 -4
- data/data/disposable/ivolo_disposable_email_domains.json +0 -48177
- data/data/disposable/jespernissen_disposable_maildomain_list.json +0 -2372
- data/data/disposable/maxmalysh_disposable_emails.json +0 -21372
- data/data/disposable/moakt.json +0 -12
- data/data/disposable/receivemail.json +0 -9
- data/data/disposable/sneakykiwi_LeagueCreatorPublic.json +0 -2364
- data/data/disposable/tempemail.json +0 -7
- data/data/disposable/tempemails.json +0 -10
- data/data/disposable/tempmail.json +0 -31
- data/data/disposable/tempmail_io.json +0 -8
- data/data/disposable/tempmailaddress.json +0 -4
- data/data/disposable/tempomail.json +0 -3
- data/data/disposable/tempr.json +0 -97
- data/data/disposable/tmail.json +0 -3
- data/data/disposable/wesbos_burner_email_providers.json +0 -4711
- data/data/disposable/willwhite_freemail.json +0 -352
- data/data/disposable/yepmail.json +0 -12
- data/data/disposable_emails.json +0 -3
- data/data/disposable_patterns.json +0 -3
- data/data/disposable_raw.json +0 -128
- data/data/reserved_subdomains.json +0 -2838
- data/data/sld.json +0 -5564
- data/data/tld.json +0 -1518
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 862ad7c2a49bcc38d917336b109047a330c6de6c6da16d83ea7953ddefe70096
         | 
| 4 | 
            +
              data.tar.gz: fb5e0b9db3ec0fdbc064eb6467cb36fab3d0f4bab6f29a5c8439c8d5edeb46fd
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: b8842cf3ee2161ef2fe18c384efdb5ff6407c135560a95b91689d29b8ff65d87272c599288de55a6422dfaa6ff4be3b0b00fbd7ea8a8472e47bc08acfb973a85
         | 
| 7 | 
            +
              data.tar.gz: 7a6fe664d6ef7a33735b8bf41cc198f8509a5712f788a2db93d6f2c4b39678ad6965eea1557fb6e43551a4d947a0cfd2e89c16a53c0721b6ada4390baa8cf293
         | 
    
        data/.gitignore
    CHANGED
    
    
    
        data/.rubocop.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -32,8 +32,7 @@ class User < ActiveRecord::Base | |
| 32 32 | 
             
            end
         | 
| 33 33 | 
             
            ```
         | 
| 34 34 |  | 
| 35 | 
            -
            By default, it rejects disposable e-mails (e.g. mailinator). This loads ~ | 
| 36 | 
            -
            but you can disable this validation by setting `disposable: true`.
         | 
| 35 | 
            +
            By default, it rejects disposable e-mails (e.g. mailinator). This loads a lot of data (~1.7MB), but you can disable this validation by setting `disposable: true`.
         | 
| 37 36 |  | 
| 38 37 | 
             
            ```ruby
         | 
| 39 38 | 
             
            class User < ActiveRecord::Base
         | 
| @@ -56,7 +55,7 @@ class User < ActiveRecord::Base | |
| 56 55 | 
             
              validates_url_format_of :site
         | 
| 57 56 |  | 
| 58 57 | 
             
              # validates TLD against list of valid TLD.
         | 
| 59 | 
            -
              # Loads ~ | 
| 58 | 
            +
              # Loads ~10KB of text.
         | 
| 60 59 | 
             
              validates_url_format_of :site, tld: true
         | 
| 61 60 | 
             
            end
         | 
| 62 61 | 
             
            ```
         | 
| @@ -153,7 +152,8 @@ A valid username/subdomain follows the hostname label validation: | |
| 153 152 | 
             
            - cannot begin or end with a hyphen
         | 
| 154 153 | 
             
            - cannot consist of numeric values only
         | 
| 155 154 |  | 
| 156 | 
            -
            The compiled list will be used for both username and subdomain validations.
         | 
| 155 | 
            +
            The compiled list will be used for both username and subdomain validations. 
         | 
| 156 | 
            +
            This validation loads ~20KB of text.
         | 
| 157 157 |  | 
| 158 158 | 
             
            ```ruby
         | 
| 159 159 | 
             
            class Server < ActiveRecord::Base
         | 
| @@ -4,18 +4,22 @@ | |
| 4 4 | 
             
            require_relative "helpers"
         | 
| 5 5 |  | 
| 6 6 | 
             
            def ten_minute_mail
         | 
| 7 | 
            -
              path = "disposable/10minutemail. | 
| 8 | 
            -
              url = "https://10minutemail.com/ | 
| 7 | 
            +
              path = "disposable/10minutemail.txt"
         | 
| 8 | 
            +
              url = "https://10minutemail.com/session/address"
         | 
| 9 9 |  | 
| 10 | 
            -
               | 
| 11 | 
            -
                 | 
| 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
         | 
| 12 16 |  | 
| 13 | 
            -
                 | 
| 17 | 
            +
                sleep random_timeout
         | 
| 14 18 | 
             
              end
         | 
| 15 19 | 
             
            end
         | 
| 16 20 |  | 
| 17 21 | 
             
            def temp_mail
         | 
| 18 | 
            -
              path = "disposable/tempmail. | 
| 22 | 
            +
              path = "disposable/tempmail.txt"
         | 
| 19 23 | 
             
              url = "https://api4.temp-mail.org/request/domains/format/json"
         | 
| 20 24 |  | 
| 21 25 | 
             
              refresh_list(url: url, path: path) do |response|
         | 
| @@ -24,7 +28,7 @@ def temp_mail | |
| 24 28 | 
             
            end
         | 
| 25 29 |  | 
| 26 30 | 
             
            def temp_mail_address
         | 
| 27 | 
            -
              path = "disposable/tempmailaddress. | 
| 31 | 
            +
              path = "disposable/tempmailaddress.txt"
         | 
| 28 32 | 
             
              url = "https://www.tempmailaddress.com/index/index"
         | 
| 29 33 |  | 
| 30 34 | 
             
              refresh_list(url: url, path: path) do |response|
         | 
| @@ -37,7 +41,7 @@ def temp_mail_address | |
| 37 41 | 
             
            end
         | 
| 38 42 |  | 
| 39 43 | 
             
            def tempmail_io
         | 
| 40 | 
            -
              path = "disposable/tempmail_io. | 
| 44 | 
            +
              path = "disposable/tempmail_io.txt"
         | 
| 41 45 | 
             
              url = "https://api.internal.temp-mail.io/api/v2/domains"
         | 
| 42 46 |  | 
| 43 47 | 
             
              refresh_list(url: url, path: path) do |response|
         | 
| @@ -46,69 +50,67 @@ def tempmail_io | |
| 46 50 | 
             
            end
         | 
| 47 51 |  | 
| 48 52 | 
             
            def gmailnator
         | 
| 49 | 
            -
               | 
| 50 | 
            -
              url = "https://gmailnator.com/index/indexquery"
         | 
| 51 | 
            -
             | 
| 52 | 
            -
              refresh_list(
         | 
| 53 | 
            -
                verb: :post,
         | 
| 54 | 
            -
                url: url,
         | 
| 55 | 
            -
                path: path,
         | 
| 56 | 
            -
                params: {action: "GenerateEmail"}
         | 
| 57 | 
            -
              ) do |response|
         | 
| 58 | 
            -
                email = response.body.gsub(/(\+[^@]+)/, "")
         | 
| 59 | 
            -
                [email]
         | 
| 60 | 
            -
              end
         | 
| 61 | 
            -
            end
         | 
| 53 | 
            +
              emails = []
         | 
| 62 54 |  | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 65 | 
            -
                {
         | 
| 66 | 
            -
                  domain: domain,
         | 
| 67 | 
            -
                  processed: domain.gsub(/\..*?$/, "")
         | 
| 68 | 
            -
                }
         | 
| 69 | 
            -
              end
         | 
| 55 | 
            +
              5.times do
         | 
| 56 | 
            +
                url = "https://gmailnator.com/bulk-emails"
         | 
| 57 | 
            +
                default_headers = {"user-agent" => USER_AGENT.sample}
         | 
| 70 58 |  | 
| 71 | 
            -
             | 
| 72 | 
            -
                      .count_by {|info| info[:processed] }
         | 
| 73 | 
            -
                      .select {|_processed, count| count > 2 }
         | 
| 59 | 
            +
                response = Aitch.get(url: url, headers: default_headers)
         | 
| 74 60 |  | 
| 75 | 
            -
             | 
| 76 | 
            -
                buffer[name] = count
         | 
| 77 | 
            -
              end
         | 
| 61 | 
            +
                throw "Received #{response.status} when getting CSRF token" unless response.ok?
         | 
| 78 62 |  | 
| 79 | 
            -
             | 
| 80 | 
            -
             | 
| 81 | 
            -
             | 
| 82 | 
            -
             | 
| 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]
         | 
| 83 67 |  | 
| 84 | 
            -
             | 
| 85 | 
            -
             | 
| 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 | 
            +
                )
         | 
| 86 73 |  | 
| 87 | 
            -
             | 
| 88 | 
            -
              puts "=> scraping #{url}"
         | 
| 74 | 
            +
                throw "Received #{response.status} when fetching list" unless response.ok?
         | 
| 89 75 |  | 
| 90 | 
            -
             | 
| 91 | 
            -
             | 
| 92 | 
            -
             | 
| 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
         | 
| 93 81 |  | 
| 94 | 
            -
             | 
| 95 | 
            -
             | 
| 96 | 
            -
             | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
             | 
| 105 | 
            -
             | 
| 106 | 
            -
             | 
| 107 | 
            -
             | 
| 108 | 
            -
             | 
| 109 | 
            -
             | 
| 110 | 
            -
             | 
| 111 | 
            -
             | 
| 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
         | 
| 112 114 | 
             
              end
         | 
| 113 115 | 
             
            rescue StandardError => error
         | 
| 114 116 | 
             
              puts "=> [ERROR] Unable to scrape #{url}; #{error.class}: #{error.message}"
         | 
| @@ -139,7 +141,7 @@ def load_github_url(url) | |
| 139 141 | 
             
              puts "=> Fetching #{url}"
         | 
| 140 142 |  | 
| 141 143 | 
             
              basename = URI.parse(url).path[%r{/([^/]+/[^/]+)}, 1].tr("/", "_").tr("-", "_")
         | 
| 142 | 
            -
              path = "disposable/#{basename}. | 
| 144 | 
            +
              path = "disposable/#{basename}.txt"
         | 
| 143 145 | 
             
              domains = load_file(path)
         | 
| 144 146 |  | 
| 145 147 | 
             
              ext = File.extname(url)
         | 
| @@ -155,48 +157,43 @@ def load_github_url(url) | |
| 155 157 |  | 
| 156 158 | 
             
              append_to_file(path, domains)
         | 
| 157 159 | 
             
              domains
         | 
| 158 | 
            -
            rescue error
         | 
| 160 | 
            +
            rescue StandardError => error
         | 
| 159 161 | 
             
              puts "=> Unable to load #{url}; #{error.class}: #{error.message}"
         | 
| 160 162 | 
             
              []
         | 
| 161 163 | 
             
            end
         | 
| 162 164 |  | 
| 163 | 
            -
            domains = []
         | 
| 164 165 | 
             
            threads = []
         | 
| 165 166 |  | 
| 166 | 
            -
            threads << thread {  | 
| 167 | 
            -
            threads << thread {  | 
| 168 | 
            -
            threads << thread {  | 
| 169 | 
            -
            threads << thread {  | 
| 170 | 
            -
            threads << thread {  | 
| 171 | 
            -
            threads << thread {  | 
| 172 | 
            -
            threads << thread {  | 
| 173 | 
            -
            threads << thread {  | 
| 174 | 
            -
            threads << thread {  | 
| 175 | 
            -
            threads << thread {  | 
| 176 | 
            -
            threads << thread {  | 
| 177 | 
            -
            threads << thread {  | 
| 178 | 
            -
            threads << thread {  | 
| 179 | 
            -
            threads << thread {  | 
| 180 | 
            -
            threads << thread {  | 
| 181 | 
            -
            threads << thread {  | 
| 182 | 
            -
            threads << thread {  | 
| 183 | 
            -
            threads << thread {  | 
| 184 | 
            -
            threads << thread {  | 
| 185 | 
            -
            threads << thread {  | 
| 186 | 
            -
            threads << thread {  | 
| 187 | 
            -
            threads << thread {  | 
| 188 | 
            -
            threads << thread {  | 
| 189 | 
            -
            threads << thread {  | 
| 190 | 
            -
            threads << thread {  | 
| 191 | 
            -
            threads << thread {  | 
| 192 | 
            -
            threads << thread {  | 
| 193 | 
            -
            threads << thread {  | 
| 194 | 
            -
            threads << thread {  | 
| 195 | 
            -
            threads << thread {  | 
| 196 | 
            -
            threads << thread { domains += domain_scraping("cs", "https://www.cs.email", "select[id=gm-host-select] option::text()") }
         | 
| 197 | 
            -
            threads << thread { domains += domain_scraping("tempmail", "https://tempmail.io/settings/", "select[id=domain] option::text()") }
         | 
| 198 | 
            -
            threads << thread { domains += domain_scraping("tempemail", "https://tempemail.co", "select[name=email_domain] option::text()") }
         | 
| 199 | 
            -
            threads << thread { domains += domain_scraping("tmail", "https://mytemp-email.com/", "a.domain-selector::text()") }
         | 
| 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()") }
         | 
| 200 197 |  | 
| 201 198 | 
             
            threads.each_slice(5) do |slice|
         | 
| 202 199 | 
             
              slice.each(&:join)
         | 
| @@ -204,17 +201,30 @@ end | |
| 204 201 |  | 
| 205 202 | 
             
            threads.clear
         | 
| 206 203 |  | 
| 207 | 
            -
             | 
| 208 | 
            -
             | 
| 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
         | 
| 209 214 |  | 
| 210 | 
            -
             | 
| 211 | 
            -
            domains = root_domains(domains)
         | 
| 215 | 
            +
            ignore_domains = %w[gmail.com hotmail.com]
         | 
| 212 216 |  | 
| 213 | 
            -
             | 
| 214 | 
            -
             | 
| 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) }
         | 
| 215 224 |  | 
| 216 | 
            -
             | 
| 217 | 
            -
            save_file(" | 
| 225 | 
            +
            puts "=> Saving domains (count: #{domains.size})"
         | 
| 226 | 
            +
            save_file("disposable_domains.txt", domains)
         | 
| 218 227 |  | 
| 219 | 
            -
             | 
| 220 | 
            -
             | 
| 228 | 
            +
            emails = gmailnator
         | 
| 229 | 
            +
            puts "=> Saving email proxies (count: #{emails.size})"
         | 
| 230 | 
            +
            save_file("disposable_emails.txt", emails)
         | 
    
        data/bin/sync-tld
    CHANGED
    
    | @@ -10,11 +10,11 @@ tlds.map!(&:downcase) | |
| 10 10 | 
             
            tlds.map!(&:strip)
         | 
| 11 11 | 
             
            tlds.map! {|tld| SimpleIDN.to_ascii(tld) }
         | 
| 12 12 |  | 
| 13 | 
            -
            save_file("tld. | 
| 13 | 
            +
            save_file("tld.txt", tlds)
         | 
| 14 14 |  | 
| 15 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 16 | 
             
            country_tlds = country_tlds
         | 
| 17 17 | 
             
                           .reject {|info| info[:tld].nil? }
         | 
| 18 18 | 
             
                           .map {|info| info[:tld].gsub(/^\./, "") }
         | 
| 19 19 |  | 
| 20 | 
            -
            save_file("country_tlds. | 
| 20 | 
            +
            save_file("country_tlds.txt", country_tlds)
         | 
| @@ -0,0 +1,235 @@ | |
| 1 | 
            +
            ad
         | 
| 2 | 
            +
            ae
         | 
| 3 | 
            +
            af
         | 
| 4 | 
            +
            ag
         | 
| 5 | 
            +
            ai
         | 
| 6 | 
            +
            al
         | 
| 7 | 
            +
            am
         | 
| 8 | 
            +
            an
         | 
| 9 | 
            +
            ao
         | 
| 10 | 
            +
            aq
         | 
| 11 | 
            +
            ar
         | 
| 12 | 
            +
            as
         | 
| 13 | 
            +
            at
         | 
| 14 | 
            +
            au
         | 
| 15 | 
            +
            aw
         | 
| 16 | 
            +
            az
         | 
| 17 | 
            +
            ba
         | 
| 18 | 
            +
            bb
         | 
| 19 | 
            +
            bd
         | 
| 20 | 
            +
            be
         | 
| 21 | 
            +
            bf
         | 
| 22 | 
            +
            bg
         | 
| 23 | 
            +
            bh
         | 
| 24 | 
            +
            bi
         | 
| 25 | 
            +
            bj
         | 
| 26 | 
            +
            bm
         | 
| 27 | 
            +
            bn
         | 
| 28 | 
            +
            bo
         | 
| 29 | 
            +
            br
         | 
| 30 | 
            +
            bs
         | 
| 31 | 
            +
            bt
         | 
| 32 | 
            +
            bv
         | 
| 33 | 
            +
            bw
         | 
| 34 | 
            +
            by
         | 
| 35 | 
            +
            bz
         | 
| 36 | 
            +
            ca
         | 
| 37 | 
            +
            cc
         | 
| 38 | 
            +
            cd
         | 
| 39 | 
            +
            cf
         | 
| 40 | 
            +
            cg
         | 
| 41 | 
            +
            ch
         | 
| 42 | 
            +
            ci
         | 
| 43 | 
            +
            ck
         | 
| 44 | 
            +
            cl
         | 
| 45 | 
            +
            cm
         | 
| 46 | 
            +
            cn
         | 
| 47 | 
            +
            co
         | 
| 48 | 
            +
            cr
         | 
| 49 | 
            +
            cu
         | 
| 50 | 
            +
            cv
         | 
| 51 | 
            +
            cx
         | 
| 52 | 
            +
            cy
         | 
| 53 | 
            +
            cz
         | 
| 54 | 
            +
            de
         | 
| 55 | 
            +
            dj
         | 
| 56 | 
            +
            dk
         | 
| 57 | 
            +
            dm
         | 
| 58 | 
            +
            do
         | 
| 59 | 
            +
            dz
         | 
| 60 | 
            +
            ec
         | 
| 61 | 
            +
            ee
         | 
| 62 | 
            +
            eg
         | 
| 63 | 
            +
            eh
         | 
| 64 | 
            +
            er
         | 
| 65 | 
            +
            es
         | 
| 66 | 
            +
            et
         | 
| 67 | 
            +
            fi
         | 
| 68 | 
            +
            fj
         | 
| 69 | 
            +
            fk
         | 
| 70 | 
            +
            fr
         | 
| 71 | 
            +
            ga
         | 
| 72 | 
            +
            gb
         | 
| 73 | 
            +
            gd
         | 
| 74 | 
            +
            ge
         | 
| 75 | 
            +
            gf
         | 
| 76 | 
            +
            gh
         | 
| 77 | 
            +
            gi
         | 
| 78 | 
            +
            gl
         | 
| 79 | 
            +
            gm
         | 
| 80 | 
            +
            gn
         | 
| 81 | 
            +
            gp
         | 
| 82 | 
            +
            gq
         | 
| 83 | 
            +
            gr
         | 
| 84 | 
            +
            gs
         | 
| 85 | 
            +
            gt
         | 
| 86 | 
            +
            gu
         | 
| 87 | 
            +
            gw
         | 
| 88 | 
            +
            gy
         | 
| 89 | 
            +
            hk
         | 
| 90 | 
            +
            hm
         | 
| 91 | 
            +
            hn
         | 
| 92 | 
            +
            hr
         | 
| 93 | 
            +
            ht
         | 
| 94 | 
            +
            hu
         | 
| 95 | 
            +
            id
         | 
| 96 | 
            +
            ie
         | 
| 97 | 
            +
            il
         | 
| 98 | 
            +
            in
         | 
| 99 | 
            +
            io
         | 
| 100 | 
            +
            iq
         | 
| 101 | 
            +
            ir
         | 
| 102 | 
            +
            is
         | 
| 103 | 
            +
            it
         | 
| 104 | 
            +
            jm
         | 
| 105 | 
            +
            jo
         | 
| 106 | 
            +
            jp
         | 
| 107 | 
            +
            ke
         | 
| 108 | 
            +
            kg
         | 
| 109 | 
            +
            kh
         | 
| 110 | 
            +
            ki
         | 
| 111 | 
            +
            km
         | 
| 112 | 
            +
            kn
         | 
| 113 | 
            +
            kp
         | 
| 114 | 
            +
            kr
         | 
| 115 | 
            +
            kw
         | 
| 116 | 
            +
            ky
         | 
| 117 | 
            +
            kz
         | 
| 118 | 
            +
            la
         | 
| 119 | 
            +
            lb
         | 
| 120 | 
            +
            lc
         | 
| 121 | 
            +
            li
         | 
| 122 | 
            +
            lk
         | 
| 123 | 
            +
            lr
         | 
| 124 | 
            +
            ls
         | 
| 125 | 
            +
            lt
         | 
| 126 | 
            +
            lu
         | 
| 127 | 
            +
            lv
         | 
| 128 | 
            +
            ly
         | 
| 129 | 
            +
            ma
         | 
| 130 | 
            +
            mc
         | 
| 131 | 
            +
            md
         | 
| 132 | 
            +
            mg
         | 
| 133 | 
            +
            mh
         | 
| 134 | 
            +
            mk
         | 
| 135 | 
            +
            ml
         | 
| 136 | 
            +
            mm
         | 
| 137 | 
            +
            mn
         | 
| 138 | 
            +
            mo
         | 
| 139 | 
            +
            mp
         | 
| 140 | 
            +
            mq
         | 
| 141 | 
            +
            mr
         | 
| 142 | 
            +
            ms
         | 
| 143 | 
            +
            mt
         | 
| 144 | 
            +
            mu
         | 
| 145 | 
            +
            mv
         | 
| 146 | 
            +
            mw
         | 
| 147 | 
            +
            mx
         | 
| 148 | 
            +
            my
         | 
| 149 | 
            +
            mz
         | 
| 150 | 
            +
            na
         | 
| 151 | 
            +
            nc
         | 
| 152 | 
            +
            ne
         | 
| 153 | 
            +
            nf
         | 
| 154 | 
            +
            ng
         | 
| 155 | 
            +
            ni
         | 
| 156 | 
            +
            nl
         | 
| 157 | 
            +
            no
         | 
| 158 | 
            +
            np
         | 
| 159 | 
            +
            nr
         | 
| 160 | 
            +
            nu
         | 
| 161 | 
            +
            nz
         | 
| 162 | 
            +
            om
         | 
| 163 | 
            +
            pa
         | 
| 164 | 
            +
            pe
         | 
| 165 | 
            +
            pf
         | 
| 166 | 
            +
            pg
         | 
| 167 | 
            +
            ph
         | 
| 168 | 
            +
            pk
         | 
| 169 | 
            +
            pl
         | 
| 170 | 
            +
            pm
         | 
| 171 | 
            +
            pn
         | 
| 172 | 
            +
            pr
         | 
| 173 | 
            +
            ps
         | 
| 174 | 
            +
            pt
         | 
| 175 | 
            +
            pw
         | 
| 176 | 
            +
            py
         | 
| 177 | 
            +
            qa
         | 
| 178 | 
            +
            re
         | 
| 179 | 
            +
            ro
         | 
| 180 | 
            +
            ru
         | 
| 181 | 
            +
            rw
         | 
| 182 | 
            +
            sa
         | 
| 183 | 
            +
            sb
         | 
| 184 | 
            +
            sc
         | 
| 185 | 
            +
            sd
         | 
| 186 | 
            +
            se
         | 
| 187 | 
            +
            sg
         | 
| 188 | 
            +
            sh
         | 
| 189 | 
            +
            si
         | 
| 190 | 
            +
            sj
         | 
| 191 | 
            +
            sk
         | 
| 192 | 
            +
            sl
         | 
| 193 | 
            +
            sm
         | 
| 194 | 
            +
            sn
         | 
| 195 | 
            +
            so
         | 
| 196 | 
            +
            sr
         | 
| 197 | 
            +
            ss
         | 
| 198 | 
            +
            st
         | 
| 199 | 
            +
            sv
         | 
| 200 | 
            +
            sy
         | 
| 201 | 
            +
            sz
         | 
| 202 | 
            +
            tc
         | 
| 203 | 
            +
            td
         | 
| 204 | 
            +
            tf
         | 
| 205 | 
            +
            tg
         | 
| 206 | 
            +
            th
         | 
| 207 | 
            +
            tj
         | 
| 208 | 
            +
            tk
         | 
| 209 | 
            +
            tl
         | 
| 210 | 
            +
            tm
         | 
| 211 | 
            +
            tn
         | 
| 212 | 
            +
            to
         | 
| 213 | 
            +
            tr
         | 
| 214 | 
            +
            tt
         | 
| 215 | 
            +
            tv
         | 
| 216 | 
            +
            tz
         | 
| 217 | 
            +
            ua
         | 
| 218 | 
            +
            ug
         | 
| 219 | 
            +
            us
         | 
| 220 | 
            +
            uy
         | 
| 221 | 
            +
            uz
         | 
| 222 | 
            +
            va
         | 
| 223 | 
            +
            vc
         | 
| 224 | 
            +
            ve
         | 
| 225 | 
            +
            vg
         | 
| 226 | 
            +
            vi
         | 
| 227 | 
            +
            vn
         | 
| 228 | 
            +
            vu
         | 
| 229 | 
            +
            wf
         | 
| 230 | 
            +
            ws
         | 
| 231 | 
            +
            ye
         | 
| 232 | 
            +
            yt
         | 
| 233 | 
            +
            za
         | 
| 234 | 
            +
            zm
         | 
| 235 | 
            +
            zw
         |