valid-email-0.1.3/0000755000175100017510000000000013661711707012736 5ustar pravipravivalid-email-0.1.3/.gitignore0000644000175100017510000000004713661711707014727 0ustar pravipravi*.swp *.gem .bundle Gemfile.lock pkg/* valid-email-0.1.3/Rakefile0000644000175100017510000000030513661711707014401 0ustar pravipravirequire "bundler/gem_tasks" require 'rspec/core/rake_task' desc "Run specs" RSpec::Core::RakeTask.new do |t| t.pattern = 'spec/**/*_spec.rb' end task :default => [:spec] task :build => [:spec] valid-email-0.1.3/spec/0000755000175100017510000000000013661711707013670 5ustar pravipravivalid-email-0.1.3/spec/email_validator_spec.rb0000644000175100017510000002074713661711707020375 0ustar pravipravirequire 'spec_helper' describe EmailValidator do person_class = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => true end person_class_mx = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => {:mx => true} end person_class_mx_with_fallback = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => {:mx_with_fallback => true} end person_class_disposable_email = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => {:ban_disposable_email => true} end person_class_nil_allowed = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => {:allow_nil => true} end person_class_blank_allowed = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => {:allow_blank => true} end person_class_mx_separated = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :mx => true end person_class_mx_with_fallback_separated = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :mx_with_fallback => true end person_class_domain = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :domain => true end person_message_specified = Class.new do include ActiveModel::Validations attr_accessor :email validates :email, :email => { :message => 'custom message', :ban_disposable_email => true } end shared_examples_for "Invalid model" do before { subject.valid? } it { is_expected.not_to be_valid } specify { expect(subject.errors[:email]).to match_array errors } end shared_examples_for "Validating emails" do before :each do I18n.locale = locale end describe "validating email" do subject { person_class.new } it "fails when email empty" do expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email is not valid" do subject.email = 'joh@doe' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email domain is prefixed with dot" do subject.email = 'john@.doe' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email domain contains two consecutive dots" do subject.email = 'john@doe-two..com' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email ends with a period" do subject.email = 'john@doe.com.' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email ends with special characters" do subject.email = 'john@doe.com&' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when email is valid with information" do subject.email = '"John Doe" ' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "passes when email is simple email address" do subject.email = 'john@doe.com' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end it "fails when email is simple email address not stripped" do subject.email = 'john@doe.com ' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when domain contains a space" do subject.email = 'john@doe .com' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when passing multiple simple email addresses" do subject.email = 'john@doe.com, maria@doe.com' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end end describe "validating email with MX and fallback to A" do subject { person_class_mx_with_fallback.new } it "passes when email domain has MX record" do subject.email = 'john@gmail.com' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end it "passes when email domain has no MX record but has an A record" do subject.email = 'john@subdomain.rubyonrails.org' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end it "fails when domain does not exists" do subject.email = 'john@nonexistentdomain.abc' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end end describe "validating email with MX" do subject { person_class_mx.new } it "passes when email domain has MX record" do subject.email = 'john@gmail.com' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end it "fails when email domain has no MX record" do subject.email = 'john@subdomain.rubyonrails.org' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "fails when domain does not exists" do subject.email = 'john@nonexistentdomain.abc' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end end describe "validating MX with fallback to A" do subject { person_class_mx_with_fallback_separated.new } context "when domain is not specified" do before { subject.email = 'john' } it_behaves_like "Invalid model" end context "when domain is not specified but @ is" do before { subject.email = 'john@' } it_behaves_like "Invalid model" end end describe "validating MX" do subject { person_class_mx_separated.new } context "when domain is not specified" do before { subject.email = 'john' } it_behaves_like "Invalid model" end context "when domain is not specified but @ is" do before { subject.email = 'john@' } it_behaves_like "Invalid model" end end describe "validating email from disposable service" do subject { person_class_disposable_email.new } it "passes when email from trusted email services" do subject.email = 'john@mail.ru' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end it "fails when email from disposable email services" do subject.email = 'john@grr.la' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end end describe "validating domain" do subject { person_class_domain.new } it "does not pass with an invalid domain" do subject.email = "test@example.org$\'" expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to eq errors end it "passes with valid domain" do subject.email = 'john@example.org' expect(subject.valid?).to be_truthy expect(subject.errors[:email]).to be_empty end end end describe "Can allow nil" do subject { person_class_nil_allowed.new } it "passes even if mail isn't set" do subject.email = nil expect(subject).to be_valid expect(subject.errors[:email]).to be_empty end end describe "Can allow blank" do subject { person_class_blank_allowed.new } it "passes even if mail is a blank string set" do subject.email = '' expect(subject).to be_valid expect(subject.errors[:email]).to be_empty end end describe "Accepts custom messages" do subject { person_message_specified.new } it "adds only the custom error" do subject.email = 'bad@mailnator.com' expect(subject.valid?).to be_falsey expect(subject.errors[:email]).to match_array [ 'custom message' ] end end describe "Translating in english" do let!(:locale){ :en } let!(:errors) { [ "is invalid" ] } it_behaves_like "Validating emails" end describe "Translating in french" do let!(:locale){ :fr } let!(:errors) { [ "est invalide" ] } it_behaves_like "Validating emails" end end valid-email-0.1.3/spec/extensions_validator_spec.rb0000644000175100017510000000067713661711707021505 0ustar pravipravirequire 'spec_helper' require 'valid_email/all_with_extensions' describe String do it { expect("mymail@gmail").to respond_to(:email?) } it "is a valid e-mail" do expect("mymail@gmail.com".email?).to be_truthy end it "is not valid when text is not a real e-mail" do expect("invalidMail".email?).to be_falsey end context "when nil" do it "is invalid e-mail" do expect(nil.email?).to be_falsey end end end valid-email-0.1.3/spec/validate_email_spec.rb0000644000175100017510000001046713661711707020177 0ustar pravipravi# encoding: utf-8 require 'spec_helper' describe ValidateEmail do describe '.valid?' do it 'returns true when passed email has valid format' do expect(ValidateEmail.valid?('user@gmail.com')).to be_truthy expect(ValidateEmail.valid?('valid.user@gmail.com')).to be_truthy end it 'returns false when passed email has invalid format' do expect(ValidateEmail.valid?('user@gmail.com.')).to be_falsey expect(ValidateEmail.valid?('user.@gmail.com')).to be_falsey expect(ValidateEmail.valid?('Hgft@(()).com')).to be_falsey end context 'when mx: true option passed' do it 'returns true when mx record exist' do expect(ValidateEmail.valid?('user@gmail.com', mx: true)).to be_truthy end it "returns false when mx record doesn't exist" do expect(ValidateEmail.valid?('user@example.com', mx: true)).to be_falsey end end context 'when domain: true option passed' do context 'with valid domains' do valid_domains = [ 'example.org', '0-mail.com', '0815.ru', '0clickemail.com', 'test.co.uk', 'fux0ringduh.com', 'girlsundertheinfluence.com', 'h.mintemail.com', 'mail-temporaire.fr', 'mt2009.com', 'mega.zik.dj', '0.test.com', 'e.test.com', 'mail.e.test.com', 'a.aa', 'test.xn--clchc0ea0b2g2a9gcd', 'my-domain.com', 'тест.рф', 'mail.тест.рф', 'umläüt-domain.de', ] valid_domains.each do |valid_domain| it "returns true for #{valid_domain}" do email = "john@#{valid_domain}" expect(ValidateEmail.valid?(email, domain: true)).to be_truthy end end end context 'with invalid domain' do invalid_domains = [ '-eouae.test', 'oue-.test', 'oeuoue.-oeuoue', 'oueaaoeu.oeue-', 'ouoeu.eou_ueoe', '.test.com', 'test..com', 'test@test.com', "example.org$\'", "foo bar.com", ] invalid_domains.each do |invalid_domain| it "returns false for #{invalid_domain}" do email = "john@#{invalid_domain}" expect(ValidateEmail.valid?(email, domain: true)).to be_falsey end end end end end describe '.valid_local?' do it 'returns false if the local segment is too long' do expect( ValidateEmail.valid_local?( 'abcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcdeabcde' ) ).to be_falsey end it 'returns false if the local segment has an empty dot atom' do expect(ValidateEmail.valid_local?('.user')).to be_falsey expect(ValidateEmail.valid_local?('.user.')).to be_falsey expect(ValidateEmail.valid_local?('user.')).to be_falsey expect(ValidateEmail.valid_local?('us..er')).to be_falsey end it 'returns false if the local segment has a special character in an unquoted dot atom' do expect(ValidateEmail.valid_local?('us@er')).to be_falsey expect(ValidateEmail.valid_local?('user.\\.name')).to be_falsey expect(ValidateEmail.valid_local?('user."name')).to be_falsey end it 'returns false if the local segment has an unescaped special character in a quoted dot atom' do expect(ValidateEmail.valid_local?('test." test".test')).to be_falsey expect(ValidateEmail.valid_local?('test."test\".test')).to be_falsey expect(ValidateEmail.valid_local?('test."te"st".test')).to be_falsey expect(ValidateEmail.valid_local?('test."\".test')).to be_falsey end it 'returns true if special characters exist but are properly quoted and escaped' do expect(ValidateEmail.valid_local?('"\ test"')).to be_truthy expect(ValidateEmail.valid_local?('"\\\\"')).to be_truthy expect(ValidateEmail.valid_local?('test."te@st".test')).to be_truthy expect(ValidateEmail.valid_local?('test."\\\\\"".test')).to be_truthy expect(ValidateEmail.valid_local?('test."blah\"\ \\\\"')).to be_truthy end it 'returns true if all characters are within the set of allowed characters' do expect(ValidateEmail.valid_local?('!#$%&\'*+-/=?^_`{|}~."\\\\\ \"(),:;<>@[]"')).to be_truthy end end end valid-email-0.1.3/spec/spec_helper.rb0000644000175100017510000000022113661711707016501 0ustar pravipravi$:.unshift File.expand_path('../../lib',__FILE__) require 'valid_email' RSpec.configure do |config| config.raise_errors_for_deprecations! end valid-email-0.1.3/config/0000755000175100017510000000000013661711707014203 5ustar pravipravivalid-email-0.1.3/config/valid_email.yml0000644000175100017510000002252713661711707017204 0ustar pravipravidisposable_email_services: - 0-mail.com - 0815.ru - 0clickemail.com - 0wnd.net - 0wnd.org - 10minutemail.com - 20minutemail.com - 2prong.com - 30minutemail.com - 33mail.com - 3d-painting.com - 4warding.com - 4warding.net - 4warding.org - 60minutemail.com - 675hosting.com - 675hosting.net - 675hosting.org - 6paq.com - 6url.com - 75hosting.com - 75hosting.net - 75hosting.org - 7tags.com - 9ox.net - a-bc.net - acentri.com - afrobacon.com - ajaxapp.net - amail.club - amail4.me - amilegit.com - amiri.net - amiriindustries.com - anonbox.net - anonymbox.com - antichef.com - antichef.net - antispam.de - appixie.com - armyspy.com - azmeil.tk - banit.club - banit.me - baxomale.ht.cx - beefmilk.com - binkmail.com - bio-muesli.net - bobmail.info - bodhi.lawlita.com - bofthew.com - boun.cr - bouncr.com - brefmail.com - broadbandninja.com - bsnow.net - bugmenot.com - bumpymail.com - cars2.club - casualdx.com - centermail.com - centermail.net - chogmail.com - choicemail1.com - cmail.club - cool.fr.nf - correo.blogos.net - cosmorph.com - courriel.fr.nf - courrieltemporaire.com - cubiclink.com - curryworld.de - cust.in - cuvox.de - dacoolest.com - daddymail.biz - dandikmail.com - dayrep.com - deadaddress.com - deadspam.com - despam.it - despammed.com - devnullmail.com - dfgh.net - digitalsanctuary.com - discardmail.com - discardmail.de - disposableaddress.com - disposableemailaddresses.com - disposeamail.com - disposemail.com - dispostable.com - dm.w3internet.co.ukexample.com - dodgeit.com - dodgit.com - dodgit.org - donemail.ru - dontreg.com - dontsendmespam.de - drdrb.com - drdrb.net - droplar.com - duck2.club - dump-email.info - dumpandjunk.com - dumpmail.de - dumpyemail.com - e4ward.com - einrot.com - email60.com - emaildienst.de - emailias.com - emailigo.de - emailinfive.com - emailmiser.com - emailsensei.com - emailtemporario.com.br - emailto.de - emailwarden.com - emailx.at.hm - emailxfer.com - emeil.in - emeil.ir - emz.net - enterto.com - ephemail.net - etranquil.com - etranquil.net - etranquil.org - evopo.com - explodemail.com - fakeinbox.com - fakeinformation.com - fastacura.com - fastchevy.com - fastchrysler.com - fastkawasaki.com - fastmazda.com - fastmitsubishi.com - fastnissan.com - fastsubaru.com - fastsuzuki.com - fasttoyota.com - fastyamaha.com - filzmail.com - fizmail.com - fleckens.hu - fr33mail.info - frapmail.com - front14.org - fux0ringduh.com - garliclife.com - get1mail.com - get2mail.fr - getairmail.com - getnada.com - getonemail.com - getonemail.net - ghosttexter.de - girlsundertheinfluence.com - gishpuppy.com - gowikibooks.com - gowikicampus.com - gowikicars.com - gowikifilms.com - gowikigames.com - gowikimusic.com - gowikinetwork.com - gowikitravel.com - gowikitv.com - great-host.in - greensloth.com - grr.la - gsrv.co.uk - guerillamail.biz - guerillamail.com - guerillamail.net - guerillamail.org - guerrillamail.biz - guerrillamail.com - guerrillamail.de - guerrillamail.net - guerrillamail.org - guerrillamailblock.com - gustr.com - h.mintemail.com - h8s.org - haltospam.com - hatespam.org - hidemail.de - hochsitze.com - hotpop.com - hulapla.de - ieatspam.eu - ieatspam.info - ihateyoualot.info - iheartspam.org - imails.info - inbax.tk - inboxalias.com - inboxclean.com - inboxclean.org - incognitomail.com - incognitomail.net - incognitomail.org - insorg-mail.info - ipoo.org - irish2me.com - iwi.net - jetable.com - jetable.fr.nf - jetable.net - jetable.org - jnxjn.com - jourrapide.com - junk1e.com - kasmail.com - kaspop.com - keepmymail.com - killmail.com - killmail.net - kir.ch.tc - klassmaster.com - klassmaster.net - klzlk.com - koszmail.pl - kulturbetrieb.info - kurzepost.de - letthemeatspam.com - lhsdv.com - lifebyfood.com - link2mail.net - litedrop.com - lol.ovpn.to - lookugly.com - lopl.co.cc - lortemail.dk - lr78.com - m4ilweb.info - maboard.com - mail-temporaire.fr - mail.by - mail.mezimages.net - mail2rss.org - mail333.com - mail4trash.com - mailbidon.com - mailblocks.com - mailcatch.com - maildrop.cc - maileater.com - mailexpire.com - mailfa.tk - mailfreeonline.com - mailhazard.com - mailhazard.us - mailhz.me - mailin8r.com - mailinater.com - mailinator.com - mailinator.net - mailinator2.com - mailincubator.com - mailme.ir - mailme.lv - mailmetrash.com - mailmoat.com - mailnator.com - mailnesia.com - mailnull.com - mailshell.com - mailsiphon.com - mailslite.com - mailzilla.com - mailzilla.org - mbx.cc - mega.zik.dj - meinspamschutz.de - meltmail.com - messagebeamer.de - mierdamail.com - mintemail.com - moburl.com - moncourrier.fr.nf - monemail.fr.nf - monmail.fr.nf - msa.minsmail.com - mt2009.com - mx0.wwwnew.eu - mycleaninbox.net - mypartyclip.de - myphantomemail.com - myspaceinc.com - myspaceinc.net - myspaceinc.org - myspacepimpedup.com - myspamless.com - mytrashmail.com - nada.email - nada.ltd - neomailbox.com - nepwk.com - nervmich.net - nervtmich.net - netmails.com - netmails.net - netzidiot.de - neverbox.com - no-spam.ws - nobulk.com - noclickemail.com - nogmailspam.info - nomail.xl.cx - nomail2me.com - nomorespamemails.com - nospam.ze.tc - nospam4.us - nospamfor.us - nospamthanks.info - notmailinator.com - nowmymail.com - nurfuerspam.de - nus.edu.sg - nwldx.com - objectmail.com - obobbo.com - oneoffemail.com - onewaymail.com - online.ms - oopi.org - ordinaryamerican.net - otherinbox.com - ourklips.com - outlawspam.com - ovpn.to - owlpic.com - pancakemail.com - paplease.com - pimpedupmyspace.com - pjjkp.com - politikerclub.de - poofy.org - pookmail.com - privacy.net - proxymail.eu - prtnx.com - punkass.com - putthisinyourspamdatabase.com - qq.com - quickinbox.com - rcpt.at - recode.me - recursor.net - regbypass.com - regbypass.comsafe-mail.net - rejectmail.com - rhyta.com - rklips.com - rmqkr.net - rppkn.com - rtrtr.com - s0ny.net - safe-mail.net - safersignup.de - safetymail.info - safetypost.de - sandelf.de - saynotospams.com - selfdestructingmail.com - sendspamhere.com - sharklasers.com - shiftmail.com - shitmail.me - shortmail.net - sibmail.com - skeefmail.com - slaskpost.se - slopsbox.com - smellfear.com - snakemail.com - sneakemail.com - sofimail.com - sofort-mail.de - sogetthis.com - soodonims.com - spam.la - spam.su - spam4.me - spamavert.com - spambob.com - spambob.net - spambob.org - spambog.com - spambog.de - spambog.ru - spambox.info - spambox.irishspringrealty.com - spambox.us - spamcannon.com - spamcannon.net - spamcero.com - spamcon.org - spamcorptastic.com - spamcowboy.com - spamcowboy.net - spamcowboy.org - spamday.com - spamex.com - spamfree24.com - spamfree24.de - spamfree24.eu - spamfree24.info - spamfree24.net - spamfree24.org - spamgourmet.com - spamgourmet.net - spamgourmet.org - spamherelots.com - spamhereplease.com - spamhole.com - spamify.com - spaminator.de - spamkill.info - spaml.com - spaml.de - spammotel.com - spamobox.com - spamoff.de - spamslicer.com - spamspot.com - spamthis.co.uk - spamthisplease.com - spamtrail.com - speed.1s.fr - supergreatmail.com - supermailer.jp - superrito.com - suremail.info - tagyourself.com - teewars.org - teleworm.com - teleworm.us - tempalias.com - tempe-mail.com - tempemail.biz - tempemail.com - tempemail.net - tempinbox.co.uk - tempinbox.com - tempmail.it - tempmail2.com - tempomail.fr - temporarily.de - temporarioemail.com.br - temporaryemail.net - temporaryforwarding.com - temporaryinbox.com - thanksnospam.info - thankyou2010.com - thisisnotmyrealemail.com - throwawayemailaddress.com - tilien.com - tmailinator.com - tradermail.info - trash-amil.com - trash-mail.at - trash-mail.com - trash-mail.de - trash2009.com - trashemail.de - trashmail.at - trashmail.com - trashmail.de - trashmail.me - trashmail.net - trashmail.org - trashmail.ws - trashmailer.com - trashymail.com - trashymail.net - trbvm.com - trillianpro.com - turual.com - twinmail.de - tyldd.com - uggsrock.com - upliftnow.com - uplipht.com - venompen.com - veryrealemail.com - viditag.com - viewcastmedia.com - viewcastmedia.net - viewcastmedia.org - webm4il.info - wegwerfadresse.de - wegwerfemail.de - wegwerfmail.de - wegwerfmail.net - wegwerfmail.org - wetrainbayarea.com - wetrainbayarea.org - wh4f.org - whatpaas.com - whyspam.me - willselfdestruct.com - winemaven.info - wmail.club - wronghead.com - wuzup.net - wuzupmail.net - wwwnew.eu - xagloo.com - xemaps.com - xents.com - xmaily.com - xoxy.net - yep.it - yogamaven.com - yopmail.com - yopmail.fr - yopmail.net - ypmail.webarnak.fr.eu.org - yuurok.com - zebins.com - zebins.eu - zehnminutenmail.de - zippymail.info - zoaxe.com - zoemail.org - valid-email-0.1.3/config/locales/0000755000175100017510000000000013661711707015625 5ustar pravipravivalid-email-0.1.3/config/locales/sv.yml0000644000175100017510000000012013661711707016771 0ustar pravipravisv: valid_email: validations: email: invalid: "är ogiltig" valid-email-0.1.3/config/locales/uk.yml0000644000175100017510000000015213661711707016765 0ustar pravipraviuk: valid_email: validations: email: invalid: "неправильний формат" valid-email-0.1.3/config/locales/id.yml0000644000175100017510000000012013661711707016735 0ustar pravipraviid: valid_email: validations: email: invalid: "tidak valid" valid-email-0.1.3/config/locales/fi.yml0000644000175100017510000000012513661711707016744 0ustar pravipravifi: valid_email: validations: email: invalid: ei ole kelvollinen valid-email-0.1.3/config/locales/de.yml0000644000175100017510000000012213661711707016733 0ustar pravipravide: valid_email: validations: email: invalid: "ist ungültig" valid-email-0.1.3/config/locales/hu.yml0000644000175100017510000000013513661711707016763 0ustar pravipravihu: valid_email: validations: email: invalid: "érvénytelen email cím" valid-email-0.1.3/config/locales/en.yml0000644000175100017510000000011713661711707016751 0ustar pravipravien: valid_email: validations: email: invalid: "is invalid" valid-email-0.1.3/config/locales/ru.yml0000644000175100017510000000015113661711707016773 0ustar pravipraviru: valid_email: validations: email: invalid: "неправильный формат"valid-email-0.1.3/config/locales/pl.yml0000644000175100017510000000013013661711707016755 0ustar pravipravipl: valid_email: validations: email: invalid: "jest nieprawidłowy" valid-email-0.1.3/config/locales/fr.yml0000644000175100017510000000012113661711707016751 0ustar pravipravifr: valid_email: validations: email: invalid: "est invalide" valid-email-0.1.3/config/locales/ja.yml0000644000175100017510000000012713661711707016742 0ustar pravipravija: valid_email: validations: email: invalid: "不正な値です" valid-email-0.1.3/config/locales/nb.yml0000644000175100017510000000011713661711707016746 0ustar pravipravinb: valid_email: validations: email: invalid: "er ugyldig" valid-email-0.1.3/config/locales/pt-BR.yml0000644000175100017510000000012413661711707017271 0ustar pravipravipt-BR: valid_email: validations: email: invalid: "é inválido" valid-email-0.1.3/History.md0000644000175100017510000000061313661711707014721 0ustar pravipravi 0.1.0 / 2017-09-27 ================== * #86 Change dependency on mail to >= 2.6.1 * #85 adding disposable email domains from getnada * #84 ValidateEmail.valid?: make domain validation true by default * #83 Allow to configure timeouts for dns * #82 Travis CI. Support for more Ruby versions * #80 rescue Mail::Field::ParseError also in domain_valid? * #78 Added pt-BR translation valid-email-0.1.3/lib/0000755000175100017510000000000013661711707013504 5ustar pravipravivalid-email-0.1.3/lib/valid_email.rb0000644000175100017510000000047213661711707016302 0ustar pravipravirequire 'valid_email/all' I18n.load_path += Dir.glob(File.expand_path('../../config/locales/**/*',__FILE__)) # Load list of disposable email domains config = File.expand_path('../../config/valid_email.yml',__FILE__) BanDisposableEmailValidator.config= YAML.load_file(config)['disposable_email_services'] rescue [] valid-email-0.1.3/lib/valid_email/0000755000175100017510000000000013661711707015752 5ustar pravipravivalid-email-0.1.3/lib/valid_email/mx_validator.rb0000644000175100017510000000074013661711707020771 0ustar pravipravirequire 'active_model' require 'active_model/validations' require 'resolv' require 'valid_email/validate_email' class MxValidator < ActiveModel::EachValidator def self.config @@config = { timeouts: [] } unless defined? @@config @@config end def validate_each(record,attribute,value) r = ValidateEmail.mx_valid?(value) record.errors.add attribute, (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) unless r r end end valid-email-0.1.3/lib/valid_email/ban_disposable_email_validator.rb0000644000175100017510000000114313661711707024457 0ustar pravipravirequire 'active_model' require 'active_model/validations' require 'valid_email/validate_email' class BanDisposableEmailValidator < ActiveModel::EachValidator # A list of disposable email domains def self.config=(options) @@config = options end # Required to use config outside def self.config @@config = [] unless defined? @@config @@config end def validate_each(record, attribute, value) r = ValidateEmail.ban_disposable_email?(value) record.errors.add attribute, (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) unless r r end end valid-email-0.1.3/lib/valid_email/version.rb0000644000175100017510000000003413661711707017761 0ustar pravipraviValidEmailVersion = "0.1.3" valid-email-0.1.3/lib/valid_email/domain_validator.rb0000644000175100017510000000057313661711707021620 0ustar pravipravirequire 'active_model' require 'active_model/validations' require 'valid_email/validate_email' class DomainValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) r = ValidateEmail.domain_valid?(value) record.errors.add attribute, (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) unless r r end end valid-email-0.1.3/lib/valid_email/validate_email.rb0000644000175100017510000000766013661711707021250 0ustar pravipravirequire 'mail' class ValidateEmail class << self SPECIAL_CHARS = %w(( ) , : ; < > @ [ ]) SPECIAL_ESCAPED_CHARS = %w(\ \\ ") LOCAL_MAX_LEN = 64 DOMAIN_REGEX = /\A(?:[[:alnum:]](?:[[[:alnum:]]-]{0,61}[[:alnum:]])?)(?:\.(?:[[:alnum:]](?:[[[:alnum:]]-]{0,61}[[:alnum:]])?))+\z/ def valid?(value, user_options={}) options = { :mx => false, :domain => true, :message => nil }.merge(user_options) m = Mail::Address.new(value) # We must check that value contains a domain and that value is an email address return false unless m.domain && m.address == value # Check that domain consists of dot-atom-text elements > 1 and does not # contain spaces. # # In mail 2.6.1, domains are invalid per rfc2822 are parsed when they shouldn't # This is to make sure we cover those cases return false unless m.domain.match(/^\S+$/) domain_dot_elements = m.domain.split(/\./) return false unless domain_dot_elements.size > 1 && !domain_dot_elements.any?(&:empty?) # Ensure that the local segment adheres to adheres to RFC-5322 return false unless valid_local?(m.local) # Check if domain has DNS MX record if options[:mx] require 'valid_email/mx_validator' return mx_valid?(value) end if options[:domain] require 'valid_email/domain_validator' return domain_valid?(value) end true rescue Mail::Field::ParseError false rescue ArgumentError => error if error.message == 'bad value for range' false else raise error end end def valid_local?(local) return false unless local.length <= LOCAL_MAX_LEN # Emails can be validated by segments delineated by '.', referred to as dot atoms. # See http://tools.ietf.org/html/rfc5322#section-3.2.3 return local.split('.', -1).all? { |da| valid_dot_atom?(da) } end def valid_dot_atom?(dot_atom) # Leading, trailing, and double '.'s aren't allowed return false if dot_atom.empty? # A dot atom can be quoted, which allows use of the SPECIAL_CHARS if dot_atom[0] == '"' || dot_atom[-1] == '"' # A quoted segment must have leading and trailing '"#"'s return false if dot_atom[0] != dot_atom[-1] # Excluding the bounding quotes, all of the SPECIAL_ESCAPED_CHARS must have a leading '\' index = dot_atom.length - 2 while index > 0 if SPECIAL_ESCAPED_CHARS.include? dot_atom[index] return false if index == 1 || dot_atom[index - 1] != '\\' # On an escaped special character, skip an index to ignore the '\' that's doing the escaping index -= 1 end index -= 1 end else # If we're not in a quoted dot atom then no special characters are allowed. return false unless ((SPECIAL_CHARS | SPECIAL_ESCAPED_CHARS) & dot_atom.split('')).empty? end return true end def mx_valid?(value, fallback=false) m = Mail::Address.new(value) return false unless m.domain Resolv::DNS.open do |dns| dns.timeouts = MxValidator.config[:timeouts] unless MxValidator.config[:timeouts].empty? return dns.getresources(m.domain, Resolv::DNS::Resource::IN::MX).size > 0 || ( fallback && dns.getresources(m.domain, Resolv::DNS::Resource::IN::A).size > 0 ) end rescue Mail::Field::ParseError false end def mx_valid_with_fallback?(value) mx_valid?(value, true) end def domain_valid?(value) m = Mail::Address.new(value) return false unless m.domain !(m.domain =~ DOMAIN_REGEX).nil? rescue Mail::Field::ParseError false end def ban_disposable_email?(value) m = Mail::Address.new(value) m.domain && !BanDisposableEmailValidator.config.include?(m.domain) rescue Mail::Field::ParseError false end end end valid-email-0.1.3/lib/valid_email/mx_with_fallback_validator.rb0000644000175100017510000000056213661711707023645 0ustar pravipravirequire 'valid_email/mx_validator' require 'valid_email/validate_email' class MxWithFallbackValidator < ActiveModel::EachValidator def validate_each(record,attribute,value) r = ValidateEmail.mx_valid_with_fallback?(value) record.errors.add attribute, (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) unless r r end end valid-email-0.1.3/lib/valid_email/all_with_extensions.rb0000644000175100017510000000025613661711707022364 0ustar pravipravirequire 'valid_email' class String def email?(options={}) ValidateEmail.valid?(self, options) end end class NilClass def email?(options={}) false end endvalid-email-0.1.3/lib/valid_email/all.rb0000644000175100017510000000037313661711707017052 0ustar pravipravirequire 'valid_email/validate_email' require 'valid_email/email_validator' require 'valid_email/mx_validator' require 'valid_email/mx_with_fallback_validator' require 'valid_email/ban_disposable_email_validator' require 'valid_email/domain_validator' valid-email-0.1.3/lib/valid_email/email_validator.rb0000644000175100017510000000224513661711707021436 0ustar pravipravirequire 'active_model' require 'active_model/validations' require 'valid_email/validate_email' class EmailValidator < ActiveModel::EachValidator def validate_each(record,attribute,value) return if options[:allow_nil] && value.nil? return if options[:allow_blank] && value.blank? r = ValidateEmail.valid?(value) # Check if domain has DNS MX record if r && options[:mx] require 'valid_email/mx_validator' r = MxValidator.new(:attributes => attributes, message: options[:message]).validate(record) elsif r && options[:mx_with_fallback] require 'valid_email/mx_with_fallback_validator' r = MxWithFallbackValidator.new(:attributes => attributes, message: options[:message]).validate(record) end # Check if domain is disposable if r && options[:ban_disposable_email] require 'valid_email/ban_disposable_email_validator' r = BanDisposableEmailValidator.new(:attributes => attributes, message: options[:message]).validate(record) end unless r msg = (options[:message] || I18n.t(:invalid, :scope => "valid_email.validations.email")) record.errors.add attribute, (msg % {value: value}) end end end valid-email-0.1.3/README.md0000644000175100017510000000741613661711707014225 0ustar pravipravi# Purpose It validates email for application use (registering a new account for example) # Usage In your Gemfile : gem 'valid_email' In your code : require 'valid_email' class Person include ActiveModel::Validations attr_accessor :name, :email validates :name, :presence => true, :length => { :maximum => 100 } validates :email, :presence => true, :email => true end p = Person.new p.name = "hallelujah" p.email = "john@doe.com" p.valid? # => true p.email = "john@doe" p.valid? # => false p.email = "John Does " p.valid? # => false You can check if email domain has MX record: validates :email, :email => {:mx => true, :message => I18n.t('validations.errors.models.user.invalid_email')} Or validates :email, :email => {:message => I18n.t('validations.errors.models.user.invalid_email')}, :mx => {:message => I18n.t('validations.errors.models.user.invalid_mx')} By default, the email domain is validated using a regular expression, which does not require an external service and improves performance. Alternatively, you can check if an email domain has a MX or A record by using `:mx_with_fallback` instead of `:mx`. validates :email, :email => {:mx_with_fallback => true} You can detect disposable accounts validates :email, :email => {:ban_disposable_email => true, :message => I18n.t('validations.errors.models.user.invalid_email')} If you don't want the MX validator stuff, just require the right file require 'valid_email/email_validator' Or in your Gemfile gem 'valid_email', :require => 'valid_email/email_validator' ### Usage outside of model validation There is a chance that you want to use e-mail validator outside of model validation. If that's the case, you can use the following methods: ```ruby ValidateEmail.valid?('email@randommail.com') # You can optionally pass a hash of options, same as validator ValidateEmail.mx_valid?('email@randommail.com') ValidateEmail.mx_valid_with_fallback?('email@randommail.com') ValidateEmail.valid?('email@randommail.com') ``` Load it (and not the rails extensions) with gem 'valid_email', require: 'valid_email/validate_email' ### String and Nil object extensions There is also a String and Nil class extension, if you require the gem in this way in Gemfile: ```ruby gem 'valid_email', require: ['valid_email/all_with_extensions'] ``` You will be able to use the following methods: ```ruby nil.email? # => false "john@gmail.com".email? # => May return true if it exists. It accepts a hash of options like ValidateEmail.valid? ``` ## Code Status * [![Build Status](https://travis-ci.org/hallelujah/valid_email.svg?branch=master)](https://travis-ci.org/hallelujah/valid_email) # Credits * Ramihajamalala Hery hery[at]rails-royce.org * Fire-Dragon-DoL francesco.belladonna[at]gmail.com * dush dusanek[at]iquest.cz * MIke Carter mike[at]mcarter.me * Heng heng[at]reamaze.com * Marco Perrando mperrando[at]soluzioninrete.it * Jörg Thalheim joerg[at]higgsboson.tk * Andrey Deryabin deriabin[at]gmail.com * Nicholas Rutherford nick.rutherford[at]gmail.com * Oleg Shur workshur[at]gmail.com * Joel Chippindale joel[at]joelchippindale.com * Sami Haahtinen sami[at]haahtinen.name * Jean Boussier jean.boussier[at]gmail.com * Masaki Hara - @qnighy # Note on Patches/Pull Requests * Fork the project. * Make your feature addition or bug fix. * Add tests for it. This is important so I don’t break it in a future version unintentionally. * Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) * Send me a pull request. Bonus points for topic branches. # Copyright Copyright © 2011 Ramihajamalala Hery. See LICENSE for details valid-email-0.1.3/.travis.yml0000644000175100017510000000030413661711707015044 0ustar pravipravisudo: false language: ruby cache: bundler rvm: - 1.9.3 - 2.0.0 - 2.1 - 2.2.1 - 2.2.2 - 2.3.3 - 2.4.0 - jruby-19mode - jruby-20mode before_install: - gem install bundler:1.17.3 valid-email-0.1.3/valid_email.gemspec0000644000175100017510000000233713661711707016556 0ustar pravipravi# -*- encoding: utf-8 -*- $:.push File.expand_path("../lib", __FILE__) require "valid_email/version" Gem::Specification.new do |s| s.name = "valid_email" s.version = ValidEmailVersion s.authors = ["Ramihajamalala Hery"] s.email = ["hery@rails-royce.org"] s.homepage = "https://github.com/hallelujah/valid_email" s.summary = %q{ActiveModel Validation for email} s.description = %q{ActiveModel Validation for email} s.license = 'MIT' s.rubyforge_project = "valid_email" s.files = `git ls-files`.split("\n") s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) } s.require_paths = ["lib"] # specify any dependencies here; for example: s.add_development_dependency "rspec", "~> 2.99" s.add_development_dependency "rake", '< 11.0' s.add_runtime_dependency "mail", ">= 2.6.1" if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('2.0') s.add_runtime_dependency 'mime-types', '<= 2.6.2' end if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2') s.add_runtime_dependency "activemodel", '< 5.0.0' else s.add_runtime_dependency "activemodel" end end valid-email-0.1.3/Gemfile0000644000175100017510000000014313661711707014227 0ustar pravipravisource "http://rubygems.org" # Specify your gem's dependencies in email_validator.gemspec gemspec valid-email-0.1.3/LICENSE0000644000175100017510000000206413661711707013745 0ustar pravipraviCopyright (c) 2011 hallelujah [Ramihajamalala Hery] Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.