email_address 0.1.13 → 0.1.18
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/.travis.yml +1 -2
- data/README.md +42 -3
- data/email_address.gemspec +1 -0
- data/lib/email_address.rb +17 -18
- data/lib/email_address/active_record_validator.rb +2 -2
- data/lib/email_address/address.rb +94 -100
- data/lib/email_address/canonical_email_address_type.rb +14 -12
- data/lib/email_address/config.rb +69 -47
- data/lib/email_address/email_address_type.rb +15 -13
- data/lib/email_address/exchanger.rb +29 -30
- data/lib/email_address/host.rb +123 -125
- data/lib/email_address/local.rb +7 -7
- data/lib/email_address/version.rb +1 -1
- data/test/email_address/test_address.rb +5 -0
- data/test/email_address/test_host.rb +29 -31
- data/test/test_aliasing.rb +54 -0
- metadata +8 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 2a5ff67ec79e4de2d356293664296391fc8296ad6a6ba08f1d1256e93f7c729c
         | 
| 4 | 
            +
              data.tar.gz: 5485014c6f886d9a382c046f9025948eeed6c114accde2957424f1f613d1b51b
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 336f61eb9e81ccf8fe859b0d05e5e4d1aaf734e06328169ce919a01fdf30caaebdb2f44e673b52cdde99e3790c413c854e486fd97e4c610b5ee6349c1e3dbe40
         | 
| 7 | 
            +
              data.tar.gz: c08f83be388d6fdb646ea46439c0a65543091e401b9c9d38e312a7d2dc34313c3269f9c16916340d090f48ae224a1cd18631153d6478f87e32073f38e319ff28
         | 
    
        data/.travis.yml
    CHANGED
    
    
    
        data/README.md
    CHANGED
    
    | @@ -50,7 +50,7 @@ It does not check: | |
| 50 50 | 
             
            By default, MX records are required in DNS. MX or "mail exchanger" records
         | 
| 51 51 | 
             
            tell where to deliver email for the domain. Many domains run their
         | 
| 52 52 | 
             
            website on one provider (ISP, Heroku, etc.), and email on a different
         | 
