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 'xorcist', '~> 1.1' | ||||
| gem 'cocoon', '~> 1.2' | ||||
| gem 'mail', '~> 2.8' | ||||
|  |  | |||
|  | @ -816,6 +816,7 @@ DEPENDENCIES | |||
|   letter_opener_web (~> 2.0) | ||||
|   link_header (~> 0.0) | ||||
|   lograge (~> 0.12) | ||||
|   mail (~> 2.8) | ||||
|   makara (~> 0.5) | ||||
|   mario-redis-lock (~> 1.2) | ||||
|   memory_profiler | ||||
|  |  | |||
|  | @ -94,6 +94,9 @@ class User < ApplicationRecord | |||
|   validates :invite_request, presence: true, on: :create, if: :invite_text_required? | ||||
| 
 | ||||
|   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 EmailMxValidator, if: :validate_email_dns? | ||||
|   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 | ||||
|     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 | ||||
|       user = Fabricate.build(:user, chosen_languages: ['']) | ||||
|       user.valid? | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue