feat: block free email provider signups
Mirrors the existing client-side check in the v3 signup form (company-email-validator via Vuelidate) so non-business emails can no longer slip in via Google OAuth, direct API calls, or any other path that bypassed the form. The deny list ships as config/deny_listed_email_domains.yml — picked up automatically by ValidEmail2 — and is trimmed to the 6.5k consumer-only domains the gem's disposable list doesn't already cover.
This commit is contained in:
@@ -17,6 +17,8 @@ class Account::SignUpEmailValidationService
|
||||
|
||||
raise InvalidEmail.new({ valid: true, disposable: true }) if address.disposable?
|
||||
|
||||
raise InvalidEmail.new({ free_email_provider: true }) if address.deny_listed?
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -60,6 +60,7 @@ en:
|
||||
signup:
|
||||
disposable_email: We do not allow disposable emails
|
||||
blocked_domain: This domain is not allowed. If you believe this is a mistake, please contact support.
|
||||
free_email_provider: Please sign up with your work email address.
|
||||
invalid_email: You have entered an invalid email
|
||||
email_already_exists: 'You have already signed up for an account with %{email}'
|
||||
invalid_params: 'Invalid, please check the signup paramters and try again'
|
||||
|
||||
@@ -7,6 +7,8 @@ module CustomExceptions::Account
|
||||
I18n.t 'errors.signup.blocked_domain'
|
||||
elsif @data[:disposable]
|
||||
I18n.t 'errors.signup.disposable_email'
|
||||
elsif @data[:free_email_provider]
|
||||
I18n.t 'errors.signup.free_email_provider'
|
||||
elsif !@data[:valid]
|
||||
I18n.t 'errors.signup.invalid_email'
|
||||
end
|
||||
|
||||
@@ -5,7 +5,8 @@ require 'rails_helper'
|
||||
RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
||||
let(:service) { described_class.new(email) }
|
||||
let(:blocked_domains) { "gmail.com\noutlook.com" }
|
||||
let(:valid_email_address) { instance_double(ValidEmail2::Address, valid?: true, disposable?: false) }
|
||||
let(:valid_email_address) { instance_double(ValidEmail2::Address, valid?: true, disposable?: false, deny_listed?: false) }
|
||||
let(:free_provider_email_address) { instance_double(ValidEmail2::Address, valid?: true, disposable?: false, deny_listed?: true) }
|
||||
let(:disposable_email_address) { instance_double(ValidEmail2::Address, valid?: true, disposable?: true) }
|
||||
let(:invalid_email_address) { instance_double(ValidEmail2::Address, valid?: false) }
|
||||
|
||||
@@ -62,9 +63,21 @@ RSpec.describe Account::SignUpEmailValidationService, type: :service do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when email is valid business email' do
|
||||
context 'when email is from a free provider' do
|
||||
let(:email) { 'test@example.com' }
|
||||
|
||||
it 'raises InvalidEmail with free email provider message' do
|
||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(free_provider_email_address)
|
||||
expect { service.perform }.to raise_error do |error|
|
||||
expect(error.class.name).to eq('CustomExceptions::Account::InvalidEmail')
|
||||
expect(error.message).to eq(I18n.t('errors.signup.free_email_provider'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when email is valid business email' do
|
||||
let(:email) { 'test@chatwoot.com' }
|
||||
|
||||
it 'returns true' do
|
||||
allow(ValidEmail2::Address).to receive(:new).with(email).and_return(valid_email_address)
|
||||
expect(service.perform).to be(true)
|
||||
|
||||
Reference in New Issue
Block a user