Improve email address validation (#29838)
This commit is contained in:
parent
8ce403a85b
commit
ba5551fd1d
5 changed files with 29 additions and 0 deletions
1
Gemfile
1
Gemfile
|
@ -158,3 +158,4 @@ gem 'concurrent-ruby', require: false
|
||||||
gem 'connection_pool', require: false
|
gem 'connection_pool', require: false
|
||||||
gem 'xorcist', '~> 1.1'
|
gem 'xorcist', '~> 1.1'
|
||||||
gem 'cocoon', '~> 1.2'
|
gem 'cocoon', '~> 1.2'
|
||||||
|
gem 'mail', '~> 2.8'
|
||||||
|
|
|
@ -816,6 +816,7 @@ DEPENDENCIES
|
||||||
letter_opener_web (~> 2.0)
|
letter_opener_web (~> 2.0)
|
||||||
link_header (~> 0.0)
|
link_header (~> 0.0)
|
||||||
lograge (~> 0.12)
|
lograge (~> 0.12)
|
||||||
|
mail (~> 2.8)
|
||||||
makara (~> 0.5)
|
makara (~> 0.5)
|
||||||
mario-redis-lock (~> 1.2)
|
mario-redis-lock (~> 1.2)
|
||||||
memory_profiler
|
memory_profiler
|
||||||
|
|
|
@ -94,6 +94,9 @@ class User < ApplicationRecord
|
||||||
validates :invite_request, presence: true, on: :create, if: :invite_text_required?
|
validates :invite_request, presence: true, on: :create, if: :invite_text_required?
|
||||||
|
|
||||||
validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
|
validates :locale, inclusion: I18n.available_locales.map(&:to_s), if: :locale?
|
||||||
|
|
||||||
|
validates :email, presence: true, email_address: true
|
||||||
|
|
||||||
validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? }
|
validates_with BlacklistedEmailValidator, if: -> { ENV['EMAIL_DOMAIN_LISTS_APPLY_AFTER_CONFIRMATION'] == 'true' || !confirmed? }
|
||||||
validates_with EmailMxValidator, if: :validate_email_dns?
|
validates_with EmailMxValidator, if: :validate_email_dns?
|
||||||
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
|
validates :agreement, acceptance: { allow_nil: false, accept: [true, 'true', '1'] }, on: :create
|
||||||
|
|
18
app/validators/email_address_validator.rb
Normal file
18
app/validators/email_address_validator.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# NOTE: I initially wrote this as `EmailValidator` but it ended up clashing
|
||||||
|
# with an indirect dependency of ours, `validate_email`, which, turns out,
|
||||||
|
# has the same approach as we do, but with an extra check disallowing
|
||||||
|
# single-label domains. Decided to not switch to `validate_email` because
|
||||||
|
# we do want to allow at least `localhost`.
|
||||||
|
|
||||||
|
class EmailAddressValidator < ActiveModel::EachValidator
|
||||||
|
def validate_each(record, attribute, value)
|
||||||
|
value = value.strip
|
||||||
|
|
||||||
|
address = Mail::Address.new(value)
|
||||||
|
record.errors.add(attribute, :invalid) if address.address != value
|
||||||
|
rescue Mail::Field::FieldError
|
||||||
|
record.errors.add(attribute, :invalid)
|
||||||
|
end
|
||||||
|
end
|
|
@ -40,6 +40,12 @@ RSpec.describe User, type: :model do
|
||||||
expect(user.valid?).to be true
|
expect(user.valid?).to be true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'is valid with a localhost e-mail address' do
|
||||||
|
user = Fabricate.build(:user, email: 'admin@localhost')
|
||||||
|
user.valid?
|
||||||
|
expect(user.valid?).to be true
|
||||||
|
end
|
||||||
|
|
||||||
it 'cleans out empty string from languages' do
|
it 'cleans out empty string from languages' do
|
||||||
user = Fabricate.build(:user, chosen_languages: [''])
|
user = Fabricate.build(:user, chosen_languages: [''])
|
||||||
user.valid?
|
user.valid?
|
||||||
|
|
Loading…
Reference in a new issue