Skip to content

Commit

Permalink
Colorize examples in README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
biow0lf authored Jan 14, 2018
1 parent 19bbc36 commit 363edb8
Showing 1 changed file with 146 additions and 112 deletions.
258 changes: 146 additions & 112 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@ To quickly validate email addresses, use the valid? and error helpers.
`valid?` returns a boolean, and `error` returns nil if valid, otherwise
a basic error message.

EmailAddress.valid? "[email protected]" #=> true
EmailAddress.error "[email protected]" #=> "Invalid Host/Domain Name"
```ruby
EmailAddress.valid? "[email protected]" #=> true
EmailAddress.error "[email protected]" #=> "Invalid Host/Domain Name"
```

`EmailAddress` deeply validates your email addresses. It checks:

Expand All @@ -48,14 +50,17 @@ website on one provider (ISP, Heroku, etc.), and email on a different
provider (such as Google Apps). Note that `example.com`, while
a valid domain name, does not have MX records.

EmailAddress.valid? "[email protected]" #=> false
EmailAddress.valid? "[email protected]", host_validation: :syntax #=> true
```ruby
EmailAddress.valid? "[email protected]" #=> false
EmailAddress.valid? "[email protected]", host_validation: :syntax #=> true
```

Most mail servers do not yet support Unicode mailboxes, so the default here is ASCII.

EmailAddress.error "Pelé@google.com" #=> "Invalid Recipient/Mailbox"
EmailAddress.valid? "Pelé@google.com", local_encoding: :unicode #=> true

```ruby
EmailAddress.error "Pelé@google.com" #=> "Invalid Recipient/Mailbox"
EmailAddress.valid? "Pelé@google.com", local_encoding: :unicode #=> true
```

## Background

Expand Down Expand Up @@ -186,8 +191,10 @@ If you are not using Bundler, you need to install the gem yourself.

Require the gem inside your script.

require 'rubygems'
require 'email_address'
```ruby
require 'rubygems'
require 'email_address'
```

## Usage

Expand All @@ -197,41 +204,47 @@ instantiate an object to inspect the address.
These top-level helpers return edited email addresses and validation
check.

address = "[email protected]"
EmailAddress.valid?(address) #=> true
EmailAddress.normal(address) #=> "[email protected]"
EmailAddress.canonical(address) #=> "[email protected]"
EmailAddress.reference(address) #=> "c5be3597c391169a5ad2870f9ca51901"
EmailAddress.redact(address) #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
EmailAddress.munge(address) #=> "cl*****@gm*****"
EmailAddress.matches?(address, 'google') #=> 'google' (true)
EmailAddress.error("#[email protected]") #=> "Invalid Mailbox"
```ruby
address = "[email protected]"
EmailAddress.valid?(address) #=> true
EmailAddress.normal(address) #=> "[email protected]"
EmailAddress.canonical(address) #=> "[email protected]"
EmailAddress.reference(address) #=> "c5be3597c391169a5ad2870f9ca51901"
EmailAddress.redact(address) #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
EmailAddress.munge(address) #=> "cl*****@gm*****"
EmailAddress.matches?(address, 'google') #=> 'google' (true)
EmailAddress.error("#[email protected]") #=> "Invalid Mailbox"
```

Or you can create an instance of the email address to work with it.

email = EmailAddress.new(address) #=> #<EmailAddress::Address:0x007fe6ee150540 ...>
email.normal #=> "[email protected]"
email.canonical #=> "[email protected]"
email.original #=> "[email protected]"
email.valid? #=> true
```ruby
email = EmailAddress.new(address) #=> #<EmailAddress::Address:0x007fe6ee150540 ...>
email.normal #=> "[email protected]"
email.canonical #=> "[email protected]"
email.original #=> "[email protected]"
email.valid? #=> true
```

Here are some other methods that are available.

email.redact #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
email.sha1 #=> "bea3f3560a757f8142d38d212a931237b218eb5e"
email.md5 #=> "c5be3597c391169a5ad2870f9ca51901"
email.host_name #=> "gmail.com"
email.provider #=> :google
email.mailbox #=> "clark.kent"
email.tag #=> "scoops"
```ruby
email.redact #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
email.sha1 #=> "bea3f3560a757f8142d38d212a931237b218eb5e"
email.md5 #=> "c5be3597c391169a5ad2870f9ca51901"
email.host_name #=> "gmail.com"
email.provider #=> :google
email.mailbox #=> "clark.kent"
email.tag #=> "scoops"

email.host.exchanger.first[:ip] #=> "2a00:1450:400b:c02::1a"
email.host.txt_hash #=> {:v=>"spf1", :redirect=>"\_spf.google.com"}
email.host.exchanger.first[:ip] #=> "2a00:1450:400b:c02::1a"
email.host.txt_hash #=> {:v=>"spf1", :redirect=>"\_spf.google.com"}

EmailAddress.normal("HIRO@こんにちは世界.com")
#=> "[email protected]"
EmailAddress.normal("[email protected]", host_encoding: :unicode)
#=> "hiro@こんにちは世界.com"
EmailAddress.normal("HIRO@こんにちは世界.com")
#=> "[email protected]"
EmailAddress.normal("[email protected]", host_encoding: :unicode)
#=> "hiro@こんにちは世界.com"
```

#### Rails Validator

Expand All @@ -240,9 +253,11 @@ Specify your email address attributes with `field: :user_email`, or
`fields: [:email1, :email2]`. If neither is given, it assumes to use the
`email` or `email_address` attribute.

class User < ActiveRecord::Base
validates_with EmailAddress::ActiveRecordValidator, field: :email
end
```ruby
class User < ActiveRecord::Base
validates_with EmailAddress::ActiveRecordValidator, field: :email
end
```

#### Rails Email Address Type Attribute

Expand All @@ -252,9 +267,11 @@ First, you need to register the type in
`config/initializers/email_address.rb` along with any global
configurations you want.

ActiveRecord::Type.register(:email_address, EmailAddress::EmailAddressType)
ActiveRecord::Type.register(:canonical_email_address,
EmailAddress::CanonicalEmailAddressType)
```ruby
ActiveRecord::Type.register(:email_address, EmailAddress::EmailAddressType)
ActiveRecord::Type.register(:canonical_email_address,
EmailAddress::CanonicalEmailAddressType)
```

Assume the Users table contains the columns "email" and "canonical_email".
We want to normalize the address in "email" and store the canonical/unique
Expand All @@ -263,39 +280,42 @@ the email attribute is assigned. With the canonical_email column,
we can look up the User, even it the given email address didn't exactly
match the registered version.

class User < ApplicationRecord
attribute :email, :email_address
attribute :canonical_email, :canonical_email_address

validates_with EmailAddress::ActiveRecordValidator,
fields: %i(email canonical_email)

def email=(email_address)
self[:canonical_email] = email_address
self[:email] = email_address
end

def self.find_by_email(email)
user = self.find_by(email: EmailAddress.normal(email))
user ||= self.find_by(canonical_email: EmailAddress.canonical(email))
user ||= self.find_by(canonical_email: EmailAddress.redacted(email))
user
end

def redact!
self[:canonical_email] = EmailAddress.redact(self.canonical_email)
self[:email] = self[:canonical_email]
end
end
```ruby
class User < ApplicationRecord
attribute :email, :email_address
attribute :canonical_email, :canonical_email_address

validates_with EmailAddress::ActiveRecordValidator,
fields: %i(email canonical_email)

def email=(email_address)
self[:canonical_email] = email_address
self[:email] = email_address
end

def self.find_by_email(email)
user = self.find_by(email: EmailAddress.normal(email))
user ||= self.find_by(canonical_email: EmailAddress.canonical(email))
user ||= self.find_by(canonical_email: EmailAddress.redacted(email))
user
end

def redact!
self[:canonical_email] = EmailAddress.redact(self.canonical_email)
self[:email] = self[:canonical_email]
end
end
```

Here is how the User model works:

user = User.create(email:"[email protected]")
user.email #=> "[email protected]"
user.canonical_email #=> "[email protected]"
User.find_by_email("[email protected]")
#=> #<User email="[email protected]">

```ruby
user = User.create(email:"[email protected]")
user.email #=> "[email protected]"
user.canonical_email #=> "[email protected]"
User.find_by_email("[email protected]")
#=> #<User email="[email protected]">
```

The `find_by_email` method looks up a given email address by the
normalized form (lower case), then by the canonical form, then finally
Expand All @@ -318,17 +338,19 @@ which syntax and network validations to perform.

You can compare email addresses:

e1 = EmailAddress.new("[email protected]")
e2 = EmailAddress.new("[email protected]")
e3 = EmailAddress.new(e2.redact)
e1.to_s #=> "[email protected]"
e2.to_s #=> "[email protected]"
e3.to_s #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
```ruby
e1 = EmailAddress.new("[email protected]")
e2 = EmailAddress.new("[email protected]")
e3 = EmailAddress.new(e2.redact)
e1.to_s #=> "[email protected]"
e2.to_s #=> "[email protected]"
e3.to_s #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"

e1 == e2 #=> false (Matches by normalized address)
e1.same_as?(e2) #=> true (Matches as canonical address)
e1.same_as?(e3) #=> true (Matches as redacted address)
e1 < e2 #=> true (Compares using normalized address)
e1 == e2 #=> false (Matches by normalized address)
e1.same_as?(e2) #=> true (Matches as canonical address)
e1.same_as?(e3) #=> true (Matches as redacted address)
e1 < e2 #=> true (Compares using normalized address)
```ruby
#### Matching
Expand All @@ -345,40 +367,50 @@ Matching addresses by simple patterns:
Usage:
e = EmailAddress.new("[email protected]")
e.matches?("gmail.com") #=> true
e.matches?("google") #=> true
e.matches?(".org") #=> false
e.matches?("g*com") #=> true
e.matches?("gmail.") #=> true
e.matches?("*kent*@") #=> true
```ruby
e = EmailAddress.new("[email protected]")
e.matches?("gmail.com") #=> true
e.matches?("google") #=> true
e.matches?(".org") #=> false
e.matches?("g*com") #=> true
e.matches?("gmail.") #=> true
e.matches?("*kent*@") #=> true
```

### Configuration

You can pass an options hash on the `.new()` and helper class methods to
control how the library treats that address. These can also be
configured during initialization by provider and default (see below).

EmailAddress.new("[email protected]",
host_validation: :syntax, host_encoding: :unicode)
```ruby
EmailAddress.new("[email protected]",
host_validation: :syntax, host_encoding: :unicode)
```

Globally, you can change and query configuration options:

EmailAddress::Config.setting(:host_validation, :mx)
EmailAddress::Config.setting(:host_validation) #=> :mx
```ruby
EmailAddress::Config.setting(:host_validation, :mx)
EmailAddress::Config.setting(:host_validation) #=> :mx
```

Or set multiple settings at once:

EmailAddress::Config.configure(local_downcase:false, host_validation: :syntax)
```ruby
EmailAddress::Config.configure(local_downcase: false, host_validation: :syntax)
```

You can add special rules by domain or provider. It takes the options
above and adds the :domain_match and :exchanger_match rules.

EmailAddress.define_provider('google',
domain_match: %w(gmail.com googlemail.com),
exchanger_match: %w(google.com), # Requires host_validation==:mx
local_size: 5..64,
mailbox_canonical: ->(m) {m.gsub('.','')})
```ruby
EmailAddress.define_provider('google',
domain_match: %w(gmail.com googlemail.com),
exchanger_match: %w(google.com), # Requires host_validation==:mx
local_size: 5..64,
mailbox_canonical: ->(m) {m.gsub('.','')})
```

The library ships with the most common set of provider rules. It is not meant
to house a database of all providers, but a separate `email_address-providers`
Expand All @@ -396,26 +428,29 @@ DNS. If you specify an exchanger pattern, but requires a DNS MX lookup.
For Rails application, create an initializer file with your default
configuration options:

# ./config/initializers/email_address.rb
EmailAddress::Config.setting( local_format: :relaxed )
EmailAddress::Config.provider(:github,
host_match: %w(github.com), local_format: :standard)
```ruby
# ./config/initializers/email_address.rb
EmailAddress::Config.setting( local_format: :relaxed )
EmailAddress::Config.provider(:github,
host_match: %w(github.com), local_format: :standard)
```

#### Override Error Messaegs

You can override the default error messages as follows:

EmailAddress::Config.error_messages(
invalid_address: "Invalid Email Address",
invalid_mailbox: "Invalid Recipient/Mailbox",
invalid_host: "Invalid Host/Domain Name",
exceeds_size: "Address too long",
not_allowed: "Address is not allowed",
incomplete_domain: "Domain name is incomplete")
```ruby
EmailAddress::Config.error_messages(
invalid_address: "Invalid Email Address",
invalid_mailbox: "Invalid Recipient/Mailbox",
invalid_host: "Invalid Host/Domain Name",
exceeds_size: "Address too long",
not_allowed: "Address is not allowed",
incomplete_domain: "Domain name is incomplete")
```

Full translation support would be ideal though.


### Available Configuration Settings

* sha1_secret -
Expand Down Expand Up @@ -518,7 +553,6 @@ Proper personal identity can still be provided using
[MIME Encoded-Words](http://en.wikipedia.org/wiki/MIME#Encoded-Word)
in Email headers.


#### Email Addresses as Sensitive Data

Like Social Security and Credit Card Numbers, email addresses are
Expand Down

0 comments on commit 363edb8

Please sign in to comment.