Skip to content

Instantly share code, notes, and snippets.

@phawk
Created June 19, 2023 18:06
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save phawk/6d067103a059109358f74bb9696f5aad to your computer and use it in GitHub Desktop.
Save phawk/6d067103a059109358f74bb9696f5aad to your computer and use it in GitHub Desktop.
Disposable email validation in Rails
# lib/tasks/disposable_email.rake
namespace :disposable_email do
desc "Downloads the latest list of disposable emails"
task download: :environment do
data = HTTP.get("https://disposable.github.io/disposable-email-domains/domains.txt").to_s
path = Rails.root.join("data/disposable_email_domains.txt")
File.open(path, "w") do |file|
file.write(data)
end
end
end
# app/services/disposable_email_service.rb
module DisposableEmailService
module_function
def disposable?(email_address)
email = Mail::Address.new(email_address.downcase) rescue nil
if email
disposable_email_domains.include?(email.domain)
else
return false
end
end
def disposable_email_domains
@_disposable_email_domains ||= File.readlines(Rails.root.join("data", "disposable_email_domains.txt")).map(&:strip)
end
end
# spec/services/disposable_email_service_spec.rb
require "rails_helper"
RSpec.describe DisposableEmailService do
describe "#disposable?(email)" do
it "returns false when the email domain is NOT disposable" do
expect(described_class.disposable?("hi@rapidruby.com")).to be(false)
end
it "returns true when the email domain is disposable" do
expect(described_class.disposable?("info@zzz-xxx.com")).to be(true)
end
end
end
# app/validators/disposable_email_validator.rb
class DisposableEmailValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
if DisposableEmailService.disposable?(value)
record.errors.add(attribute, (options[:message] || "is a disposable email address and is banned"))
end
end
end
# app/models/user.rb
class User < ApplicationRecord
validates :email, disposable_email: true, presence: true, uniqueness: true, format: { with: URI::MailTo::EMAIL_REGEXP }
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment