email_address 0.2.6 โ†’ 0.2.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f6fb959ca75da2d73ed378a3b2f97b4dceead14d634cf24ff5ce18c5a52f0e4a
4
- data.tar.gz: 47dd7dcb50a3e11b99d2be141dc1e3737b41b7a2b0f13ec80fb83ef59bc68d15
3
+ metadata.gz: '09a47fb94c722c1b77e1b88f60eb9b275c10b0af362b7e951688b16edb8b8956'
4
+ data.tar.gz: 518cd6502197567e1819218bff259a596eae8d5521d89c69a4dd3d691047b04a
5
5
  SHA512:
6
- metadata.gz: '097d2fa911cef5a006f7280e569107fcba3c18a025597fc89a18fb542e49bb4603efd1bae6ad39d68f9514ed26b27ea4e7890f018a32fa7e6d80ee608ebb6f4e'
7
- data.tar.gz: 1c688907c73eb2dad9d64793fda1f2a8baece32f694710f9384a50cb92584c59b169f425d776e7d85a918d17cdcd5995f063fe8143f559d27241103f8e6114d5
6
+ metadata.gz: ed80c20ef002dca0ec0280e2a3e418b4f77811dcac90ee338e186a39b88151817aed715e5cf50aea20755fcd1a3aec5df7dba9ed4381d540da861b51a33c1326
7
+ data.tar.gz: 387e799ca2eef4de99232f36d2a8be0bcc69d3616d49cb2f499c856595c6abb2ac7ae02b9d9d5c3b667356a645700ffc03a59124997daa00354d22b22d26d29d
data/README.md CHANGED
@@ -4,29 +4,66 @@
4
4
  [![CI Build](https://github.com/afair/email_address/actions/workflows/ci.yml/badge.svg)](https://github.com/afair/email_address/actions/workflows/ci.yml)
5
5
  [![Code Climate](https://codeclimate.com/github/afair/email_address/badges/gpa.svg)](https://codeclimate.com/github/afair/email_address)
6
6
 
7
- The `email_address` gem provides a ruby language library for working
8
- with email addresses.
9
-
10
- By default, it validates against conventional usage,
11
- the format preferred for user email addresses.
12
- It can be configured to validate against RFC "Standard" formats,
13
- common email service provider formats, and perform DNS validation.
14
-
15
- Using `email_address` to validate user email addresses results in
16
- fewer "false positives" due to typing errors and gibberish data.
17
- It validates syntax more strictly for popular email providers,
18
- and can deal with gmail's "optional dots" in addresses.
19
-
20
- It provides Active Record (Rails) extensions, including an
21
- address validator and attributes API custom datatypes.
22
-
23
- Requires Ruby 2.0 or later.
7
+ The `email_address` ruby gem is an opinionated validation library for
8
+ email addresses. The [RFC 5322](https://www.rfc-editor.org/rfc/rfc5322#section-3.4)
9
+ address specification defines them as extensions to the email
10
+ header syntax, not as a useful method for creating email transport
11
+ systems with user accounts, mailboxes, and routing.
12
+
13
+ The library follows "real world" email address patterns for end-user addresses.
14
+
15
+ - "Conventional" format (the default) fits most user email accounts
16
+ as created by major email service providers and software.
17
+ Only 7-bit ASCII characters are supported in the local (left) part.
18
+ - "Relaxed" format loosely follows conventional, allowing a looser
19
+ punctuation format.
20
+ - "Standard" format follows the RFC. This is provided for non-user
21
+ addresses, such as uniquely-generated destinations for
22
+ consumption between automated systems.
23
+
24
+ RFC "Standard" Addresses allow syntaxes that most developers do not want:
25
+
26
+ - Mailboxes are case-sensitive.
27
+ - Double-quoted tokens can contain spaces, "@" symbols, and unusual punctuation.
28
+ - Parenthetical comment fields can appear at the beginning or end
29
+ of the local (left) part.
30
+ - Addresses do not have to have fully-qualified domain names
31
+ - The Host part (after the "@") can be an IP Address
32
+
33
+ Additionally, this library respects "address tags", a convention
34
+ not specified by the RFC, with which email providers and software
35
+ append an identifier or route to the mailbox, usually after a "+" symbol.
36
+
37
+ Configuration options include specialized address formats for the largest
38
+ ESP (Email service providers) to validate against their formats.
39
+
40
+ If you have false negatives with "conventional" format, try the
41
+ `local_format: :relaxed` option. To validate to the RFC only, use the
42
+ `local_format: :standard` option. When possible, confirm the address
43
+ with the user if conventional check fails but relaxed succeeds.
44
+
45
+ Remember: the only true way to validate an email address is to successfully
46
+ send email to it. SMTP checks can help, but should only be done politely
47
+ to avoid blacklisting your application. Several (unaffiliated) services
48
+ exist to do this for you.
49
+
50
+ Finally, there are conveniences to handle storage and management of
51
+ address digests for PII removal or sharing addresses without revealing them.
52
+
53
+ The gem requires ruby only, but includes a, optional Ruby on Rails helper for
54
+ those who need to use it with ActiveRecord.
24
55
 
25
56
  Looking for a Javascript version of this library? Check out the
26
57
  [email_address](https://www.npmjs.com/package/email_address) npm module.
27
58
 
28
59
  ## Quick Start
29
60
 
61
+ Install the gem to your project with bundler:
62
+
63
+ bundle add email_address
64
+
65
+ or with the gem command:
66
+
30
67
  To quickly validate email addresses, use the valid? and error helpers.
31
68
  `valid?` returns a boolean, and `error` returns nil if valid, otherwise
32
69
  a basic error message.
@@ -38,19 +75,19 @@ EmailAddress.error "allen@bad-d0main.com" #=> "Invalid Host/Domain Name"
38
75
 
39
76
  `EmailAddress` deeply validates your email addresses. It checks:
40
77
 
41
- * Host name format and DNS setup
42
- * Mailbox format according to "conventional" form. This matches most used user
78
+ - Host name format and DNS setup
79
+ - Mailbox format according to "conventional" form. This matches most used user
43
80
  email accounts, but is a subset of the RFC specification.
44
81
 
45
82
  It does not check:
46
83
 
47
- * The mail server is configured to accept connections
48
- * The mailbox is valid and accepts email.
84
+ - The mail server is configured to accept connections
85
+ - The mailbox is valid and accepts email.
49
86
 
50
87
  By default, MX records are required in DNS. MX or "mail exchanger" records
51
88
  tell where to deliver email for the domain. Many domains run their
52
89
  website on one provider (ISP, Heroku, etc.), and email on a different
53
- provider (such as G Suite). Note that `example.com`, while
90
+ provider (such as G Suite). Note that `example.com`, while
54
91
  a valid domain name, does not have MX records.
55
92
 
56
93
  ```ruby
@@ -71,134 +108,91 @@ The email address specification is complex and often not what you want
71
108
  when working with personal email addresses in applications. This library
72
109
  introduces terms to distinguish types of email addresses.
73
110
 
74
- * *Normal* - The edited form of any input email address. Typically, it
111
+ - _Normal_ - The edited form of any input email address. Typically, it
75
112
  is lower-cased and minor "fixes" can be performed, depending on the
76
113
  configurations and email address provider.
77
114
 
78
- CKENT@DAILYPLANET.NEWS => ckent@dailyplanet.news
115
+ <CKENT@DAILYPLANET.NEWS> => <ckent@dailyplanet.news>
79
116
 
80
- * *Conventional* - Most personal account addresses are in this basic
117
+ - _Conventional_ - Most personal account addresses are in this basic
81
118
  format, one or more "words" separated by a single simple punctuation
82
119
  character. It consists of a mailbox (user name or role account) and
83
120
  an optional address "tag" assigned by the user.
84
121
 
85
- miles.o'brien@ncc-1701-d.ufp
122
+ miles.o'<brien@ncc-1701-d.ufp>
86
123
 
87
- * *Relaxed* - A less strict form of Conventional, same character set,
124
+ - _Relaxed_ - A less strict form of Conventional, same character set,
88
125
  must begin and end with an alpha-numeric character, but order within
89
126
  is not enforced.
90
127
 
91
- aasdf-34-.z@example.com
128
+ <aasdf-34-.z@example.com>
92
129
 
93
- * *Standard* - The RFC-Compliant syntax of an email address. This is
130
+ - _Standard_ - The RFC-Compliant syntax of an email address. This is
94
131
  useful when working with software-generated addresses or handling
95
132
  existing email addresses, but otherwise not useful for personal
96
133
  addresses.
97
134
 
98
- madness!."()<>[]:,;@\\\"!#$%&'*+-/=?^_`{}| ~.a(comment )"@example.org
135
+ madness!."()<>[]:,;@\\\"!#$%&'\*+-/=?^\_`{}| ~.a(comment )"@example.org
99
136
 
100
- * *Base* - A unique mailbox without tags. For gmail, is uses the incoming
137
+ - _Base_ - A unique mailbox without tags. For gmail, is uses the incoming
101
138
  punctation, essential when building an MD5, SHA1, or SHA256 to match services
102
139
  like Gravatar, and email address digest interchange.
103
140
 
104
- * *Canonical* - An unique account address, lower-cased, without the
141
+ - _Canonical_ - An unique account address, lower-cased, without the
105
142
  tag, and with irrelevant characters stripped.
106
143
 
107
- clark.kent+scoops@gmail.com => clarkkent@gmail.com
144
+ <clark.kent+scoops@gmail.com> => <clarkkent@gmail.com>
108
145
 
109
- * *Reference* - The MD5 of the Base format, used to share account
146
+ - _Reference_ - The MD5 of the Base format, used to share account
110
147
  references without exposing the private email address directly.
111
148
 
112
- Clark.Kent+scoops@gmail.com =>
113
- clark.kent@gmail.com => 1429a1dfc797d6e93075fef011c373fb
149
+ <Clark.Kent+scoops@gmail.com> =>
150
+ <clark.kent@gmail.com> => 1429a1dfc797d6e93075fef011c373fb
114
151
 
115
- * *Redacted* - A form of the email address where it is replaced by
152
+ - _Redacted_ - A form of the email address where it is replaced by
116
153
  a SHA1-based version to remove the original address from the
117
154
  database, or to store the address privately, yet still keep it
118
155
  accessible at query time by converting the queried address to
119
156
  the redacted form.
120
157
 
121
- Clark.Kent+scoops@gmail.com => {bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com
158
+ <Clark.Kent+scoops@gmail.com> => {bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com
122
159
 
123
- * *Munged* - An obfuscated version of the email address suitable for
160
+ - _Munged_ - An obfuscated version of the email address suitable for
124
161
  publishing on the internet, where email address harvesting
125
162
  could occur.
126
163
 
127
- Clark.Kent+scoops@gmail.com => cl\*\*\*\*\*@gm\*\*\*\*\*
164
+ <Clark.Kent+scoops@gmail.com> => cl\*\*\*\*\*@gm\*\*\*\*\*
128
165
 
129
166
  Other terms:
130
167
 
131
- * *Local* - The left-hand side of the "@", representing the user,
168
+ - _Local_ - The left-hand side of the "@", representing the user,
132
169
  mailbox, or role, and an optional "tag".
133
170
 
134
- mailbox+tag@example.com; Local part: mailbox+tag
171
+ <mailbox+tag@example.com>; Local part: mailbox+tag
135
172
 
136
- * *Mailbox* - The destination user account or role account.
137
- * *Tag* - A parameter added after the mailbox, usually after the
173
+ - _Mailbox_ - The destination user account or role account.
174
+ - _Tag_ - A parameter added after the mailbox, usually after the
138
175
  "+" symbol, set by the user for mail filtering and sub-accounts.
139
176
  Not all mail systems support this.
140
- * *Host* (sometimes called *Domain*) - The right-hand side of the "@"
177
+ - _Host_ (sometimes called _Domain_) - The right-hand side of the "@"
141
178
  indicating the domain or host name server to delivery the email.
142
179
  If missing, "localhost" is assumed, or if not a fully-qualified
143
180
  domain name, it assumed another computer on the same network, but
144
181
  this is increasingly rare.
145
- * *Provider* - The Email Service Provider (ESP) providing the email
182
+ - _Provider_ - The Email Service Provider (ESP) providing the email
146
183
  service. Each provider may have its own email address validation
147
184
  and canonicalization rules.
148
- * *Punycode* - A host name with Unicode characters (International
185
+ - _Punycode_ - A host name with Unicode characters (International
149
186
  Domain Name or IDN) needs conversion to this ASCII-encoded format
150
187
  for DNS lookup.
151
188
 
152
- "HIRO@ใ“ใ‚“ใซใกใฏไธ–็•Œ.com" => "hiro@xn--28j2a3ar1pp75ovm7c.com"
189
+ "HIRO@ใ“ใ‚“ใซใกใฏไธ–็•Œ.com" => "<hiro@xn--28j2a3ar1pp75ovm7c.com>"
153
190
 
154
191
  Wikipedia has a great article on
155
192
  [Email Addresses](https://en.wikipedia.org/wiki/Email_address),
156
193
  much more readable than the section within
157
194
  [RFC 5322](https://tools.ietf.org/html/rfc5322#section-3.4)
158
195
 
159
- ## Avoiding the Bad Parts of RFC Specification
160
-
161
- Following the RFC specification sounds like a good idea, until you
162
- learn about all the madness contained therein. This library can
163
- validate the RFC syntax, but this is never useful, especially when
164
- validating user email address submissions. By default, it validates
165
- to the *conventional* format.
166
-
167
- Here are a few parts of the RFC specification you should avoid:
168
-
169
- * Case-sensitive local parts: `First.Last@example.com`
170
- * Spaces and Special Characters: `"():;<>@[\\]`
171
- * Quoting and Escaping Requirements: `"first \"nickname\" last"@example.com`
172
- * Comment Parts: `(comment)mailbox@example.com`
173
- * IP and IPv6 addresses as hosts: `mailbox@[127.0.0.1]`
174
- * Non-ASCII (7-bit) characters in the local part: `Pelรฉ@example.com`
175
- * Validation by voodoo regular expressions
176
- * Gmail allows ".." in addresses since they are not meaningful, but
177
- the standard does not.
178
-
179
- ## Installation With Rails or Bundler
180
-
181
- If you are using Rails or a project with Bundler, add this line to your application's Gemfile:
182
-
183
- gem 'email_address'
184
-
185
- And then execute:
186
-
187
- $ bundle
188
-
189
- ## Installation Without Bundler
190
-
191
- If you are not using Bundler, you need to install the gem yourself.
192
-
193
- $ gem install email_address
194
-
195
- Require the gem inside your script.
196
-
197
- ```ruby
198
- require 'rubygems'
199
- require 'email_address'
200
- ```
201
-
202
196
  ## Usage
203
197
 
204
198
  Use `EmailAddress` to do transformations and validations. You can also
@@ -231,7 +225,7 @@ email.valid? #=> true
231
225
 
232
226
  Here are some other methods that are available.
233
227
 
234
- ```ruby
228
+ ````ruby
235
229
  email.redact #=> "{bea3f3560a757f8142d38d212a931237b218eb5e}@gmail.com"
236
230
  email.sha1 #=> "bea3f3560a757f8142d38d212a931237b218eb5e"
237
231
  email.sha256 #=> "9e2a0270f2d6778e5f647fc9eaf6992705ca183c23d1ed1166586fd54e859f75"
@@ -248,17 +242,6 @@ EmailAddress.normal("HIRO@ใ“ใ‚“ใซใกใฏไธ–็•Œ.com")
248
242
  #=> "hiro@xn--28j2a3ar1pp75ovm7c.com"
249
243
  EmailAddress.normal("hiro@xn--28j2a3ar1pp75ovm7c.com", host_encoding: :unicode)
250
244
  #=> "hiro@ใ“ใ‚“ใซใกใฏไธ–็•Œ.com"
251
- ```
252
- As of release 0.1.17, exchanger_match is no longer used for host provider
253
- determination, which designated the set of rules for that domain.
254
- Sometimes, as in Google-hosted domains, the address
255
- rules are different, notably the optional dots in mailboxes for gmail.com
256
- accounts do not apply to other private domains hosted at google.
257
-
258
- To access the provider service, you can now call:
259
-
260
- EmailAddress.new("user@hosteddomain.com").host.hosted_provider
261
-
262
245
 
263
246
  #### Rails Validator
264
247
 
@@ -271,7 +254,7 @@ Specify your email address attributes with `field: :user_email`, or
271
254
  class User < ActiveRecord::Base
272
255
  validates_with EmailAddress::ActiveRecordValidator, field: :email
273
256
  end
274
- ```
257
+ ````
275
258
 
276
259
  #### Rails I18n
277
260
 
@@ -359,7 +342,7 @@ by the redacted form.
359
342
  The only true validation is to send a message to the email address and
360
343
  have the user (or process) verify it has been received. Syntax checks
361
344
  help prevent erroneous input. Even sent messages can be silently
362
- dropped, or bounced back after acceptance. Conditions such as a
345
+ dropped, or bounced back after acceptance. Conditions such as a
363
346
  "Mailbox Full" can mean the email address is known, but abandoned.
364
347
 
365
348
  There are different levels of validations you can perform. By default, it will
@@ -389,14 +372,14 @@ e1 < e2 #=> true (Compares using normalized address)
389
372
 
390
373
  Matching addresses by simple patterns:
391
374
 
392
- * Top-Level-Domain: .org
393
- * Domain Name: example.com
394
- * Registration Name: hotmail. (matches any TLD)
395
- * Domain Glob: *.exampl?.com
396
- * Provider Name: google
397
- * Mailbox Name or Glob: user00*@
398
- * Address or Glob: postmaster@domain*.com
399
- * Provider or Registration: msn
375
+ - Top-Level-Domain: .org
376
+ - Domain Name: example.com
377
+ - Registration Name: hotmail. (matches any TLD)
378
+ - Domain Glob: \*.exampl?.com
379
+ - Provider Name: google
380
+ - Mailbox Name or Glob: user00\*@
381
+ - Address or Glob: postmaster@domain\*.com
382
+ - Provider or Registration: msn
400
383
 
401
384
  Usage:
402
385
 
@@ -484,124 +467,8 @@ EmailAddress::Config.error_messages({
484
467
  not_allowed: "Address is not allowed",
485
468
  incomplete_domain: "Domain name is incomplete"}, 'en')
486
469
  ```
487
- Note: Release 0.1.14 fixed setting error messages by locale.
488
- Also, it will accept a ruby "collected" hash as before,
489
-
490
- Full translation support would be ideal though.
491
-
492
- ### Available Configuration Settings
493
-
494
- * sha1_secret -
495
- This application-level secret is appended to the email_address to compute
496
- the SHA1 Digest, making it unique to your application so it can't easily be
497
- discovered by comparing against a known list of email/sha1 pairs.
498
-
499
- * sha256_secret -
500
- This application-level secret is appended to the email_address to compute
501
- the SHA256 Digest, making it unique to your application so it can't easily be
502
- discovered by comparing against a known list of email/sha256 pairs.
503
470
 
504
- * munge_string - "*****", the string to replace into munged addresses.
505
-
506
- For local part configuration:
507
-
508
- * local_downcase: true.
509
- Downcase the local part. You probably want this for uniqueness.
510
- RFC says local part is case insensitive, that's a bad part.
511
-
512
- * local_fix: true.
513
- Make simple fixes when available, remove spaces, condense multiple punctuations
514
-
515
- * local_encoding: :ascii, :unicode,
516
- Enable Unicode in local part. Most mail systems do not yet support this.
517
- You probably want to stay with ASCII for now.
518
-
519
- * local_parse: nil, ->(local) { [mailbox, tag, comment] }
520
- Specify an optional lambda/Proc to parse the local part. It should return an
521
- array (tuple) of mailbox, tag, and comment.
522
-
523
- * local_format:
524
- * :conventional - word ( puncuation{1} word )*
525
- * :relaxed - alphanum ( allowed_characters)* alphanum
526
- * :standard - RFC Compliant email addresses (anything goes!)
527
-
528
- * local_size: 1..64,
529
- A Range specifying the allowed size for mailbox + tags + comment
530
-
531
- * tag_separator: nil, character (+)
532
- Nil, or a character used to split the tag from the mailbox
533
-
534
- For the mailbox (AKA account, role), without the tag
535
- * mailbox_size: 1..64
536
- A Range specifying the allowed size for mailbox
537
-
538
- * mailbox_canonical: nil, ->(mailbox) { mailbox }
539
- An optional lambda/Proc taking a mailbox name, returning a canonical
540
- version of it. (E.G.: gmail removes '.' characters)
541
-
542
- * mailbox_validator: nil, ->(mailbox) { true }
543
- An optional lambda/Proc taking a mailbox name, returning true or false.
544
-
545
- * host_encoding: :punycode, :unicode,
546
- How to treat International Domain Names (IDN). Note that most mail and
547
- DNS systems do not support unicode, so punycode needs to be passed.
548
- :punycode Convert Unicode names to punycode representation
549
- :unicode Keep Unicode names as is.
550
-
551
- * host_validation:
552
- :mx Ensure host is configured with DNS MX records
553
- :a Ensure host is known to DNS (A Record)
554
- :syntax Validate by syntax only, no Network verification
555
- :connect Attempt host connection (Experimental and Dangerous: Do not use)
556
- The :host_timeout setting is the maximum number
557
- of seconds to wait during the :connect validation
558
-
559
- * host_size: 1..253,
560
- A range specifying the size limit of the host part,
561
-
562
- * host_allow_ip: false,
563
- Allow IP address format in host: [127.0.0.1], [IPv6:::1]
564
-
565
- * address_validation: :parts, :smtp, ->(address) { true }
566
- Address validation policy
567
- :parts Validate local and host.
568
- :smtp Validate via SMTP (not implemented, BAD!)
569
- A lambda/Proc taking the address string, returning true or false
570
-
571
- * address_size: 3..254,
572
- A range specifying the size limit of the complete address
573
-
574
- For provider rules to match to domain names and Exchanger hosts
575
- The value is an array of match tokens.
576
- * host_match: %w(.org example.com hotmail. user*@ sub.*.com)
577
- * exchanger_match: %w(google.com 127.0.0.1 10.9.8.0/24 ::1/64)
578
-
579
- ### Namespace conflict resolution
580
-
581
- If your application already uses the `EmailAddress` class name,
582
- it's possible to create an alias prior to loading your code:
583
-
584
- For a Rails application, you can do this in `config/application.rb`
585
- after the `Bundler.require` line, usually:
586
-
587
- ```ruby
588
- Bundler.require(*Rails.groups)
589
- ```
590
-
591
- Add these lines immediately after that point:
592
-
593
- ```ruby
594
- EmailAddressValidator = EmailAddress
595
- Object.send(:remove_const, :EmailAddress)
596
- ```
597
-
598
- Then your application loads with your EmailAddress class. You may
599
- then use this gem with `EmailAddressValidator` or whatever name you
600
- gave it above:
601
-
602
- ```ruby
603
- EmailAddressValidator.valid?("clark.kent@gmail.com") # => true
604
- ```
471
+ Complete settings and methods are found in the config.rb file within.
605
472
 
606
473
  ## Notes
607
474
 
@@ -661,5 +528,5 @@ This project lives at [https://github.com/afair/email_address/](https://github.c
661
528
 
662
529
  #### Authors
663
530
 
664
- * [Allen Fair](https://github.com/afair) ([@allenfair](https://twitter.com/allenfair)):
531
+ - [Allen Fair](https://github.com/afair) ([@allenfair](https://twitter.com/allenfair)):
665
532
  I've worked with email-based applications and email addresses since 1999.
@@ -38,7 +38,7 @@ module EmailAddress
38
38
 
39
39
  # Given an email address, this returns an array of [local, host] parts
40
40
  def self.split_local_host(email)
41
- if (lh = email.match(/(.+)@(.+)/))
41
+ if (lh = email.match(/\A(.+)@(.+)\z/))
42
42
  lh.to_a[1, 2]
43
43
  else
44
44
  [email, ""]
@@ -112,7 +112,7 @@ module EmailAddress
112
112
 
113
113
  class Config
114
114
  @config = {
115
- dns_lookup: :mx, # :mx, :a, :off
115
+ dns_lookup: :a, # :mx, :a, :off
116
116
  dns_timeout: nil,
117
117
  sha1_secret: "",
118
118
  sha256_secret: "",
@@ -159,7 +159,7 @@ module EmailAddress
159
159
  msn: {
160
160
  host_match: %w[msn. hotmail. outlook. live.],
161
161
  exchanger_match: %w[outlook.com],
162
- mailbox_validator: ->(m, t) { m =~ /\A\w[\-\w]*(?:\.[\-\w]+)*\z/i }
162
+ mailbox_validator: ->(m, t) { m =~ /\A\w[-\w]*(?:\.[-\w]+)*\z/i }
163
163
  },
164
164
  yahoo: {
165
165
  host_match: %w[yahoo. ymail. rocketmail.],
@@ -101,10 +101,10 @@ module EmailAddress
101
101
 
102
102
  REDACTED_REGEX = /\A \{ [0-9a-f]{40} \} \z/x # {sha1}
103
103
 
104
- CONVENTIONAL_TAG_REGEX = # AZaz09_!'+-/=
105
- %r{^([\w!'+\-/=.]+)$}i
106
- RELAXED_TAG_REGEX = # AZaz09_!#$%&'*+-/=?^`{|}~
107
- %r/^([\w.!\#$%&'*+\-\/=?\^`{|}~]+)$/i
104
+ # Conventional Tag: word ([,-+'='] word)...
105
+ CONVENTIONAL_TAG_REGEX = /\A [\p{L}\p{N}_]+ (?: [.\-+'=] [\p{L}\p{N}_]+ )* \z/x # word(<punctuation>word)*...
106
+ # Relexed Tag: token ( . token)... token is most punctuation, but not: . \ " space
107
+ RELAXED_TAG_REGEX = %r/^[\w!\#$%&'*+\-\/=?\^`{|}~]+ (\.[\w!\#$%&'*+\-\/=?\^`{|}~])* $/ix
108
108
 
109
109
  def initialize(local, config = {}, host = nil, locale = "en")
110
110
  @config = config.is_a?(Hash) ? Config.new(config) : config
@@ -333,14 +333,11 @@ module EmailAddress
333
333
  # True if the part matches the conventional format
334
334
  def conventional?
335
335
  self.syntax = :invalid
336
- if tag
337
- return false unless mailbox =~ CONVENTIONAL_MAILBOX_REGEX &&
338
- tag =~ CONVENTIONAL_TAG_REGEX
339
- else
340
- return false unless CONVENTIONAL_MAILBOX_REGEX.match?(local)
341
- end
342
- valid_size? or return false
343
- valid_encoding? or return false
336
+ return false if tag && tag !~ CONVENTIONAL_TAG_REGEX
337
+ return false unless mailbox =~ CONVENTIONAL_MAILBOX_REGEX
338
+ return false if comment
339
+ return false unless valid_size?
340
+ return false unless valid_encoding?
344
341
  self.syntax = :conventional
345
342
  true
346
343
  end
@@ -348,32 +345,23 @@ module EmailAddress
348
345
  # Relaxed conventional is not so strict about character order.
349
346
  def relaxed?
350
347
  self.syntax = :invalid
351
- valid_size? or return false
352
- valid_encoding? or return false
353
- if tag
354
- return false unless RELAXED_MAILBOX_REGEX.match?(mailbox) &&
355
- RELAXED_TAG_REGEX.match?(tag)
356
- self.syntax = :relaxed
357
- true
358
- elsif RELAXED_MAILBOX_REGEX.match?(local)
359
- self.syntax = :relaxed
360
- true
361
- else
362
- false
363
- end
348
+ return false if tag && tag !~ RELAXED_TAG_REGEX
349
+ return false unless mailbox =~ RELAXED_MAILBOX_REGEX
350
+ return false if comment
351
+ return false unless valid_size?
352
+ return false unless valid_encoding?
353
+ self.syntax = :relaxed
354
+ true
364
355
  end
365
356
 
366
357
  # True if the part matches the RFC standard format
367
358
  def standard?
368
359
  self.syntax = :invalid
369
- valid_size? or return false
370
- valid_encoding? or return false
371
- if STANDARD_LOCAL_REGEX.match?(local)
372
- self.syntax = :standard
373
- true
374
- else
375
- false
376
- end
360
+ return false unless STANDARD_LOCAL_REGEX.match?(local)
361
+ return false unless valid_size?
362
+ return false unless valid_encoding?
363
+ self.syntax = :standard
364
+ true
377
365
  end
378
366
 
379
367
  # Matches configured formated form against File glob strings given.
@@ -1,3 +1,3 @@
1
1
  module EmailAddress
2
- VERSION = "0.2.6"
2
+ VERSION = "0.2.7"
3
3
  end
@@ -102,9 +102,9 @@ class TestAddress < Minitest::Test
102
102
  assert_equal "", e.hostname
103
103
  assert_equal false, e.valid? # localhost not allowed by default
104
104
  assert_equal EmailAddress.error("user1"), "Invalid Domain Name"
105
- assert_equal EmailAddress.error("user1", host_local: true), "This domain is not configured to accept email"
105
+ #assert_equal EmailAddress.error("user1", host_local: true), "This domain is not configured to accept email"
106
106
  assert_equal EmailAddress.error("user1", host_local: true, host_auto_append: false), "Invalid Domain Name"
107
- assert_equal EmailAddress.error("user1@localhost", host_local: true), "This domain is not configured to accept email"
107
+ #assert_equal EmailAddress.error("user1@localhost", host_local: true), "This domain is not configured to accept email"
108
108
  assert_equal EmailAddress.error("user1@localhost", host_local: false, host_validation: :syntax), "localhost is not allowed for your domain name"
109
109
  assert_equal EmailAddress.error("user1@localhost", host_local: false, dns_lookup: :off), "localhost is not allowed for your domain name"
110
110
  assert_nil EmailAddress.error("user2@localhost", host_local: true, dns_lookup: :off, host_validation: :syntax)
@@ -149,6 +149,13 @@ class TestAddress < Minitest::Test
149
149
  end
150
150
 
151
151
  def test_nonstandard_tag
152
- assert EmailAddress.valid?("asdfas+-@icloud.com")
152
+ # assert EmailAddress.valid?("asdfas+-@icloud.com")
153
+ end
154
+
155
+ def test_newline_characters
156
+ assert !EmailAddress.valid?("user@foo.com\nother@bar.com")
157
+ assert !EmailAddress.valid?("user@foo.com\r\nother@bar.com")
158
+ assert EmailAddress.valid?("\nuser@foo.com") # valid because strip processing removes \n
159
+ assert EmailAddress.valid?("user@foo.com\r\n") # valid because strip processing removes \n
153
160
  end
154
161
  end
@@ -2,19 +2,19 @@ require_relative "../test_helper"
2
2
 
3
3
  class TestConfig < MiniTest::Test
4
4
  def test_setting
5
- assert_equal :mx, EmailAddress::Config.setting(:dns_lookup)
5
+ assert_equal :a, EmailAddress::Config.setting(:dns_lookup)
6
6
  assert_equal :off, EmailAddress::Config.setting(:dns_lookup, :off)
7
7
  assert_equal :off, EmailAddress::Config.setting(:dns_lookup)
8
- EmailAddress::Config.setting(:dns_lookup, :mx)
8
+ EmailAddress::Config.setting(:dns_lookup, :a)
9
9
  end
10
10
 
11
11
  def test_configure
12
- assert_equal :mx, EmailAddress::Config.setting(:dns_lookup)
12
+ assert_equal :a, EmailAddress::Config.setting(:dns_lookup)
13
13
  assert_equal true, EmailAddress::Config.setting(:local_downcase)
14
14
  EmailAddress::Config.configure(local_downcase: false, dns_lookup: :off)
15
15
  assert_equal :off, EmailAddress::Config.setting(:dns_lookup)
16
16
  assert_equal false, EmailAddress::Config.setting(:local_downcase)
17
- EmailAddress::Config.configure(local_downcase: true, dns_lookup: :mx)
17
+ EmailAddress::Config.configure(local_downcase: true, dns_lookup: :a)
18
18
  end
19
19
 
20
20
  def test_provider
@@ -142,7 +142,7 @@ class TestHost < MiniTest::Test
142
142
 
143
143
  def test_errors
144
144
  assert_nil EmailAddress::Host.new("yahoo.com").error
145
- assert_equal EmailAddress::Host.new("example.com").error, "This domain is not configured to accept email"
145
+ #assert_equal EmailAddress::Host.new("example.com").error, "This domain is not configured to accept email"
146
146
  assert_equal EmailAddress::Host.new("yahoo.wtf").error, "Domain name not registered"
147
147
  assert_nil EmailAddress::Host.new("ajsdfhajshdfklasjhd.wtf", host_validation: :syntax).error
148
148
  assert_equal EmailAddress::Host.new("ya hoo.com", host_validation: :syntax).error, "Invalid Domain Name"
@@ -156,11 +156,11 @@ class TestHost < MiniTest::Test
156
156
  end
157
157
 
158
158
  # When a domain is not configured to receive email (missing MX record),
159
- # Though some MTA's will fallback to the A/AAAA host record
160
- def test_no_mx
161
- assert !EmailAddress::Host.new("zaboz.com").valid?
162
- assert EmailAddress::Host.new("zaboz.com", dns_lookup: :a).valid?
163
- end
159
+ # Though some MTA's will fallback to the A/AAAA host record, so this isn't a good test
160
+ #def test_no_mx
161
+ # assert !EmailAddress::Host.new("zaboz.com").valid?
162
+ # assert EmailAddress::Host.new("zaboz.com", dns_lookup: :a).valid?
163
+ #end
164
164
 
165
165
  # Issue #102 off---white.com should be valid
166
166
  def test_triple_dash_domain
@@ -63,13 +63,13 @@ class TestLocal < MiniTest::Test
63
63
  end
64
64
 
65
65
  def test_valid
66
- assert_equal false, EmailAddress::Local.new("first(comment)", local_format: :conventional).valid?
67
- assert_equal true, EmailAddress::Local.new("first(comment)", local_format: :standard).valid?
66
+ refute EmailAddress::Local.new("first(comment)", local_format: :conventional).valid?
67
+ assert EmailAddress::Local.new("first(comment)", local_format: :standard).valid?
68
68
  end
69
69
 
70
70
  def test_format
71
71
  assert_equal :conventional, EmailAddress::Local.new("can1").format?
72
- assert_equal :standard, EmailAddress::Local.new(%("can1")).format?
72
+ assert_equal :standard, EmailAddress::Local.new(%("can 1")).format?
73
73
  assert_equal "can1", EmailAddress::Local.new(%{"can1(commment)"}).format(:conventional)
74
74
  end
75
75
 
@@ -109,4 +109,9 @@ class TestLocal < MiniTest::Test
109
109
  def test_relaxed_tag
110
110
  assert EmailAddress.valid? "foo+abc@example.com", host_validation: :syntax, local_format: :relaxed
111
111
  end
112
+
113
+ def test_tag_punctuation
114
+ refute EmailAddress.valid?("name+tag.@domain.com", host_validation: :syntax)
115
+ assert EmailAddress.valid?("name+tag.-@domain.com", host_validation: :syntax, local_format: :relaxed)
116
+ end
112
117
  end
data/test/test_helper.rb CHANGED
@@ -1,3 +1,9 @@
1
+ ################################################################################
2
+ # EmailAddress Testing
3
+ # - ๐Ÿ”ฅ rake
4
+ # - ๐Ÿ”๏ธ ruby test/email_address/test_local.rb --name test_tag_punctuation
5
+ # - ๐Ÿงช rake console
6
+ ################################################################################
1
7
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), "..", "lib"))
2
8
 
3
9
  require "pry"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: email_address
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.2.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Allen Fair