email_domain_checker 0.1.0 → 0.1.1
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/README.md +45 -0
- data/lib/email_domain_checker/active_model_validator.rb +107 -0
- data/lib/email_domain_checker/version.rb +1 -2
- data/lib/email_domain_checker.rb +11 -0
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 0cfee88066764e2eb7e65860751c532baa42fad3066ea868245d57786c826a8d
|
|
4
|
+
data.tar.gz: 04c3ae92d49eddf9979755d2d60e1c2e3bfd77d7f8acb762beefd4bcb6eb01e9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: be4b1fc7445f80308a1ca93af0d068c4ded227ad59b630cb374c1c63e8a7bcf2d8b5ed8c75ef0ff09dfae937eaaec205358e637b0e4f0bb72dc6e4a46bb79553
|
|
7
|
+
data.tar.gz: e4b1ed6439c71e06918488023a94d99334015af247846ab611076db9caf9c66a4ad4a1263562720ba1f54c6ae1cf0fec6329e636d5d8b1a420865cfacad9d130
|
data/README.md
CHANGED
|
@@ -73,6 +73,51 @@ checker = EmailDomainChecker::Checker.new("user@example.com")
|
|
|
73
73
|
checker.redacted_email # => "{hash}@example.com"
|
|
74
74
|
```
|
|
75
75
|
|
|
76
|
+
### ActiveModel/ActiveRecord Integration
|
|
77
|
+
|
|
78
|
+
When ActiveModel is available, you can use the `DomainCheckValidator` for easy validation and normalization in your models:
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
class User < ActiveRecord::Base
|
|
82
|
+
validates :email, domain_check: { check_mx: true, timeout: 3 }, normalize: true
|
|
83
|
+
end
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
#### Options
|
|
87
|
+
|
|
88
|
+
- `domain_check`: Hash of options for domain validation
|
|
89
|
+
- `check_mx`: Check MX records (default: `true`)
|
|
90
|
+
- `check_a`: Check A records (default: `false`)
|
|
91
|
+
- `timeout`: DNS query timeout in seconds (default: `5`)
|
|
92
|
+
- `validate_format`: Validate email format (default: `true`)
|
|
93
|
+
- `validate_domain`: Validate domain (default: `true`)
|
|
94
|
+
- `normalize`: Normalize email before validation (default: `false`)
|
|
95
|
+
- `message`: Custom error message
|
|
96
|
+
|
|
97
|
+
#### Examples
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
# Basic validation with domain check
|
|
101
|
+
class User < ActiveRecord::Base
|
|
102
|
+
validates :email, domain_check: { check_mx: true, timeout: 3 }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# Format validation only (skip domain check)
|
|
106
|
+
class User < ActiveRecord::Base
|
|
107
|
+
validates :email, domain_check: { validate_domain: false }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# With automatic normalization
|
|
111
|
+
class User < ActiveRecord::Base
|
|
112
|
+
validates :email, domain_check: { check_mx: true }, normalize: true
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# With custom error message
|
|
116
|
+
class User < ActiveRecord::Base
|
|
117
|
+
validates :email, domain_check: { check_mx: true }, message: "Invalid email address"
|
|
118
|
+
end
|
|
119
|
+
```
|
|
120
|
+
|
|
76
121
|
### Configuration Options
|
|
77
122
|
|
|
78
123
|
- `validate_format`: Validate email format using email_address gem (default: true)
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "active_model"
|
|
4
|
+
|
|
5
|
+
require_relative "checker"
|
|
6
|
+
require_relative "normalizer"
|
|
7
|
+
|
|
8
|
+
module EmailDomainChecker
|
|
9
|
+
# ActiveModel validator for email domain checking
|
|
10
|
+
#
|
|
11
|
+
# Usage:
|
|
12
|
+
# class User < ActiveRecord::Base
|
|
13
|
+
# validates :email, domain_check: { check_mx: true, timeout: 3 }, normalize: true
|
|
14
|
+
# end
|
|
15
|
+
#
|
|
16
|
+
# Options:
|
|
17
|
+
# - domain_check: Hash of options for domain validation
|
|
18
|
+
# * check_mx: Boolean (default: true) - Check MX records
|
|
19
|
+
# * check_a: Boolean (default: false) - Check A records
|
|
20
|
+
# * timeout: Integer (default: 5) - DNS query timeout in seconds
|
|
21
|
+
# * validate_format: Boolean (default: true) - Validate email format
|
|
22
|
+
# * validate_domain: Boolean (default: true) - Validate domain
|
|
23
|
+
# - normalize: Boolean (default: false) - Normalize email before validation
|
|
24
|
+
# - message: String or Symbol - Custom error message
|
|
25
|
+
class DomainCheckValidator < ActiveModel::EachValidator
|
|
26
|
+
def validate_each(record, attribute, value)
|
|
27
|
+
return if value.blank?
|
|
28
|
+
|
|
29
|
+
# ActiveModel passes domain_check hash contents directly to options
|
|
30
|
+
# when using validates :email, domain_check: { normalize: false }
|
|
31
|
+
# So options will be { validate_domain: false, normalize: false } etc.
|
|
32
|
+
normalize_option = options[:normalize] == true
|
|
33
|
+
|
|
34
|
+
original_value = value.is_a?(String) ? value : value.to_s
|
|
35
|
+
normalized_value = normalize_option ? Normalizer.normalize(original_value) : original_value
|
|
36
|
+
|
|
37
|
+
if normalize_option && normalized_value != original_value
|
|
38
|
+
record.public_send("#{attribute}=", normalized_value)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
validation_options = build_validation_options(record, attribute)
|
|
42
|
+
value_for_checker = normalize_option ? normalized_value : original_value
|
|
43
|
+
checker = Checker.new(value_for_checker, validation_options)
|
|
44
|
+
|
|
45
|
+
unless checker.valid?
|
|
46
|
+
error_message = error_message_for(record, attribute, checker)
|
|
47
|
+
record.errors.add(attribute, error_message[:key], message: error_message[:message])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def build_validation_options(record, attribute)
|
|
54
|
+
default_options = {
|
|
55
|
+
validate_format: true,
|
|
56
|
+
validate_domain: true,
|
|
57
|
+
check_mx: true,
|
|
58
|
+
check_a: false,
|
|
59
|
+
timeout: 5
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
# ActiveModel passes domain_check hash contents directly to options
|
|
63
|
+
# Exclude normalize and message from validation options
|
|
64
|
+
domain_check_options = options.reject { |k, _v| k == :normalize || k == :message }
|
|
65
|
+
default_options.merge(domain_check_options)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def error_message_for(record, attribute, checker)
|
|
69
|
+
message_option = options[:message]
|
|
70
|
+
if message_option
|
|
71
|
+
return {
|
|
72
|
+
key: :invalid,
|
|
73
|
+
message: message_option.is_a?(Symbol) ? record.errors.generate_message(attribute, message_option) : message_option
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
unless checker.format_valid?
|
|
78
|
+
return {
|
|
79
|
+
key: :invalid_format,
|
|
80
|
+
message: i18n_message("errors.messages.invalid_email_format", "is not a valid email format")
|
|
81
|
+
}
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
unless checker.domain_valid?
|
|
85
|
+
return {
|
|
86
|
+
key: :invalid_domain,
|
|
87
|
+
message: i18n_message("errors.messages.invalid_email_domain", "has an invalid domain")
|
|
88
|
+
}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
{
|
|
92
|
+
key: :invalid,
|
|
93
|
+
message: i18n_message("errors.messages.invalid_email", "is not a valid email address")
|
|
94
|
+
}
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def i18n_message(key, default)
|
|
98
|
+
return default unless defined?(I18n)
|
|
99
|
+
|
|
100
|
+
I18n.t(key, default: default)
|
|
101
|
+
rescue StandardError
|
|
102
|
+
default
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
DomainCheckValidator = EmailDomainChecker::DomainCheckValidator unless defined?(DomainCheckValidator)
|
data/lib/email_domain_checker.rb
CHANGED
|
@@ -8,6 +8,17 @@ require_relative "email_domain_checker/domain_validator"
|
|
|
8
8
|
require_relative "email_domain_checker/email_address_adapter"
|
|
9
9
|
require_relative "email_domain_checker/checker"
|
|
10
10
|
|
|
11
|
+
# Conditionally load ActiveModel integration if ActiveModel is available
|
|
12
|
+
begin
|
|
13
|
+
# Require logger gem for older Rails/ActiveModel versions on Ruby 3.4+
|
|
14
|
+
# This is needed because logger was removed from Ruby standard library in 3.4+
|
|
15
|
+
require "logger" if RUBY_VERSION >= "3.4"
|
|
16
|
+
require "active_model"
|
|
17
|
+
require_relative "email_domain_checker/active_model_validator"
|
|
18
|
+
rescue LoadError
|
|
19
|
+
# ActiveModel is not available, skip integration
|
|
20
|
+
end
|
|
21
|
+
|
|
11
22
|
module EmailDomainChecker
|
|
12
23
|
class Error < StandardError; end
|
|
13
24
|
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: email_domain_checker
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Koki Tatematsu
|
|
@@ -79,6 +79,7 @@ files:
|
|
|
79
79
|
- Rakefile
|
|
80
80
|
- email_domain_checker.gemspec
|
|
81
81
|
- lib/email_domain_checker.rb
|
|
82
|
+
- lib/email_domain_checker/active_model_validator.rb
|
|
82
83
|
- lib/email_domain_checker/checker.rb
|
|
83
84
|
- lib/email_domain_checker/config.rb
|
|
84
85
|
- lib/email_domain_checker/dns_resolver.rb
|