Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement email validation #97

Open
JohnRDOrazio opened this issue Sep 26, 2021 · 0 comments
Open

Implement email validation #97

JohnRDOrazio opened this issue Sep 26, 2021 · 0 comments
Labels
enhancement New feature or request

Comments

@JohnRDOrazio
Copy link
Collaborator

JohnRDOrazio commented Sep 26, 2021

Email validation will be done mainly by sending a validation link. However it can be useful to filter out valid email formats from the start, just in case someone accidentally types in an invalid email format.

Browsing on stackoverflow, I found a mention of the valid_email2 gem which could help some:

Don't use a regular expression for email address validation. It's a trap. There are way more valid email address formats than you'll think of. However! The mail gem (it's required by ActionMailer, so you have it) will parse email addresses — with a proper parser — for you:

require 'mail'
a = Mail::Address.new('[email protected]')

This will throw a Mail::Field::ParseError if it's a non-compliant email address. (We're not getting into things like doing an MX address lookup or anything.)

If you want the good ol' Rails validator experience, you can make app/models/concerns/email_validatable.rb:

require 'mail'

module EmailValidatable
  extend ActiveSupport::Concern

  class EmailValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      begin
        a = Mail::Address.new(value)
      rescue Mail::Field::ParseError
        record.errors[attribute] << (options[:message] || "is not an email")
      end
    end
  end
end

and then in your model, you can:

include EmailValidatable
validates :email, email: true

As Iwo Dziechciarow's comment below mentions, this passes anything that's a valid "To:" address through. So something like Foo Bar <[email protected]> is valid. This might be a problem for you, it might not; it really is a valid address, after all.

If you do want just the address portion of it:

a = Mail::Address.new('Foo Bar <[email protected]>')
a.address
=> "[email protected]"

As Björn Weinbrenne notes below, there are way more valid RFC2822 addresses than you may expect (I'm quite sure all of the addresses listed there are compliant, and may receive mail depending system configurations) — this is why I don't recommend trying a regex, but using a compliant parser.

If you really care whether you can send email to an address then your best bet — by far — is to actually send a message with a verification link.

@JohnRDOrazio JohnRDOrazio changed the title Email validation Implement email validation Sep 26, 2021
@JohnRDOrazio JohnRDOrazio added the enhancement New feature or request label Sep 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant