validates_email_format_of 1.7.2 → 1.8.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/dependabot.yml +6 -0
- data/.github/workflows/ci.yml +45 -7
- data/Appraisals +4 -0
- data/CHANGELOG.md +26 -2
- data/README.md +120 -0
- data/config/locales/de.yml +1 -1
- data/config/locales/en.yml +1 -1
- data/config/locales/id.yml +8 -0
- data/config/locales/it.yml +1 -1
- data/config/locales/pl.yml +1 -1
- data/config/locales/pt-BR.yml +1 -1
- data/config/locales/pt.yml +1 -1
- data/config/locales/tr.yml +8 -0
- data/gemfiles/rails_7.1.gemfile +7 -0
- data/lib/validates_email_format_of/active_model.rb +1 -1
- data/lib/validates_email_format_of/version.rb +1 -1
- data/lib/validates_email_format_of.rb +67 -21
- data/spec/spec_helper.rb +5 -5
- data/spec/validates_email_format_of_spec.rb +78 -9
- data/validates_email_format_of.gemspec +3 -3
- metadata +19 -15
- data/README.rdoc +0 -100
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 11c21b2a28ee1659e6727cc106aaf912487adf9b519eceeebd68f3dbb1750b88
|
|
4
|
+
data.tar.gz: 8db0acd0c16c49e5042640bf159aa75caad8f75b899a5df91527d66c899012aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c3fcec1122983e8bbcff3e8a388260d040851467dbb89d6a1157e38ab59fbe908c3b8c69793ac2166ee1cedaf1d78d0c6613fc4ac8c450fb523c45fda1821b59
|
|
7
|
+
data.tar.gz: dbc08e3633edf9d254e80d6614795a36f4c806046aa6dafb1c0aa46e9aa729f19701fbf533be9253138d119b35c8203fdea1a64a87c6c364e0e53ded94e23a7c
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
1
|
name: CI
|
|
2
2
|
|
|
3
3
|
on:
|
|
4
|
-
|
|
5
|
-
branches: [master]
|
|
6
|
-
pull_request:
|
|
7
|
-
branches: [master]
|
|
4
|
+
- pull_request
|
|
8
5
|
|
|
9
6
|
permissions:
|
|
10
7
|
contents: read
|
|
@@ -17,38 +14,78 @@ jobs:
|
|
|
17
14
|
|
|
18
15
|
strategy:
|
|
19
16
|
matrix:
|
|
20
|
-
ruby: ["2.6", "2.7", "3.0", "3.1"]
|
|
21
|
-
gemfile: ["4.2", "5.0", "5.1", "5.2", "6.0", "6.1", "7.0"]
|
|
17
|
+
ruby: ["2.6", "2.7", "3.0", "3.1", "3.2", "3.3", "jruby-head"]
|
|
18
|
+
gemfile: ["4.2", "5.0", "5.1", "5.2", "6.0", "6.1", "7.0", "7.1"]
|
|
19
|
+
|
|
22
20
|
exclude:
|
|
23
21
|
- gemfile: "4.2"
|
|
24
22
|
ruby: "3.0"
|
|
25
23
|
- gemfile: "4.2"
|
|
26
24
|
ruby: "3.1"
|
|
25
|
+
- gemfile: "4.2"
|
|
26
|
+
ruby: "3.2"
|
|
27
|
+
- gemfile: "4.2"
|
|
28
|
+
ruby: "3.3"
|
|
29
|
+
- gemfile: "4.2"
|
|
30
|
+
ruby: "jruby-head"
|
|
27
31
|
- gemfile: "5.0"
|
|
28
32
|
ruby: "3.0"
|
|
29
33
|
- gemfile: "5.0"
|
|
30
34
|
ruby: "3.1"
|
|
35
|
+
- gemfile: "5.0"
|
|
36
|
+
ruby: "3.2"
|
|
37
|
+
- gemfile: "5.0"
|
|
38
|
+
ruby: "3.3"
|
|
39
|
+
- gemfile: "5.0"
|
|
40
|
+
ruby: "jruby-head"
|
|
31
41
|
- gemfile: "5.1"
|
|
32
42
|
ruby: "3.0"
|
|
33
43
|
- gemfile: "5.1"
|
|
34
44
|
ruby: "3.1"
|
|
45
|
+
- gemfile: "5.1"
|
|
46
|
+
ruby: "3.2"
|
|
47
|
+
- gemfile: "5.1"
|
|
48
|
+
ruby: "3.3"
|
|
49
|
+
- gemfile: "5.1"
|
|
50
|
+
ruby: "jruby-head"
|
|
35
51
|
- gemfile: "5.2"
|
|
36
52
|
ruby: "3.0"
|
|
37
53
|
- gemfile: "5.2"
|
|
38
54
|
ruby: "3.1"
|
|
55
|
+
- gemfile: "5.2"
|
|
56
|
+
ruby: "3.2"
|
|
57
|
+
- gemfile: "5.2"
|
|
58
|
+
ruby: "3.3"
|
|
59
|
+
- gemfile: "5.2"
|
|
60
|
+
ruby: "jruby-head"
|
|
61
|
+
- gemfile: "6.0"
|
|
62
|
+
ruby: "3.2"
|
|
63
|
+
- gemfile: "6.0"
|
|
64
|
+
ruby: "3.3"
|
|
65
|
+
- gemfile: "6.1"
|
|
66
|
+
ruby: "3.2"
|
|
67
|
+
- gemfile: "6.1"
|
|
68
|
+
ruby: "3.3"
|
|
39
69
|
- gemfile: "7.0"
|
|
40
70
|
ruby: "2.5"
|
|
41
71
|
- gemfile: "7.0"
|
|
42
72
|
ruby: "2.6"
|
|
43
73
|
- gemfile: "7.0"
|
|
44
74
|
ruby: "2.7"
|
|
75
|
+
- gemfile: "7.1"
|
|
76
|
+
ruby: "2.5"
|
|
77
|
+
- gemfile: "7.1"
|
|
78
|
+
ruby: "2.6"
|
|
79
|
+
- gemfile: "7.1"
|
|
80
|
+
ruby: "2.7"
|
|
81
|
+
|
|
45
82
|
|
|
46
83
|
env:
|
|
47
84
|
BUNDLE_GEMFILE: gemfiles/rails_${{ matrix.gemfile }}.gemfile
|
|
48
85
|
RAILS_ENV: test
|
|
49
86
|
|
|
50
87
|
steps:
|
|
51
|
-
- uses: actions/checkout@
|
|
88
|
+
- uses: actions/checkout@v4
|
|
52
89
|
|
|
53
90
|
- name: "Install Ruby ${{ matrix.ruby }}"
|
|
54
91
|
# To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
|
|
@@ -65,3 +102,4 @@ jobs:
|
|
|
65
102
|
|
|
66
103
|
- name: Run standard.rb
|
|
67
104
|
run: bundle exec rake standard
|
|
105
|
+
if: ${{ ! startsWith(matrix.ruby, '2.') }}
|
data/Appraisals
CHANGED
data/CHANGELOG.md
CHANGED
|
@@ -2,13 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
[Unreleased]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.
|
|
5
|
+
[Unreleased]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.8.2...master
|
|
6
|
+
|
|
7
|
+
## [1.8.2]
|
|
8
|
+
|
|
9
|
+
* Improve German translations - https://github.com/validates-email-format-of/validates_email_format_of/pull/111
|
|
10
|
+
|
|
11
|
+
[1.8.2]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.8.1...1.8.2
|
|
12
|
+
|
|
13
|
+
## [1.8.1]
|
|
14
|
+
|
|
15
|
+
* Fix IDN->Punycode conversion when domain names start with periods - https://github.com/validates-email-format-of/validates_email_format_of/issues/109
|
|
16
|
+
* Add jruby to test matrix - https://github.com/validates-email-format-of/validates_email_format_of/pull/108
|
|
17
|
+
|
|
18
|
+
[1.8.1]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.8.0...1.8.1
|
|
19
|
+
|
|
20
|
+
## [1.8.0]
|
|
21
|
+
|
|
22
|
+
* Add Internationalized Domain Name support - https://github.com/validates-email-format-of/validates_email_format_of/pull/103 - thanks https://github.com/sbilharz !
|
|
23
|
+
* Add Turkish locale - https://github.com/validates-email-format-of/validates_email_format_of/pull/101 - thanks https://github.com/@krmbzds !
|
|
24
|
+
* Added Indonesian locale - https://github.com/validates-email-format-of/validates_email_format_of/commit/129ebfc3a3b432b4df0334bcbdd74b1d17d765e0 - thanks https://github.com/khoerodin !
|
|
25
|
+
* Fix inconsistent `generate_messages` behaviour - https://github.com/validates-email-format-of/validates_email_format_of/pull/105
|
|
26
|
+
* ⚠️ Deprecate `:with` option - https://github.com/validates-email-format-of/validates_email_format_of/issues/42
|
|
27
|
+
* Require i18n >= 0.8.0 in modern Ruby versions - https://github.com/advisories/GHSA-34hf-g744-jw64
|
|
28
|
+
|
|
29
|
+
[1.8.0]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.7.2...1.8.0
|
|
6
30
|
|
|
7
31
|
## [1.7.2]
|
|
8
32
|
|
|
9
33
|
* Fix regression that disallowed domains starting with number - https://github.com/validates-email-format-of/validates_email_format_of/issues/88
|
|
10
34
|
|
|
11
|
-
[
|
|
35
|
+
[1.7.2]: https://github.com/validates-email-format-of/validates_email_format_of/compare/v1.7.1...v1.7.2
|
|
12
36
|
|
|
13
37
|
## [1.7.1] (3 Aug 2022)
|
|
14
38
|
|
data/README.md
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# validates_email_format_of
|
|
2
|
+
|
|
3
|
+
[]( https://github.com/validates-email-format-of/validates_email_format_of/actions/workflows/ci.yml?query=branch%3Amaster)
|
|
4
|
+
|
|
5
|
+
A Ruby gem to validate email addresses against RFC 2822 and RFC 5322, with optional domain name lookups.
|
|
6
|
+
|
|
7
|
+
## Why this email validator?
|
|
8
|
+
|
|
9
|
+
This gem is the O.G. email validation gem for Rails. It was started back in 2006.
|
|
10
|
+
|
|
11
|
+
Why use this validator? Instead of trying to validate email addresses with one giant regular expression, this library parses addresses character by character. This lets us handle weird cases like [nested comments](https://www.rfc-editor.org/rfc/rfc5322#appendix-A.5). Gross, but technically allowed.
|
|
12
|
+
|
|
13
|
+
In reality, most email validating scripts will get you where you need to go. This library just aims to go all the way.
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Add the gem to your Gemfile with:
|
|
18
|
+
|
|
19
|
+
```sh
|
|
20
|
+
gem 'validates_email_format_of'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Usage in a Rails app
|
|
24
|
+
|
|
25
|
+
```ruby
|
|
26
|
+
class Person < ActiveRecord::Base
|
|
27
|
+
validates :email, :email_format => { :message => "is not looking good" }
|
|
28
|
+
|
|
29
|
+
# OR
|
|
30
|
+
|
|
31
|
+
validates_email_format_of :email, :message => "is not looking good"
|
|
32
|
+
end
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
You can use the included `rspec` matcher as well:
|
|
36
|
+
|
|
37
|
+
```ruby
|
|
38
|
+
require "validates_email_format_of/rspec_matcher"
|
|
39
|
+
|
|
40
|
+
describe Person do
|
|
41
|
+
it { should validate_email_format_of(:email).with_message("is not looking good") }
|
|
42
|
+
end
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Usage without Rails
|
|
46
|
+
|
|
47
|
+
```ruby
|
|
48
|
+
ValidatesEmailFormatOf::validate_email_format("example@mydomain.com") # => nil
|
|
49
|
+
ValidatesEmailFormatOf::validate_email_format("invalid@") # => ["does not appear to be a valid email address"]
|
|
50
|
+
|
|
51
|
+
# Optional, if you want error messages to be in your language
|
|
52
|
+
ValidatesEmailFormatOf::load_i18n_locales
|
|
53
|
+
I18n.locale = :pl
|
|
54
|
+
|
|
55
|
+
ValidatesEmailFormatOf::validate_email_format("invalid@") # => ["nieprawidłowy adres email"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Internationalized Domain Names (IDN) and Punycode
|
|
59
|
+
|
|
60
|
+
As of v1.8.0, this gem can validate email addresses using internationalized domain names (like `test@пример.рф`) as well as domains that have already been converted to Punycode code (like `test@xn--test@-3weu6azakd.xn--p1ai`).
|
|
61
|
+
|
|
62
|
+
If you would like to forbid internationalized domains, you can pass the `idn: false` option. Punycode is always accepted.
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
## Options
|
|
66
|
+
|
|
67
|
+
| Option | Type | Description |
|
|
68
|
+
| --- | --- | --- |
|
|
69
|
+
| `:message` | String | A custom error message when the email format is invalid (default is: "does not appear to be a valid email address") |
|
|
70
|
+
| `:check_mx` | Boolean | Check domain for a valid MX record (default is false) |
|
|
71
|
+
| `:check_mx_timeout` | Integer | Timeout in seconds for checking MX records before a `ResolvTimeout` is raised (default is 3). |
|
|
72
|
+
| `:idn` | Boolean | Allowed internationalized domain names like `test@exämple.com` and `test@пример.рф`. Otherwise only domains that have already been converted to [Punycode](https://en.wikipedia.org/wiki/Punycode) are supported. (default is true) |
|
|
73
|
+
| `:mx_message` | String | A custom error message when the domain does not match a valid MX record (default is: "is not routable"). Ignored unless :check_mx option is true. |
|
|
74
|
+
| `:local_length` |Integer | Maximum number of characters allowed in the local part (everything before the '@') (default is 64) |
|
|
75
|
+
| `:domain_length` | Integer | Maximum number of characters allowed in the domain part (everything after the '@') (default is 255) |
|
|
76
|
+
| `:generate_message` | Boolean | Return the I18n key of the error message instead of the error message itself (default is false) |
|
|
77
|
+
|
|
78
|
+
The standard ActiveModel validation options (`:on`, `:if`, `:unless`, `:allow_nil`, `:allow_blank`, etc...) all work as well when using the gem as part of a Rails application.
|
|
79
|
+
## Testing
|
|
80
|
+
|
|
81
|
+
The gem is tested against Rails 4.2 and onward across a bunch of Ruby versions including jruby. You can see our [current Ruby and Rails test matrix here](.github/workflows/ci.yml).
|
|
82
|
+
|
|
83
|
+
To execute the unit tests against [all the Rails versions we support run](gemfiles/) <tt>bundle exec appraisal rspec</tt> or run against an individual version with <tt>bundle exec appraisal rails-6.0 rspec</tt>.
|
|
84
|
+
## Contributing
|
|
85
|
+
|
|
86
|
+
If you think we're letting some rules about valid email formats slip through the cracks, don't just update the parser. Instead, add a failing test and demonstrate that the described email address should be treated differently. A link to an appropriate RFC is the best way to do this. Then change the gem code to make the test pass.
|
|
87
|
+
|
|
88
|
+
```ruby
|
|
89
|
+
describe "i_think_this_is_not_a_v@lid_email_addre.ss" do
|
|
90
|
+
# According to http://..., this email address IS NOT valid.
|
|
91
|
+
it { should have_errors_on_email.because("does not appear to be valid") }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
describe "i_think_this_is_a_v@lid_email_addre.ss" do
|
|
95
|
+
# According to http://..., this email address IS valid.
|
|
96
|
+
it { should_not have_errors_on_email }
|
|
97
|
+
end
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Yes, our Rspec syntax is that simple!
|
|
101
|
+
|
|
102
|
+
## Homepage
|
|
103
|
+
|
|
104
|
+
* https://github.com/validates-email-format-of/validates_email_format_of
|
|
105
|
+
|
|
106
|
+
## Credits
|
|
107
|
+
|
|
108
|
+
Written by [Alex Dunae](https://dunae.ca), 2006-24.
|
|
109
|
+
|
|
110
|
+
Many thanks to the plugin's recent contributors: https://github.com/alexdunae/validates_email_format_of/contributors
|
|
111
|
+
|
|
112
|
+
Thanks to [Francis Hwang](http://fhwang.net/) at Diversion Media for creating the 1.1 update.
|
|
113
|
+
|
|
114
|
+
Thanks to Travis Sinnott for creating the 1.3 update.
|
|
115
|
+
|
|
116
|
+
Thanks to Denis Ahearn at [Riverock Technologies](http://www.riverocktech.com/) for creating the 1.4 update.
|
|
117
|
+
|
|
118
|
+
Thanks to [George Anderson](http://github.com/george) and ['history'](http://github.com/history) for creating the 1.4.1 update.
|
|
119
|
+
|
|
120
|
+
Thanks to [Isaac Betesh](https://github.com/betesh) for converting tests to Rspec and refactoring for version 1.6.0.
|
data/config/locales/de.yml
CHANGED
|
@@ -2,7 +2,7 @@ de:
|
|
|
2
2
|
activemodel: &errors
|
|
3
3
|
errors:
|
|
4
4
|
messages:
|
|
5
|
-
invalid_email_address: 'ist
|
|
5
|
+
invalid_email_address: 'ist anscheinend keine gültige E-Mail-Adresse'
|
|
6
6
|
email_address_not_routable: 'kann nicht erreicht werden'
|
|
7
7
|
activerecord:
|
|
8
8
|
<<: *errors
|
data/config/locales/en.yml
CHANGED
|
@@ -2,7 +2,7 @@ en:
|
|
|
2
2
|
activemodel: &errors
|
|
3
3
|
errors:
|
|
4
4
|
messages:
|
|
5
|
-
invalid_email_address: 'does not appear to be a valid
|
|
5
|
+
invalid_email_address: 'does not appear to be a valid email address'
|
|
6
6
|
email_address_not_routable: 'is not routable'
|
|
7
7
|
activerecord:
|
|
8
8
|
<<: *errors
|
data/config/locales/it.yml
CHANGED
data/config/locales/pl.yml
CHANGED
data/config/locales/pt-BR.yml
CHANGED
|
@@ -2,7 +2,7 @@ pt-BR:
|
|
|
2
2
|
activemodel: &errors
|
|
3
3
|
errors:
|
|
4
4
|
messages:
|
|
5
|
-
invalid_email_address: 'não parece ser um endereço de
|
|
5
|
+
invalid_email_address: 'não parece ser um endereço de email válido'
|
|
6
6
|
email_address_not_routable: 'não é acessível'
|
|
7
7
|
activerecord:
|
|
8
8
|
<<: *errors
|
data/config/locales/pt.yml
CHANGED
|
@@ -9,7 +9,7 @@ module ActiveModel
|
|
|
9
9
|
module Validations
|
|
10
10
|
class EmailFormatValidator < EachValidator
|
|
11
11
|
def validate_each(record, attribute, value)
|
|
12
|
-
(ValidatesEmailFormatOf.validate_email_format(value, options
|
|
12
|
+
(ValidatesEmailFormatOf.validate_email_format(value, options) || []).each do |error|
|
|
13
13
|
record.errors.add(attribute, error)
|
|
14
14
|
end
|
|
15
15
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require "validates_email_format_of/version"
|
|
2
|
+
require "simpleidn"
|
|
2
3
|
|
|
3
4
|
module ValidatesEmailFormatOf
|
|
4
5
|
def self.load_i18n_locales
|
|
@@ -77,7 +78,7 @@ module ValidatesEmailFormatOf
|
|
|
77
78
|
# > restriction on the first character is relaxed to allow either a
|
|
78
79
|
# > letter or a digit. Host software MUST support this more liberal
|
|
79
80
|
# > syntax.
|
|
80
|
-
DOMAIN_PART_LABEL = /\A[A-Za-z0-9][A-Za-z0-9
|
|
81
|
+
DOMAIN_PART_LABEL = /\A[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9]?\Z/
|
|
81
82
|
|
|
82
83
|
# From https://tools.ietf.org/id/draft-liman-tld-names-00.html#rfc.section.2
|
|
83
84
|
#
|
|
@@ -92,10 +93,12 @@ module ValidatesEmailFormatOf
|
|
|
92
93
|
# ld = ALPHA / DIGIT
|
|
93
94
|
# ALPHA = %x41-5A / %x61-7A ; A-Z / a-z
|
|
94
95
|
# DIGIT = %x30-39 ; 0-9
|
|
95
|
-
DOMAIN_PART_TLD = /\A[A-Za-z][A-Za-z0-9
|
|
96
|
+
DOMAIN_PART_TLD = /\A[A-Za-z][A-Za-z0-9-]*[A-Za-z0-9]\Z/
|
|
96
97
|
|
|
97
|
-
def self.validate_email_domain(email, check_mx_timeout: 3)
|
|
98
|
+
def self.validate_email_domain(email, idn: true, check_mx_timeout: 3)
|
|
98
99
|
domain = email.to_s.downcase.match(/@(.+)/)[1]
|
|
100
|
+
domain = SimpleIDN.to_ascii(domain) if idn
|
|
101
|
+
|
|
99
102
|
Resolv::DNS.open do |dns|
|
|
100
103
|
dns.timeouts = check_mx_timeout
|
|
101
104
|
@mx = dns.getresources(domain, Resolv::DNS::Resource::IN::MX) + dns.getresources(domain, Resolv::DNS::Resource::IN::A)
|
|
@@ -119,8 +122,8 @@ module ValidatesEmailFormatOf
|
|
|
119
122
|
# * <tt>message</tt> - A custom error message (default is: "does not appear to be valid")
|
|
120
123
|
# * <tt>check_mx</tt> - Check for MX records (default is false)
|
|
121
124
|
# * <tt>check_mx_timeout</tt> - Timeout in seconds for checking MX records before a `ResolvTimeout` is raised (default is 3)
|
|
125
|
+
# * <tt>idn</tt> - Enable or disable Internationalized Domain Names (default is true)
|
|
122
126
|
# * <tt>mx_message</tt> - A custom error message when an MX record validation fails (default is: "is not routable.")
|
|
123
|
-
# * <tt>with</tt> The regex to use for validating the format of the email address (deprecated)
|
|
124
127
|
# * <tt>local_length</tt> Maximum number of characters allowed in the local part (default is 64)
|
|
125
128
|
# * <tt>domain_length</tt> Maximum number of characters allowed in the domain part (default is 255)
|
|
126
129
|
# * <tt>generate_message</tt> Return the I18n key of the error message instead of the error message itself (default is false)
|
|
@@ -128,6 +131,7 @@ module ValidatesEmailFormatOf
|
|
|
128
131
|
default_options = {message: options[:generate_message] ? ERROR_MESSAGE_I18N_KEY : default_message,
|
|
129
132
|
check_mx: false,
|
|
130
133
|
check_mx_timeout: 3,
|
|
134
|
+
idn: true,
|
|
131
135
|
mx_message: if options[:generate_message]
|
|
132
136
|
ERROR_MX_MESSAGE_I18N_KEY
|
|
133
137
|
else
|
|
@@ -154,12 +158,13 @@ module ValidatesEmailFormatOf
|
|
|
154
158
|
domain.reverse!
|
|
155
159
|
|
|
156
160
|
if opts.has_key?(:with) # holdover from versions <= 1.4.7
|
|
161
|
+
deprecation_warn(":with option is deprecated and will be removed in the next version")
|
|
157
162
|
return [opts[:message]] unless email&.match?(opts[:with])
|
|
158
163
|
else
|
|
159
|
-
return [opts[:message]] unless validate_local_part_syntax(local) && validate_domain_part_syntax(domain)
|
|
164
|
+
return [opts[:message]] unless validate_local_part_syntax(local) && validate_domain_part_syntax(domain, idn: opts[:idn])
|
|
160
165
|
end
|
|
161
166
|
|
|
162
|
-
if opts[:check_mx] && !validate_email_domain(email, check_mx_timeout: opts[:check_mx_timeout])
|
|
167
|
+
if opts[:check_mx] && !validate_email_domain(email, check_mx_timeout: opts[:check_mx_timeout], idn: opts[:idn])
|
|
163
168
|
return [opts[:mx_message]]
|
|
164
169
|
end
|
|
165
170
|
|
|
@@ -171,6 +176,19 @@ module ValidatesEmailFormatOf
|
|
|
171
176
|
in_quoted_string = false
|
|
172
177
|
comment_depth = 0
|
|
173
178
|
|
|
179
|
+
# The local part is made up of dot-atom and quoted-string joined together by "." characters
|
|
180
|
+
#
|
|
181
|
+
# https://www.rfc-editor.org/rfc/rfc5322#section-3.4.1
|
|
182
|
+
# > local-part = dot-atom / quoted-string / obs-local-part
|
|
183
|
+
#
|
|
184
|
+
# https://www.rfc-editor.org/rfc/rfc5322#section-3.2.3
|
|
185
|
+
# Both atom and dot-atom are interpreted as a single unit, comprising
|
|
186
|
+
# > the string of characters that make it up. Semantically, the optional
|
|
187
|
+
# > comments and FWS surrounding the rest of the characters are not part
|
|
188
|
+
# > of the atom; the atom is only the run of atext characters in an atom,
|
|
189
|
+
# > or the atext and "." characters in a dot-atom.
|
|
190
|
+
joining_atoms = true
|
|
191
|
+
|
|
174
192
|
(0..local.length - 1).each do |i|
|
|
175
193
|
ord = local[i].ord
|
|
176
194
|
|
|
@@ -180,6 +198,32 @@ module ValidatesEmailFormatOf
|
|
|
180
198
|
next
|
|
181
199
|
end
|
|
182
200
|
|
|
201
|
+
# double quote delimits quoted strings
|
|
202
|
+
if ord == 34
|
|
203
|
+
if in_quoted_string # leaving the quoted string
|
|
204
|
+
in_quoted_string = false
|
|
205
|
+
next
|
|
206
|
+
elsif joining_atoms # are we allowed to enter a quoted string?
|
|
207
|
+
in_quoted_string = true
|
|
208
|
+
joining_atoms = false
|
|
209
|
+
next
|
|
210
|
+
else
|
|
211
|
+
return false
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
# period indicates we want to join atoms, e.g. `aaa.bbb."ccc"@example.com
|
|
216
|
+
if ord == 46
|
|
217
|
+
return false if i.zero?
|
|
218
|
+
return false if joining_atoms
|
|
219
|
+
joining_atoms = true
|
|
220
|
+
next
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
joining_atoms = false
|
|
224
|
+
|
|
225
|
+
# quoted string logic must come before comment processing since a quoted string
|
|
226
|
+
# may contain parens, e.g. `"name(a)"@example.com`
|
|
183
227
|
if in_quoted_string
|
|
184
228
|
next if QTEXT.match?(local[i])
|
|
185
229
|
end
|
|
@@ -198,41 +242,35 @@ module ValidatesEmailFormatOf
|
|
|
198
242
|
end
|
|
199
243
|
|
|
200
244
|
# backslash signifies the start of a quoted pair
|
|
201
|
-
if ord == 92
|
|
202
|
-
|
|
245
|
+
if ord == 92
|
|
246
|
+
# https://www.rfc-editor.org/rfc/rfc5322#section-3.2.1
|
|
247
|
+
# > The only places in this specification where quoted-pair currently appears are
|
|
248
|
+
# > ccontent, qcontent, and in obs-dtext in section 4.
|
|
249
|
+
return false unless in_quoted_string || comment_depth > 0
|
|
203
250
|
in_quoted_pair = true
|
|
204
251
|
next
|
|
205
252
|
end
|
|
206
253
|
|
|
207
|
-
# double quote delimits quoted strings
|
|
208
|
-
if ord == 34
|
|
209
|
-
in_quoted_string = !in_quoted_string
|
|
210
|
-
next
|
|
211
|
-
end
|
|
212
|
-
|
|
213
254
|
if comment_depth > 0
|
|
214
255
|
next if CTEXT.match?(local[i])
|
|
215
256
|
elsif ATEXT.match?(local[i, 1])
|
|
216
257
|
next
|
|
217
258
|
end
|
|
218
259
|
|
|
219
|
-
# period must be followed by something
|
|
220
|
-
if ord == 46
|
|
221
|
-
return false if i == 0 || i == local.length - 1 # can't be first or last char
|
|
222
|
-
next unless local[i + 1].ord == 46 # can't be followed by a period
|
|
223
|
-
end
|
|
224
|
-
|
|
225
260
|
return false
|
|
226
261
|
end
|
|
227
262
|
|
|
263
|
+
return false if in_quoted_pair # unbalanced quoted pair
|
|
228
264
|
return false if in_quoted_string # unbalanced quotes
|
|
229
265
|
return false unless comment_depth.zero? # unbalanced comment parens
|
|
266
|
+
return false if joining_atoms # the last char we encountered was a period
|
|
230
267
|
|
|
231
268
|
true
|
|
232
269
|
end
|
|
233
270
|
|
|
234
|
-
def self.validate_domain_part_syntax(domain)
|
|
271
|
+
def self.validate_domain_part_syntax(domain, idn: true)
|
|
235
272
|
parts = domain.downcase.split(".", -1)
|
|
273
|
+
parts.map! { |part| SimpleIDN.to_ascii(part) } if idn
|
|
236
274
|
|
|
237
275
|
return false if parts.length <= 1 # Only one domain part
|
|
238
276
|
|
|
@@ -256,6 +294,14 @@ module ValidatesEmailFormatOf
|
|
|
256
294
|
return false unless DOMAIN_PART_TLD.match?(parts[-1])
|
|
257
295
|
true
|
|
258
296
|
end
|
|
297
|
+
|
|
298
|
+
def self.deprecation_warn(msg)
|
|
299
|
+
if defined?(ActiveSupport::Deprecation)
|
|
300
|
+
ActiveSupport::Deprecation.warn(msg)
|
|
301
|
+
else
|
|
302
|
+
warn(msg)
|
|
303
|
+
end
|
|
304
|
+
end
|
|
259
305
|
end
|
|
260
306
|
|
|
261
307
|
require "validates_email_format_of/active_model" if defined?(::ActiveModel) && !(ActiveModel::VERSION::MAJOR < 2 || (ActiveModel::VERSION::MAJOR == 2 && ActiveModel::VERSION::MINOR < 1))
|
data/spec/spec_helper.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
require "active_model"
|
|
2
2
|
require "active_support"
|
|
3
|
-
require "pry"
|
|
4
|
-
require "byebug"
|
|
5
3
|
|
|
6
4
|
RSpec::Matchers.define :have_errors_on_email do
|
|
7
|
-
match do |
|
|
5
|
+
match do |user|
|
|
6
|
+
actual = user.errors.full_messages
|
|
7
|
+
expect(user.errors.added?(:email, ValidatesEmailFormatOf::ERROR_MESSAGE_I18N_KEY))
|
|
8
8
|
expect(actual).not_to be_nil, "#{actual} should not be nil"
|
|
9
9
|
expect(actual).not_to be_empty, "#{actual} should not be empty"
|
|
10
10
|
expect(actual.size).to eq(@reasons.size), "#{actual} should have #{@reasons.size} elements"
|
|
@@ -19,7 +19,7 @@ RSpec::Matchers.define :have_errors_on_email do
|
|
|
19
19
|
chain :and_because do |reason|
|
|
20
20
|
(@reasons ||= []) << reason
|
|
21
21
|
end
|
|
22
|
-
match_when_negated do |
|
|
23
|
-
expect(
|
|
22
|
+
match_when_negated do |user|
|
|
23
|
+
expect(user.errors).to(be_empty)
|
|
24
24
|
end
|
|
25
25
|
end
|
|
@@ -22,7 +22,7 @@ describe ValidatesEmailFormatOf do
|
|
|
22
22
|
ActiveModel::Name.new(self, nil, "User")
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
|
-
user.new(example.example_group_instance.email).tap(&:valid?)
|
|
25
|
+
user.new(example.example_group_instance.email).tap(&:valid?)
|
|
26
26
|
end
|
|
27
27
|
let(:options) { {} }
|
|
28
28
|
let(:email) { |example| example.example_group.description }
|
|
@@ -58,13 +58,24 @@ describe ValidatesEmailFormatOf do
|
|
|
58
58
|
"_somename@example.com",
|
|
59
59
|
# apostrophes
|
|
60
60
|
"test'test@example.com",
|
|
61
|
-
#
|
|
61
|
+
# punycode domain names
|
|
62
62
|
"test@xn--bcher-kva.ch",
|
|
63
63
|
"test@example.xn--0zwm56d",
|
|
64
|
+
|
|
65
|
+
# IDN domains,
|
|
66
|
+
"test@exämple.com",
|
|
67
|
+
"test@пример.рф",
|
|
68
|
+
"test@почта.бел",
|
|
69
|
+
|
|
64
70
|
"test@192.192.192.1",
|
|
65
71
|
# Allow quoted characters. Valid according to http://www.rfc-editor.org/errata_search.php?rfc=3696
|
|
66
72
|
'"Abc\@def"@example.com',
|
|
73
|
+
"\"quote\".dotatom.\"otherquote\"@example.com",
|
|
67
74
|
'"Quote(Only".Chars@wier.de',
|
|
75
|
+
"\"much.more unusual\"@example.com",
|
|
76
|
+
"\"very.unusual.@.unusual.com\"@example.com",
|
|
77
|
+
'"very.(),:;<>[]\".VERY.\"very@\\ \"very\".unusual"@strange.example.com',
|
|
78
|
+
'"()<>[]:,;@\"!#$%&*+-/=?^_`{}| ~ ? ^_`{}|~.a"@example.org',
|
|
68
79
|
'"Fred\ Bloggs"@example.com',
|
|
69
80
|
'"Joe.\\Blow"@example.com',
|
|
70
81
|
# Balanced quoted characters
|
|
@@ -98,6 +109,7 @@ describe ValidatesEmailFormatOf do
|
|
|
98
109
|
"invalid@example.com-",
|
|
99
110
|
"invalid-example.com",
|
|
100
111
|
"invalid@example.b#r.com",
|
|
112
|
+
"just\"not\"right@example.com",
|
|
101
113
|
"invalid@example.c",
|
|
102
114
|
"invali d@example.com",
|
|
103
115
|
# TLD can not be only numeric
|
|
@@ -128,10 +140,11 @@ describe ValidatesEmailFormatOf do
|
|
|
128
140
|
"\nnewline@example.com",
|
|
129
141
|
" spacesbefore@example.com",
|
|
130
142
|
"spacesafter@example.com ",
|
|
131
|
-
"(unbalancedcomment@example.com"
|
|
143
|
+
"(unbalancedcomment@example.com",
|
|
144
|
+
"help@.example.co.uk" # TLD can not start with a period
|
|
132
145
|
].each do |address|
|
|
133
146
|
describe address do
|
|
134
|
-
it { should have_errors_on_email.because("does not appear to be a valid
|
|
147
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
135
148
|
end
|
|
136
149
|
end
|
|
137
150
|
|
|
@@ -141,7 +154,7 @@ describe ValidatesEmailFormatOf do
|
|
|
141
154
|
it { should_not have_errors_on_email }
|
|
142
155
|
end
|
|
143
156
|
describe "#{"a" * (limit + 1)}@example.com" do
|
|
144
|
-
it { should have_errors_on_email.because("does not appear to be a valid
|
|
157
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
145
158
|
end
|
|
146
159
|
end
|
|
147
160
|
describe "when using default" do
|
|
@@ -158,7 +171,7 @@ describe ValidatesEmailFormatOf do
|
|
|
158
171
|
it { should_not have_errors_on_email }
|
|
159
172
|
end
|
|
160
173
|
describe "user@#{"a." * (limit / 2 + 1)}com" do
|
|
161
|
-
it { should have_errors_on_email.because("does not appear to be a valid
|
|
174
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
162
175
|
end
|
|
163
176
|
end
|
|
164
177
|
describe "when using default" do
|
|
@@ -179,6 +192,27 @@ describe ValidatesEmailFormatOf do
|
|
|
179
192
|
end
|
|
180
193
|
end
|
|
181
194
|
|
|
195
|
+
describe "when idn support is disabled" do
|
|
196
|
+
before(:each) do
|
|
197
|
+
allow(SimpleIDN).to receive(:to_ascii).never
|
|
198
|
+
end
|
|
199
|
+
let(:options) { {idn: false} }
|
|
200
|
+
describe "test@exämple.com" do
|
|
201
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
describe "when idn support is enabled" do
|
|
206
|
+
before(:each) do
|
|
207
|
+
expect(SimpleIDN).to receive(:to_ascii).with("exämple").and_return("xn--exmple-cua")
|
|
208
|
+
expect(SimpleIDN).to receive(:to_ascii).with("com").and_return("com")
|
|
209
|
+
end
|
|
210
|
+
let(:options) { {idn: true} }
|
|
211
|
+
describe "test@exämple.com" do
|
|
212
|
+
it { should_not have_errors_on_email }
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
182
216
|
describe "mx record" do
|
|
183
217
|
domain = "example.com"
|
|
184
218
|
email = "valid@#{domain}"
|
|
@@ -216,6 +250,9 @@ describe ValidatesEmailFormatOf do
|
|
|
216
250
|
let(:mx_record) { [] }
|
|
217
251
|
describe email do
|
|
218
252
|
it { should have_errors_on_email.because("is not routable") }
|
|
253
|
+
it "adds the i18n key" do
|
|
254
|
+
subject.errors.added?(:email, ValidatesEmailFormatOf::ERROR_MX_MESSAGE_I18N_KEY)
|
|
255
|
+
end
|
|
219
256
|
end
|
|
220
257
|
describe "with a custom error message" do
|
|
221
258
|
let(:options) { {check_mx: true, mx_message: "There ain't no such domain!"} }
|
|
@@ -223,6 +260,7 @@ describe ValidatesEmailFormatOf do
|
|
|
223
260
|
it { should have_errors_on_email.because("There ain't no such domain!") }
|
|
224
261
|
end
|
|
225
262
|
end
|
|
263
|
+
|
|
226
264
|
describe "i18n" do
|
|
227
265
|
before(:each) do
|
|
228
266
|
allow(I18n.config).to receive(:locale).and_return(locale)
|
|
@@ -236,6 +274,7 @@ describe ValidatesEmailFormatOf do
|
|
|
236
274
|
end
|
|
237
275
|
end
|
|
238
276
|
end
|
|
277
|
+
|
|
239
278
|
describe "when not testing" do
|
|
240
279
|
before(:each) { allow(Resolv::DNS).to receive(:open).never }
|
|
241
280
|
describe "by default" do
|
|
@@ -258,13 +297,43 @@ describe ValidatesEmailFormatOf do
|
|
|
258
297
|
end
|
|
259
298
|
end
|
|
260
299
|
|
|
300
|
+
describe "mx record for internationalized domain" do
|
|
301
|
+
domain = "пример.рф"
|
|
302
|
+
email = "valid@#{domain}"
|
|
303
|
+
|
|
304
|
+
describe "when idn support is enabled" do
|
|
305
|
+
let(:dns) { double(Resolv::DNS) }
|
|
306
|
+
let(:options) { {check_mx: true, idn: true} }
|
|
307
|
+
|
|
308
|
+
before(:each) do
|
|
309
|
+
allow(Resolv::DNS).to receive(:open).and_yield(dns)
|
|
310
|
+
allow(dns).to receive(:"timeouts=").with(3).once
|
|
311
|
+
allow(dns).to receive(:getresources).with(SimpleIDN.to_ascii(domain), Resolv::DNS::Resource::IN::A).once.and_return([double])
|
|
312
|
+
allow(dns).to receive(:getresources).with(SimpleIDN.to_ascii(domain), Resolv::DNS::Resource::IN::MX).once.and_return([double])
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
describe email do
|
|
316
|
+
it { should_not have_errors_on_email }
|
|
317
|
+
end
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
describe "when idn support is disabled" do
|
|
321
|
+
let(:options) { {check_mx: true, idn: false} }
|
|
322
|
+
|
|
323
|
+
describe "test@пример.рф" do
|
|
324
|
+
let(:domain) { "exämple.com" }
|
|
325
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
326
|
+
end
|
|
327
|
+
end
|
|
328
|
+
end
|
|
329
|
+
|
|
261
330
|
describe "custom regex" do
|
|
262
331
|
let(:options) { {with: /[0-9]+@[0-9]+/} }
|
|
263
332
|
describe "012345@789" do
|
|
264
333
|
it { should_not have_errors_on_email }
|
|
265
334
|
end
|
|
266
335
|
describe "valid@example.com" do
|
|
267
|
-
it { should have_errors_on_email.because("does not appear to be a valid
|
|
336
|
+
it { should have_errors_on_email.because("does not appear to be a valid email address") }
|
|
268
337
|
end
|
|
269
338
|
end
|
|
270
339
|
|
|
@@ -275,7 +344,7 @@ describe ValidatesEmailFormatOf do
|
|
|
275
344
|
describe "present locale" do
|
|
276
345
|
let(:locale) { :pl }
|
|
277
346
|
describe "invalid@exmaple." do
|
|
278
|
-
it { should have_errors_on_email.because("nieprawidłowy adres
|
|
347
|
+
it { should have_errors_on_email.because("nieprawidłowy adres email") }
|
|
279
348
|
end
|
|
280
349
|
end
|
|
281
350
|
end
|
|
@@ -320,7 +389,7 @@ describe ValidatesEmailFormatOf do
|
|
|
320
389
|
ActiveModel::Name.new(self, nil, "User")
|
|
321
390
|
end
|
|
322
391
|
end
|
|
323
|
-
user.new(example.example_group_instance.email).tap(&:valid?)
|
|
392
|
+
user.new(example.example_group_instance.email).tap(&:valid?)
|
|
324
393
|
end
|
|
325
394
|
|
|
326
395
|
it_should_behave_like :all_specs
|
|
@@ -4,7 +4,7 @@ require "validates_email_format_of/version"
|
|
|
4
4
|
Gem::Specification.new do |s|
|
|
5
5
|
s.name = "validates_email_format_of"
|
|
6
6
|
s.version = ValidatesEmailFormatOf::VERSION
|
|
7
|
-
s.summary = "Validate
|
|
7
|
+
s.summary = "Validate email addresses against RFC 2822 and RFC 3696."
|
|
8
8
|
s.description = s.summary
|
|
9
9
|
s.authors = ["Alex Dunae", "Isaac Betesh"]
|
|
10
10
|
s.email = ["code@dunae.ca", "iybetesh@gmail.com"]
|
|
@@ -16,13 +16,13 @@ Gem::Specification.new do |s|
|
|
|
16
16
|
if RUBY_VERSION < "1.9.3"
|
|
17
17
|
s.add_dependency "i18n", "< 0.7.0"
|
|
18
18
|
else
|
|
19
|
-
s.add_dependency "i18n"
|
|
19
|
+
s.add_dependency "i18n", ">= 0.8.0"
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
+
s.add_dependency "simpleidn"
|
|
22
23
|
s.add_development_dependency "activemodel"
|
|
23
24
|
s.add_development_dependency "bundler"
|
|
24
25
|
s.add_development_dependency "rspec"
|
|
25
26
|
s.add_development_dependency "standard"
|
|
26
27
|
s.add_development_dependency "appraisal"
|
|
27
|
-
s.add_development_dependency "pry-byebug"
|
|
28
28
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: validates_email_format_of
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.8.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Alex Dunae
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: i18n
|
|
@@ -17,22 +17,22 @@ dependencies:
|
|
|
17
17
|
requirements:
|
|
18
18
|
- - ">="
|
|
19
19
|
- !ruby/object:Gem::Version
|
|
20
|
-
version:
|
|
20
|
+
version: 0.8.0
|
|
21
21
|
type: :runtime
|
|
22
22
|
prerelease: false
|
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
24
24
|
requirements:
|
|
25
25
|
- - ">="
|
|
26
26
|
- !ruby/object:Gem::Version
|
|
27
|
-
version:
|
|
27
|
+
version: 0.8.0
|
|
28
28
|
- !ruby/object:Gem::Dependency
|
|
29
|
-
name:
|
|
29
|
+
name: simpleidn
|
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
|
31
31
|
requirements:
|
|
32
32
|
- - ">="
|
|
33
33
|
- !ruby/object:Gem::Version
|
|
34
34
|
version: '0'
|
|
35
|
-
type: :
|
|
35
|
+
type: :runtime
|
|
36
36
|
prerelease: false
|
|
37
37
|
version_requirements: !ruby/object:Gem::Requirement
|
|
38
38
|
requirements:
|
|
@@ -40,7 +40,7 @@ dependencies:
|
|
|
40
40
|
- !ruby/object:Gem::Version
|
|
41
41
|
version: '0'
|
|
42
42
|
- !ruby/object:Gem::Dependency
|
|
43
|
-
name:
|
|
43
|
+
name: activemodel
|
|
44
44
|
requirement: !ruby/object:Gem::Requirement
|
|
45
45
|
requirements:
|
|
46
46
|
- - ">="
|
|
@@ -54,7 +54,7 @@ dependencies:
|
|
|
54
54
|
- !ruby/object:Gem::Version
|
|
55
55
|
version: '0'
|
|
56
56
|
- !ruby/object:Gem::Dependency
|
|
57
|
-
name:
|
|
57
|
+
name: bundler
|
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
|
59
59
|
requirements:
|
|
60
60
|
- - ">="
|
|
@@ -68,7 +68,7 @@ dependencies:
|
|
|
68
68
|
- !ruby/object:Gem::Version
|
|
69
69
|
version: '0'
|
|
70
70
|
- !ruby/object:Gem::Dependency
|
|
71
|
-
name:
|
|
71
|
+
name: rspec
|
|
72
72
|
requirement: !ruby/object:Gem::Requirement
|
|
73
73
|
requirements:
|
|
74
74
|
- - ">="
|
|
@@ -82,7 +82,7 @@ dependencies:
|
|
|
82
82
|
- !ruby/object:Gem::Version
|
|
83
83
|
version: '0'
|
|
84
84
|
- !ruby/object:Gem::Dependency
|
|
85
|
-
name:
|
|
85
|
+
name: standard
|
|
86
86
|
requirement: !ruby/object:Gem::Requirement
|
|
87
87
|
requirements:
|
|
88
88
|
- - ">="
|
|
@@ -96,7 +96,7 @@ dependencies:
|
|
|
96
96
|
- !ruby/object:Gem::Version
|
|
97
97
|
version: '0'
|
|
98
98
|
- !ruby/object:Gem::Dependency
|
|
99
|
-
name:
|
|
99
|
+
name: appraisal
|
|
100
100
|
requirement: !ruby/object:Gem::Requirement
|
|
101
101
|
requirements:
|
|
102
102
|
- - ">="
|
|
@@ -109,7 +109,7 @@ dependencies:
|
|
|
109
109
|
- - ">="
|
|
110
110
|
- !ruby/object:Gem::Version
|
|
111
111
|
version: '0'
|
|
112
|
-
description: Validate
|
|
112
|
+
description: Validate email addresses against RFC 2822 and RFC 3696.
|
|
113
113
|
email:
|
|
114
114
|
- code@dunae.ca
|
|
115
115
|
- iybetesh@gmail.com
|
|
@@ -117,6 +117,7 @@ executables: []
|
|
|
117
117
|
extensions: []
|
|
118
118
|
extra_rdoc_files: []
|
|
119
119
|
files:
|
|
120
|
+
- ".github/dependabot.yml"
|
|
120
121
|
- ".github/workflows/ci.yml"
|
|
121
122
|
- ".gitignore"
|
|
122
123
|
- ".rspec"
|
|
@@ -124,15 +125,17 @@ files:
|
|
|
124
125
|
- CHANGELOG.md
|
|
125
126
|
- Gemfile
|
|
126
127
|
- MIT-LICENSE
|
|
127
|
-
- README.
|
|
128
|
+
- README.md
|
|
128
129
|
- config/locales/de.yml
|
|
129
130
|
- config/locales/en.yml
|
|
130
131
|
- config/locales/fr.yml
|
|
132
|
+
- config/locales/id.yml
|
|
131
133
|
- config/locales/it.yml
|
|
132
134
|
- config/locales/ja.yml
|
|
133
135
|
- config/locales/pl.yml
|
|
134
136
|
- config/locales/pt-BR.yml
|
|
135
137
|
- config/locales/pt.yml
|
|
138
|
+
- config/locales/tr.yml
|
|
136
139
|
- gemfiles/rails_4.2.gemfile
|
|
137
140
|
- gemfiles/rails_5.0.gemfile
|
|
138
141
|
- gemfiles/rails_5.1.gemfile
|
|
@@ -140,6 +143,7 @@ files:
|
|
|
140
143
|
- gemfiles/rails_6.0.gemfile
|
|
141
144
|
- gemfiles/rails_6.1.gemfile
|
|
142
145
|
- gemfiles/rails_7.0.gemfile
|
|
146
|
+
- gemfiles/rails_7.1.gemfile
|
|
143
147
|
- lib/validates_email_format_of.rb
|
|
144
148
|
- lib/validates_email_format_of/active_model.rb
|
|
145
149
|
- lib/validates_email_format_of/railtie.rb
|
|
@@ -169,8 +173,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
169
173
|
- !ruby/object:Gem::Version
|
|
170
174
|
version: '0'
|
|
171
175
|
requirements: []
|
|
172
|
-
rubygems_version: 3.
|
|
176
|
+
rubygems_version: 3.3.26
|
|
173
177
|
signing_key:
|
|
174
178
|
specification_version: 4
|
|
175
|
-
summary: Validate
|
|
179
|
+
summary: Validate email addresses against RFC 2822 and RFC 3696.
|
|
176
180
|
test_files: []
|
data/README.rdoc
DELETED
|
@@ -1,100 +0,0 @@
|
|
|
1
|
-
= validates_email_format_of Gem and Rails Plugin
|
|
2
|
-
|
|
3
|
-
Validate e-mail addresses against RFC 2822 and RFC 3696.
|
|
4
|
-
|
|
5
|
-
== Installation
|
|
6
|
-
|
|
7
|
-
Installing as a gem:
|
|
8
|
-
|
|
9
|
-
gem install validates_email_format_of
|
|
10
|
-
|
|
11
|
-
Or in your Gemfile:
|
|
12
|
-
|
|
13
|
-
gem 'validates_email_format_of'
|
|
14
|
-
|
|
15
|
-
== Usage
|
|
16
|
-
|
|
17
|
-
# Rails
|
|
18
|
-
# I18n locales are loaded automatically.
|
|
19
|
-
class Person < ActiveRecord::Base
|
|
20
|
-
validates_email_format_of :email, :message => 'is not looking good'
|
|
21
|
-
# OR
|
|
22
|
-
validates :email, :email_format => { :message => 'is not looking good' }
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Now you can test your model using RSpec:
|
|
26
|
-
require "validates_email_format_of/rspec_matcher"
|
|
27
|
-
describe Person do
|
|
28
|
-
it { should validate_email_format_of(:email).with_message('is not looking good') }
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# If you're not using Rails (which really means, if you're not using ActiveModel::Validations)
|
|
32
|
-
ValidatesEmailFormatOf::load_i18n_locales # Optional, if you want error messages to be in your language
|
|
33
|
-
I18n.locale = :pl # If, for example, you want Polish error messages.
|
|
34
|
-
ValidatesEmailFormatOf::validate_email_format("example@mydomain.com") # => nil
|
|
35
|
-
ValidatesEmailFormatOf::validate_email_format("invalid_because_there_is_no_at_symbol") # => ["does not appear to be a valid e-mail address"]
|
|
36
|
-
|
|
37
|
-
=== Options
|
|
38
|
-
|
|
39
|
-
:message
|
|
40
|
-
String. A custom error message when the email format is invalid (default is: "does not appear to be a valid e-mail address")
|
|
41
|
-
:check_mx
|
|
42
|
-
Boolean. Check domain for a valid MX record (default is false)
|
|
43
|
-
:check_mx_timeout
|
|
44
|
-
Integer. Timeout in seconds for checking MX records before a `ResolvTimeout` is raised (default is 3).
|
|
45
|
-
:mx_message
|
|
46
|
-
String. A custom error message when the domain does not match a valid MX record (default is: "is not routable"). Ignored unless :check_mx option is true.
|
|
47
|
-
:local_length
|
|
48
|
-
Maximum number of characters allowed in the local part (everything before the '@') (default is 64)
|
|
49
|
-
:domain_length
|
|
50
|
-
Maximum number of characters allowed in the domain part (everything after the '@') (default is 255)
|
|
51
|
-
:generate_message
|
|
52
|
-
Boolean. Return the I18n key of the error message instead of the error message itself (default is false)
|
|
53
|
-
:with
|
|
54
|
-
Specify a custom Regex as the valid email format.
|
|
55
|
-
:on, :if, :unless, :allow_nil, :allow_blank, :strict
|
|
56
|
-
Standard ActiveModel validation options. These work in the ActiveModel/ActiveRecord/Rails syntax only.
|
|
57
|
-
See http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates for details.
|
|
58
|
-
|
|
59
|
-
== Testing
|
|
60
|
-
|
|
61
|
-
To execute the unit tests against [all the Rails versions we support run](gemfiles/) <tt>bundle exec appraisal rspec</tt> or run against an individual version with <tt>bundle exec appraisal rails-6.0 rspec</tt>.
|
|
62
|
-
|
|
63
|
-
Tested in Ruby 1.8.7, 1.9.2, 1.9.3, 2.0.0, 2.1.2, JRuby and REE 1.8.7.
|
|
64
|
-
|
|
65
|
-
== Contributing
|
|
66
|
-
|
|
67
|
-
If you think we're letting some rules about valid email formats slip through the cracks, don't just update the Regex.
|
|
68
|
-
Instead, add a failing test, and demonstrate that the described email address should be treated differently. A link to an appropriate RFC is the best way to do this.
|
|
69
|
-
Then change the gem code to make the test pass.
|
|
70
|
-
|
|
71
|
-
describe "i_think_this_is_not_a_v@lid_email_addre.ss" do
|
|
72
|
-
# According to http://..., this email address IS NOT valid.
|
|
73
|
-
it { should have_errors_on_email.because("does not appear to be valid") }
|
|
74
|
-
end
|
|
75
|
-
describe "i_think_this_is_a_v@lid_email_addre.ss" do
|
|
76
|
-
# According to http://..., this email address IS valid.
|
|
77
|
-
it { should_not have_errors_on_email }
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
Yes, our Rspec syntax is that simple!
|
|
81
|
-
|
|
82
|
-
== Homepage
|
|
83
|
-
|
|
84
|
-
* https://github.com/validates-email-format-of/validates_email_format_of
|
|
85
|
-
|
|
86
|
-
== Credits
|
|
87
|
-
|
|
88
|
-
Written by Alex Dunae (dunae.ca), 2006-22.
|
|
89
|
-
|
|
90
|
-
Many thanks to the plugin's recent contributors: https://github.com/alexdunae/validates_email_format_of/contributors
|
|
91
|
-
|
|
92
|
-
Thanks to Francis Hwang (http://fhwang.net/) at Diversion Media for creating the 1.1 update.
|
|
93
|
-
|
|
94
|
-
Thanks to Travis Sinnott for creating the 1.3 update.
|
|
95
|
-
|
|
96
|
-
Thanks to Denis Ahearn at Riverock Technologies (http://www.riverocktech.com/) for creating the 1.4 update.
|
|
97
|
-
|
|
98
|
-
Thanks to George Anderson (http://github.com/george) and 'history' (http://github.com/history) for creating the 1.4.1 update.
|
|
99
|
-
|
|
100
|
-
Thanks to Isaac Betesh (https://github.com/betesh) for converting tests to Rspec and refactoring for version 1.6.0.
|