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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 946d5e9368662216b21d1dfa1434edbdbe992b6c1354d3b53b73a62e8d262a06
4
- data.tar.gz: 9e47f0583115b145f461d7fcbc2cda5a4db3abe263a8edab82df98d160242431
3
+ metadata.gz: 0cfee88066764e2eb7e65860751c532baa42fad3066ea868245d57786c826a8d
4
+ data.tar.gz: 04c3ae92d49eddf9979755d2d60e1c2e3bfd77d7f8acb762beefd4bcb6eb01e9
5
5
  SHA512:
6
- metadata.gz: c333b2f6dd62889860581493a2453ee0f16db2f9db024f3f3ff8db88c2496e4d438221ff31a55d8fc2fd3174d5aec834615e221a2e49b377c22dc4bc3c569ed3
7
- data.tar.gz: 2fd79606ecdf91e1c665b71ccb343f2b3703082db2c5d63085919435fabc7955f89cae73d2a66a8fefb9c8d4d26611b25346e06c4b69f6e1958852f2228f8b0e
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)
@@ -1,6 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EmailDomainChecker
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  end
6
-
@@ -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.0
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