| 53 | 
            -
            provider (such as  | 
| 53 | 
            +
            provider (such as G Suite).  Note that `example.com`, while
         | 
| 54 54 | 
             
            a valid domain name, does not have MX records.
         | 
| 55 55 |  | 
| 56 56 | 
             
            ```ruby
         | 
| @@ -248,6 +248,16 @@ EmailAddress.normal("HIRO@こんにちは世界.com") | |
| 248 248 | 
             
            EmailAddress.normal("hiro@xn--28j2a3ar1pp75ovm7c.com", host_encoding: :unicode)
         | 
| 249 249 | 
             
                                #=> "hiro@こんにちは世界.com"
         | 
| 250 250 | 
             
            ```
         | 
| 251 | 
            +
            As of release 0.1.17, exchanger_match is no longer used for host provider
         | 
| 252 | 
            +
            determination, which designated the set of rules for that domain.
         | 
| 253 | 
            +
            Sometimes, as in Google-hosted domains, the address
         | 
| 254 | 
            +
            rules are different, notably the optional dots in mailboxes for gmail.com
         | 
| 255 | 
            +
            accounts do not apply to other private domains hosted at google.
         | 
| 256 | 
            +
             | 
| 257 | 
            +
            To access the provider service, you can now call:
         | 
| 258 | 
            +
             | 
| 259 | 
            +
                EmailAddress.new("user@hosteddomain.com").host.hosted_provider
         | 
| 260 | 
            +
             | 
| 251 261 |  | 
| 252 262 | 
             
            #### Rails Validator
         | 
| 253 263 |  | 
| @@ -446,14 +456,16 @@ EmailAddress::Config.provider(:github, | |
| 446 456 | 
             
            You can override the default error messages as follows:
         | 
| 447 457 |  | 
| 448 458 | 
             
            ```ruby
         | 
| 449 | 
            -
            EmailAddress::Config.error_messages(
         | 
| 459 | 
            +
            EmailAddress::Config.error_messages({
         | 
| 450 460 | 
             
              invalid_address:    "Invalid Email Address",
         | 
| 451 461 | 
             
              invalid_mailbox:    "Invalid Recipient/Mailbox",
         | 
| 452 462 | 
             
              invalid_host:       "Invalid Host/Domain Name",
         | 
| 453 463 | 
             
              exceeds_size:       "Address too long",
         | 
| 454 464 | 
             
              not_allowed:        "Address is not allowed",
         | 
| 455 | 
            -
              incomplete_domain:  "Domain name is incomplete")
         | 
| 465 | 
            +
              incomplete_domain:  "Domain name is incomplete"}, 'en')
         | 
| 456 466 | 
             
            ```
         | 
| 467 | 
            +
            Note: Release 0.1.14 fixed setting error messages by locale.
         | 
| 468 | 
            +
            Also, it will accept a ruby "collected" hash as before,
         | 
| 457 469 |  | 
| 458 470 | 
             
            Full translation support would be ideal though.
         | 
| 459 471 |  | 
| @@ -540,6 +552,33 @@ The value is an array of match tokens. | |
| 540 552 | 
             
            * host_match:         %w(.org example.com hotmail. user*@ sub.*.com)
         | 
| 541 553 | 
             
            * exchanger_match:    %w(google.com 127.0.0.1 10.9.8.0/24 ::1/64)
         | 
| 542 554 |  | 
| 555 | 
            +
            ### Namespace conflict resolution
         | 
| 556 | 
            +
             | 
| 557 | 
            +
            If your application already uses the `EmailAddress` class name,
         | 
| 558 | 
            +
            it's possible to create an alias prior to loading your code:
         | 
| 559 | 
            +
             | 
| 560 | 
            +
            For a Rails application, you can do this in `config/application.rb`
         | 
| 561 | 
            +
            after the `Bundler.require` line, usually:
         | 
| 562 | 
            +
             | 
| 563 | 
            +
            ```ruby
         | 
| 564 | 
            +
            Bundler.require(*Rails.groups)
         | 
| 565 | 
            +
            ```
         | 
| 566 | 
            +
             | 
| 567 | 
            +
            Add these lines immediately after that point:
         | 
| 568 | 
            +
             | 
| 569 | 
            +
            ```ruby
         | 
| 570 | 
            +
            EmailAddressValidator = EmailAddress
         | 
| 571 | 
            +
            Object.send(:remove_const, :EmailAddress)
         | 
| 572 | 
            +
            ```
         | 
| 573 | 
            +
             | 
| 574 | 
            +
            Then your application loads with your EmailAddress class. You may
         | 
| 575 | 
            +
            then use this gem with `EmailAddressValidator` or whatever name you
         | 
| 576 | 
            +
            gave it above:
         | 
| 577 | 
            +
             | 
| 578 | 
            +
            ```ruby
         | 
| 579 | 
            +
            EmailAddressValidator.valid?("clark.kent@gmail.com") # => true
         | 
| 580 | 
            +
            ```
         | 
| 581 | 
            +
             | 
| 543 582 | 
             
            ## Notes
         | 
| 544 583 |  | 
| 545 584 | 
             
            #### Internationalization
         | 
    
        data/email_address.gemspec
    CHANGED
    
    | @@ -13,6 +13,7 @@ Gem::Specification.new do |spec| | |
| 13 13 | 
             
              spec.homepage      = "https://github.com/afair/email_address"
         | 
| 14 14 | 
             
              spec.license       = "MIT"
         | 
| 15 15 |  | 
| 16 | 
            +
              #spec.required_ruby_version = ">= 2.3.0"
         | 
| 16 17 | 
             
              spec.files         = `git ls-files`.split($/)
         | 
| 17 18 | 
             
              spec.executables   = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
         | 
| 18 19 | 
             
              spec.test_files    = spec.files.grep(%r{^(test|spec|features)/})
         | 
    
        data/lib/email_address.rb
    CHANGED
    
    | @@ -40,31 +40,30 @@ module EmailAddress | |
| 40 40 | 
             
              #   secret to use in options[:secret]
         | 
| 41 41 | 
             
              class << self
         | 
| 42 42 | 
             
                (%i[valid? error normal redact munge canonical reference base srs] &
         | 
| 43 | 
            -
                  | 
| 43 | 
            +
                 Address.public_instance_methods
         | 
| 44 44 | 
             
                ).each do |proxy_method|
         | 
| 45 45 | 
             
                  define_method(proxy_method) do |*args, &block|
         | 
| 46 | 
            -
                     | 
| 46 | 
            +
                    Address.new(*args).public_send(proxy_method, &block)
         | 
| 47 47 | 
             
                  end
         | 
| 48 48 | 
             
                end
         | 
| 49 | 
            -
              end
         | 
| 50 | 
            -
             | 
| 51 49 |  | 
| 52 | 
            -
             | 
| 53 | 
            -
             | 
| 54 | 
            -
             | 
| 55 | 
            -
             | 
| 56 | 
            -
             | 
| 50 | 
            +
                # Creates an instance of this email address.
         | 
| 51 | 
            +
                # This is a short-cut to EmailAddress::Address.new
         | 
| 52 | 
            +
                def new(email_address, config={})
         | 
| 53 | 
            +
                  Address.new(email_address, config)
         | 
| 54 | 
            +
                end
         | 
| 57 55 |  | 
| 58 | 
            -
             | 
| 59 | 
            -
             | 
| 60 | 
            -
             | 
| 56 | 
            +
                def new_redacted(email_address, config={})
         | 
| 57 | 
            +
                  Address.new(Address.new(email_address, config).redact)
         | 
| 58 | 
            +
                end
         | 
| 61 59 |  | 
| 62 | 
            -
             | 
| 63 | 
            -
             | 
| 64 | 
            -
             | 
| 60 | 
            +
                def new_canonical(email_address, config={})
         | 
| 61 | 
            +
                  Address.new(Address.new(email_address, config).canonical, config)
         | 
| 62 | 
            +
                end
         | 
| 65 63 |  | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 68 | 
            -
             | 
| 64 | 
            +
                # Does the email address match any of the given rules
         | 
| 65 | 
            +
                def matches?(email_address, rules, config={})
         | 
| 66 | 
            +
                  Address.new(email_address, config).matches?(rules)
         | 
| 67 | 
            +
                end
         | 
| 69 68 | 
             
              end
         | 
| 70 69 | 
             
            end
         | 
| @@ -35,10 +35,10 @@ module EmailAddress | |
| 35 35 |  | 
| 36 36 | 
             
                def validate_email(r,f)
         | 
| 37 37 | 
             
                  return if r[f].nil?
         | 
| 38 | 
            -
                  e =  | 
| 38 | 
            +
                  e = Address.new(r[f])
         | 
| 39 39 | 
             
                  unless e.valid?
         | 
| 40 40 | 
             
                    r.errors[f] << (@opt[:message] ||
         | 
| 41 | 
            -
                                    | 
| 41 | 
            +
                                   Config.error_messages[:invalid_address] ||
         | 
| 42 42 | 
             
                                   "Invalid Email Address")
         | 
| 43 43 | 
             
                  end
         | 
| 44 44 | 
             
                end
         | 
| @@ -1,46 +1,45 @@ | |
| 1 1 | 
             
            # frozen_string_literal: true
         | 
| 2 2 |  | 
| 3 | 
            -
            require  | 
| 4 | 
            -
            require  | 
| 3 | 
            +
            require "digest/sha1"
         | 
| 4 | 
            +
            require "digest/md5"
         | 
| 5 5 |  | 
| 6 6 | 
             
            module EmailAddress
         | 
| 7 7 | 
             
              # Implements the Email Address container, which hold the Local
         | 
| 8 | 
            -
              # (EmailAddress::Local) and Host ( | 
| 8 | 
            +
              # (EmailAddress::Local) and Host (EmailAddress::Host) parts.
         | 
| 9 9 | 
             
              class Address
         | 
| 10 10 | 
             
                include Comparable
         | 
| 11 | 
            -
                include  | 
| 11 | 
            +
                include Rewriter
         | 
| 12 12 |  | 
| 13 13 | 
             
                attr_accessor :original, :local, :host, :config, :reason
         | 
| 14 14 |  | 
| 15 | 
            -
                CONVENTIONAL_REGEX = /\A#{ | 
| 16 | 
            -
                                       @#{ | 
| 17 | 
            -
                STANDARD_REGEX | 
| 18 | 
            -
                                       @#{ | 
| 19 | 
            -
                RELAXED_REGEX | 
| 20 | 
            -
                                       @#{ | 
| 15 | 
            +
                CONVENTIONAL_REGEX = /\A#{Local::CONVENTIONAL_MAILBOX_WITHIN}
         | 
| 16 | 
            +
                                       @#{Host::DNS_HOST_REGEX}\z/x
         | 
| 17 | 
            +
                STANDARD_REGEX = /\A#{Local::STANDARD_LOCAL_WITHIN}
         | 
| 18 | 
            +
                                       @#{Host::DNS_HOST_REGEX}\z/x
         | 
| 19 | 
            +
                RELAXED_REGEX = /\A#{Local::RELAXED_MAILBOX_WITHIN}
         | 
| 20 | 
            +
                                       @#{Host::DNS_HOST_REGEX}\z/x
         | 
| 21 21 |  | 
| 22 22 | 
             
                # Given an email address of the form "local@hostname", this sets up the
         | 
| 23 23 | 
             
                # instance, and initializes the address to the "normalized" format of the
         | 
| 24 24 | 
             
                # address. The original string is available in the #original method.
         | 
| 25 | 
            -
                def initialize(email_address, config={})
         | 
| 26 | 
            -
                  @config | 
| 27 | 
            -
                  @original | 
| 28 | 
            -
                  email_address | 
| 29 | 
            -
                  email_address | 
| 30 | 
            -
                  local, host | 
| 31 | 
            -
             | 
| 32 | 
            -
                  @host | 
| 33 | 
            -
                  @ | 
| 34 | 
            -
                  @ | 
| 35 | 
            -
                  @error        = @error_message = nil
         | 
| 25 | 
            +
                def initialize(email_address, config = {})
         | 
| 26 | 
            +
                  @config = Config.new(config)
         | 
| 27 | 
            +
                  @original = email_address
         | 
| 28 | 
            +
                  email_address = (email_address || "").strip
         | 
| 29 | 
            +
                  email_address = parse_rewritten(email_address) unless config[:skip_rewrite]
         | 
| 30 | 
            +
                  local, host = Address.split_local_host(email_address)
         | 
| 31 | 
            +
             | 
| 32 | 
            +
                  @host = Host.new(host, @config)
         | 
| 33 | 
            +
                  @local = Local.new(local, @config, @host)
         | 
| 34 | 
            +
                  @error = @error_message = nil
         | 
| 36 35 | 
             
                end
         | 
| 37 36 |  | 
| 38 37 | 
             
                # Given an email address, this returns an array of [local, host] parts
         | 
| 39 38 | 
             
                def self.split_local_host(email)
         | 
| 40 | 
            -
                  if lh = email.match(/(.+)@(.+)/)
         | 
| 41 | 
            -
                    lh.to_a[1,2]
         | 
| 39 | 
            +
                  if (lh = email.match(/(.+)@(.+)/))
         | 
| 40 | 
            +
                    lh.to_a[1, 2]
         | 
| 42 41 | 
             
                  else
         | 
| 43 | 
            -
                    [email,  | 
| 42 | 
            +
                    [email, ""]
         | 
| 44 43 | 
             
                  end
         | 
| 45 44 | 
             
                end
         | 
| 46 45 |  | 
| @@ -54,26 +53,26 @@ module EmailAddress | |
| 54 53 |  | 
| 55 54 | 
             
                # Everything to the left of the @ in the address, called the local part.
         | 
| 56 55 | 
             
                def left
         | 
| 57 | 
            -
                   | 
| 56 | 
            +
                  local.to_s
         | 
| 58 57 | 
             
                end
         | 
| 59 58 |  | 
| 60 59 | 
             
                # Returns the mailbox portion of the local port, with no tags. Usually, this
         | 
| 61 60 | 
             
                # can be considered the user account or role account names. Some systems
         | 
| 62 61 | 
             
                # employ dynamic email addresses which don't have the same meaning.
         | 
| 63 62 | 
             
                def mailbox
         | 
| 64 | 
            -
                   | 
| 63 | 
            +
                  local.mailbox
         | 
| 65 64 | 
             
                end
         | 
| 66 65 |  | 
| 67 66 | 
             
                # Returns the tag part of the local address, or nil if not given.
         | 
| 68 67 | 
             
                def tag
         | 
| 69 | 
            -
                   | 
| 68 | 
            +
                  local.tag
         | 
| 70 69 | 
             
                end
         | 
| 71 70 |  | 
| 72 71 | 
             
                # Retuns any comments parsed from the local part of the email address.
         | 
| 73 72 | 
             
                # This is retained for inspection after construction, even if it is
         | 
| 74 73 | 
             
                # removed from the normalized email address.
         | 
| 75 74 | 
             
                def comment
         | 
| 76 | 
            -
                   | 
| 75 | 
            +
                  local.comment
         | 
| 77 76 | 
             
                end
         | 
| 78 77 |  | 
| 79 78 | 
             
                ############################################################################
         | 
| @@ -87,8 +86,8 @@ module EmailAddress | |
| 87 86 | 
             
                def host_name
         | 
| 88 87 | 
             
                  @host.host_name
         | 
| 89 88 | 
             
                end
         | 
| 90 | 
            -
                alias  | 
| 91 | 
            -
                alias  | 
| 89 | 
            +
                alias right host_name
         | 
| 90 | 
            +
                alias hostname host_name
         | 
| 92 91 |  | 
| 93 92 | 
             
                # Returns the ESP (Email Service Provider) or ISP name derived
         | 
| 94 93 | 
             
                # using the provider configuration rules.
         | 
| @@ -104,18 +103,18 @@ module EmailAddress | |
| 104 103 | 
             
                def normal
         | 
| 105 104 | 
             
                  if !@original
         | 
| 106 105 | 
             
                    @original
         | 
| 107 | 
            -
                  elsif  | 
| 106 | 
            +
                  elsif local.to_s.size == 0
         | 
| 108 107 | 
             
                    ""
         | 
| 109 | 
            -
                  elsif  | 
| 110 | 
            -
                     | 
| 108 | 
            +
                  elsif host.to_s.size == 0
         | 
| 109 | 
            +
                    local.to_s
         | 
| 111 110 | 
             
                  else
         | 
| 112 | 
            -
                    "#{ | 
| 111 | 
            +
                    "#{local}@#{host}"
         | 
| 113 112 | 
             
                  end
         | 
| 114 113 | 
             
                end
         | 
| 115 | 
            -
                alias  | 
| 114 | 
            +
                alias to_s normal
         | 
| 116 115 |  | 
| 117 116 | 
             
                def inspect
         | 
| 118 | 
            -
                  " | 
| 117 | 
            +
                  "#<#{self.class}:0x#{object_id.to_s(16)} address=\"#{self}\">"
         | 
| 119 118 | 
             
                end
         | 
| 120 119 |  | 
| 121 120 | 
             
                # Returns the canonical email address according to the provider
         | 
| @@ -123,56 +122,56 @@ module EmailAddress | |
| 123 122 | 
             
                # spaves and comments and tags, and any extraneous part of the address
         | 
| 124 123 | 
             
                # not considered a unique account by the provider.
         | 
| 125 124 | 
             
                def canonical
         | 
| 126 | 
            -
                  c =  | 
| 127 | 
            -
                  c += "@" +  | 
| 125 | 
            +
                  c = local.canonical
         | 
| 126 | 
            +
                  c += "@" + host.canonical if host.canonical && host.canonical > " "
         | 
| 128 127 | 
             
                  c
         | 
| 129 128 | 
             
                end
         | 
| 130 129 |  | 
| 131 130 | 
             
                # True if the given address is already in it's canonical form.
         | 
| 132 131 | 
             
                def canonical?
         | 
| 133 | 
            -
                   | 
| 132 | 
            +
                  canonical == to_s
         | 
| 134 133 | 
             
                end
         | 
| 135 134 |  | 
| 136 135 | 
             
                # The base address is the mailbox, without tags, and host.
         | 
| 137 136 | 
             
                def base
         | 
| 138 | 
            -
                   | 
| 137 | 
            +
                  mailbox + "@" + hostname
         | 
| 139 138 | 
             
                end
         | 
| 140 139 |  | 
| 141 140 | 
             
                # Returns the redacted form of the address
         | 
| 142 141 | 
             
                # This format is defined by this libaray, and may change as usage increases.
         | 
| 143 142 | 
             
                # Takes either :sha1 (default) or :md5 as the argument
         | 
| 144 | 
            -
                def redact(digest | 
| 145 | 
            -
                  raise "Unknown Digest type: #{digest}" unless %i | 
| 146 | 
            -
                  return  | 
| 147 | 
            -
                  r = % | 
| 148 | 
            -
                  r += "@" +  | 
| 143 | 
            +
                def redact(digest = :sha1)
         | 
| 144 | 
            +
                  raise "Unknown Digest type: #{digest}" unless %i[sha1 md5].include?(digest)
         | 
| 145 | 
            +
                  return to_s if local.redacted?
         | 
| 146 | 
            +
                  r = %({#{send(digest)}})
         | 
| 147 | 
            +
                  r += "@" + host.to_s if host.to_s && host.to_s > " "
         | 
| 149 148 | 
             
                  r
         | 
| 150 149 | 
             
                end
         | 
| 151 150 |  | 
| 152 151 | 
             
                # True if the address is already in the redacted state.
         | 
| 153 152 | 
             
                def redacted?
         | 
| 154 | 
            -
                   | 
| 153 | 
            +
                  local.redacted?
         | 
| 155 154 | 
             
                end
         | 
| 156 155 |  | 
| 157 156 | 
             
                # Returns the munged form of the address, by default "mailbox@domain.tld"
         | 
| 158 157 | 
             
                # returns "ma*****@do*****".
         | 
| 159 158 | 
             
                def munge
         | 
| 160 | 
            -
                  [ | 
| 159 | 
            +
                  [local.munge, host.munge].join("@")
         | 
| 161 160 | 
             
                end
         | 
| 162 161 |  | 
| 163 162 | 
             
                # Returns and MD5 of the canonical address form. Some cross-system systems
         | 
| 164 163 | 
             
                # use the email address MD5 instead of the actual address to refer to the
         | 
| 165 164 | 
             
                # same shared user identity without exposing the actual address when it
         | 
| 166 165 | 
             
                # is not known in common.
         | 
| 167 | 
            -
                def reference(form | 
| 168 | 
            -
                  Digest::MD5.hexdigest( | 
| 166 | 
            +
                def reference(form = :base)
         | 
| 167 | 
            +
                  Digest::MD5.hexdigest(send(form))
         | 
| 169 168 | 
             
                end
         | 
| 170 | 
            -
                alias  | 
| 169 | 
            +
                alias md5 reference
         | 
| 171 170 |  | 
| 172 171 | 
             
                # This returns the SHA1 digest (in a hex string) of the canonical email
         | 
| 173 172 | 
             
                # address. See #md5 for more background.
         | 
| 174 | 
            -
                def sha1(form | 
| 175 | 
            -
                  Digest::SHA1.hexdigest(( | 
| 173 | 
            +
                def sha1(form = :base)
         | 
| 174 | 
            +
                  Digest::SHA1.hexdigest((send(form) || "") + (@config[:sha1_secret] || ""))
         | 
| 176 175 | 
             
                end
         | 
| 177 176 |  | 
| 178 177 | 
             
                #---------------------------------------------------------------------------
         | 
| @@ -182,41 +181,41 @@ module EmailAddress | |
| 182 181 | 
             
                # Equal matches the normalized version of each address. Use the Threequal to check
         | 
| 183 182 | 
             
                # for match on canonical or redacted versions of addresses
         | 
| 184 183 | 
             
                def ==(other_email)
         | 
| 185 | 
            -
                   | 
| 184 | 
            +
                  to_s == other_email.to_s
         | 
| 186 185 | 
             
                end
         | 
| 187 | 
            -
                alias  | 
| 188 | 
            -
                alias  | 
| 186 | 
            +
                alias eql? ==
         | 
| 187 | 
            +
                alias equal? ==
         | 
| 189 188 |  | 
| 190 189 | 
             
                # Return the <=> or CMP comparison operator result (-1, 0, +1) on the comparison
         | 
| 191 190 | 
             
                # of this addres with another, using the canonical or redacted forms.
         | 
| 192 191 | 
             
                def same_as?(other_email)
         | 
| 193 192 | 
             
                  if other_email.is_a?(String)
         | 
| 194 | 
            -
                    other_email =  | 
| 193 | 
            +
                    other_email = Address.new(other_email)
         | 
| 195 194 | 
             
                  end
         | 
| 196 195 |  | 
| 197 | 
            -
                   | 
| 198 | 
            -
                     | 
| 199 | 
            -
                     | 
| 196 | 
            +
                  canonical == other_email.canonical ||
         | 
| 197 | 
            +
                    redact == other_email.canonical ||
         | 
| 198 | 
            +
                    canonical == other_email.redact
         | 
| 200 199 | 
             
                end
         | 
| 201 | 
            -
                alias  | 
| 200 | 
            +
                alias include? same_as?
         | 
| 202 201 |  | 
| 203 202 | 
             
                # Return the <=> or CMP comparison operator result (-1, 0, +1) on the comparison
         | 
| 204 203 | 
             
                # of this addres with another, using the normalized form.
         | 
| 205 204 | 
             
                def <=>(other_email)
         | 
| 206 | 
            -
                   | 
| 205 | 
            +
                  to_s <=> other_email.to_s
         | 
| 207 206 | 
             
                end
         | 
| 208 207 |  | 
| 209 208 | 
             
                # Address matches one of these Matcher rule patterns
         | 
| 210 209 | 
             
                def matches?(*rules)
         | 
| 211 210 | 
             
                  rules.flatten!
         | 
| 212 | 
            -
                  match | 
| 213 | 
            -
                  match ||=  | 
| 211 | 
            +
                  match = local.matches?(rules)
         | 
| 212 | 
            +
                  match ||= host.matches?(rules)
         | 
| 214 213 | 
             
                  return match if match
         | 
| 215 214 |  | 
| 216 215 | 
             
                  # Does "root@*.com" match "root@example.com" domain name
         | 
| 217 216 | 
             
                  rules.each do |r|
         | 
| 218 | 
            -
                    if r | 
| 219 | 
            -
                      return r if File.fnmatch?(r,  | 
| 217 | 
            +
                    if r.match(/.+@.+/)
         | 
| 218 | 
            +
                      return r if File.fnmatch?(r, to_s)
         | 
| 220 219 | 
             
                    end
         | 
| 221 220 | 
             
                  end
         | 
| 222 221 | 
             
                  false
         | 
| @@ -228,24 +227,24 @@ module EmailAddress | |
| 228 227 |  | 
| 229 228 | 
             
                # Returns true if this address is considered valid according to the format
         | 
| 230 229 | 
             
                # configured for its provider, It test the normalized form.
         | 
| 231 | 
            -
                def valid?(options={})
         | 
| 230 | 
            +
                def valid?(options = {})
         | 
| 232 231 | 
             
                  @error = nil
         | 
| 233 | 
            -
                  unless  | 
| 234 | 
            -
                    return set_error  | 
| 232 | 
            +
                  unless local.valid?
         | 
| 233 | 
            +
                    return set_error local.error
         | 
| 235 234 | 
             
                  end
         | 
| 236 | 
            -
                  unless  | 
| 237 | 
            -
                    return set_error  | 
| 235 | 
            +
                  unless host.valid?
         | 
| 236 | 
            +
                    return set_error host.error_message
         | 
| 238 237 | 
             
                  end
         | 
| 239 | 
            -
                  if @config[:address_size] && !@config[:address_size].include?( | 
| 238 | 
            +
                  if @config[:address_size] && !@config[:address_size].include?(to_s.size)
         | 
| 240 239 | 
             
                    return set_error :exceeds_size
         | 
| 241 240 | 
             
                  end
         | 
| 242 241 | 
             
                  if @config[:address_validation].is_a?(Proc)
         | 
| 243 | 
            -
                    unless @config[:address_validation].call( | 
| 242 | 
            +
                    unless @config[:address_validation].call(to_s)
         | 
| 244 243 | 
             
                      return set_error :not_allowed
         | 
| 245 244 | 
             
                    end
         | 
| 246 245 | 
             
                  else
         | 
| 247 | 
            -
                    return false unless  | 
| 248 | 
            -
                    return false unless  | 
| 246 | 
            +
                    return false unless local.valid?
         | 
| 247 | 
            +
                    return false unless host.valid?
         | 
| 249 248 | 
             
                  end
         | 
| 250 249 | 
             
                  true
         | 
| 251 250 | 
             
                end
         | 
| @@ -254,42 +253,37 @@ module EmailAddress | |
| 254 253 | 
             
                # as an email address check, but is provided to assist in problem resolution.
         | 
| 255 254 | 
             
                # If you abuse this, you *could* be blocked by the ESP.
         | 
| 256 255 | 
             
                def connect
         | 
| 257 | 
            -
                   | 
| 258 | 
            -
             | 
| 259 | 
            -
             | 
| 260 | 
            -
             | 
| 261 | 
            -
             | 
| 262 | 
            -
             | 
| 256 | 
            +
                  smtp = Net::SMTP.new(host_name || ip_address)
         | 
| 257 | 
            +
                  smtp.start(@config[:smtp_helo_name] || "localhost")
         | 
| 258 | 
            +
                  smtp.mailfrom @config[:smtp_mail_from] || "postmaster@localhost"
         | 
| 259 | 
            +
                  smtp.rcptto to_s
         | 
| 260 | 
            +
                  # p [:connect]
         | 
| 261 | 
            +
                  smtp.finish
         | 
| 262 | 
            +
                  true
         | 
| 263 | 
            +
                rescue Net::SMTPUnknownError => e
         | 
| 264 | 
            +
                  set_error(:address_unknown, e.to_s)
         | 
| 265 | 
            +
                rescue Net::SMTPFatalError => e
         | 
| 266 | 
            +
                  set_error(:address_unknown, e.to_s)
         | 
| 267 | 
            +
                rescue SocketError => e
         | 
| 268 | 
            +
                  set_error(:address_unknown, e.to_s)
         | 
| 269 | 
            +
                ensure
         | 
| 270 | 
            +
                  if smtp&.started?
         | 
| 263 271 | 
             
                    smtp.finish
         | 
| 264 | 
            -
                    true
         | 
| 265 | 
            -
                  rescue Net::SMTPUnknownError => e
         | 
| 266 | 
            -
                    set_error(:address_unknown, e.to_s)
         | 
| 267 | 
            -
                  rescue Net::SMTPFatalError => e
         | 
| 268 | 
            -
                    set_error(:address_unknown, e.to_s)
         | 
| 269 | 
            -
                  rescue SocketError => e
         | 
| 270 | 
            -
                    set_error(:address_unknown, e.to_s)
         | 
| 271 | 
            -
                  ensure
         | 
| 272 | 
            -
                    if smtp && smtp.started?
         | 
| 273 | 
            -
                      smtp.finish
         | 
| 274 | 
            -
                    end
         | 
| 275 | 
            -
                    !!@error
         | 
| 276 272 | 
             
                  end
         | 
| 273 | 
            +
                  !!@error
         | 
| 277 274 | 
             
                end
         | 
| 278 275 |  | 
| 279 | 
            -
                def set_error(err, reason=nil)
         | 
| 276 | 
            +
                def set_error(err, reason = nil)
         | 
| 280 277 | 
             
                  @error = err
         | 
| 281 | 
            -
                  @reason= reason
         | 
| 282 | 
            -
                  @error_message =  | 
| 278 | 
            +
                  @reason = reason
         | 
| 279 | 
            +
                  @error_message = Config.error_message(err)
         | 
| 283 280 | 
             
                  false
         | 
| 284 281 | 
             
                end
         | 
| 285 282 |  | 
| 286 | 
            -
                 | 
| 287 | 
            -
                  @error_message
         | 
| 288 | 
            -
                end
         | 
| 283 | 
            +
                attr_reader :error_message
         | 
| 289 284 |  | 
| 290 285 | 
             
                def error
         | 
| 291 | 
            -
                   | 
| 286 | 
            +
                  valid? ? nil : @error_message
         | 
| 292 287 | 
             
                end
         | 
| 293 | 
            -
             | 
| 294 288 | 
             
              end
         | 
| 295 289 | 
             
            end
         |