diff --git a/README.md b/README.md index 3462b98..df51c22 100644 --- a/README.md +++ b/README.md @@ -34,6 +34,24 @@ Optionally prefix the subject line: subject_prefix: '[STAGING]' ) +Optionally white-list emails: + + Mail.register_interceptor RecipientInterceptor.new( + ENV['EMAIL_RECIPIENTS'], + email_whitelist: ['whitelisted@example.com'] + ) + +Optionally white-list domains: + + Mail.register_interceptor RecipientInterceptor.new( + ENV['EMAIL_RECIPIENTS'], + domain_whitelist: ['example.com'] + ) + +Note: If one or more of the original recipients match the email white-list or domain white-list, +the email's to field will not be overridden. However, non-white-listed emails will be removed from +the email's to field. + Credits ------- diff --git a/lib/recipient_interceptor.rb b/lib/recipient_interceptor.rb index a408603..9989a02 100644 --- a/lib/recipient_interceptor.rb +++ b/lib/recipient_interceptor.rb @@ -1,15 +1,18 @@ require 'mail' class RecipientInterceptor + def initialize(recipients, options = {}) @recipients = normalize_to_array(recipients) + @email_whitelist = options[:email_whitelist] || [] + @domain_whitelist = options[:domain_whitelist] || [] @subject_prefix = options[:subject_prefix] end def delivering_email(message) add_custom_headers message add_subject_prefix message - message.to = @recipients + message.to = sanitize_recipients(message) message.cc = [] message.bcc = [] end @@ -41,4 +44,25 @@ def add_custom_headers(message) end end end + + def sanitize_recipients(message) + recipients = message.to + sanitized_recipients = recipients.select { |email| whitelisted?(email) } + sanitized_recipients.any? ? sanitized_recipients : @recipients + end + + def whitelisted?(email) + whitelisted_email?(email) || whitelisted_domain?(email) + end + + def whitelisted_email?(email) + @email_whitelist.include?(email) + end + + def whitelisted_domain?(email) + @domain_whitelist.any? do |domain| + email =~ /@#{domain}$/ + end + end + end diff --git a/spec/recipient_interceptor_spec.rb b/spec/recipient_interceptor_spec.rb index 64f9ee2..debfad4 100644 --- a/spec/recipient_interceptor_spec.rb +++ b/spec/recipient_interceptor_spec.rb @@ -40,6 +40,98 @@ expect(response.to).to eq [recipient_string] end + context 'given an email white-list' do + context 'for emails with one recipient' do + it 'does not override the to field for a white-listed email' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + email_whitelist: ['original@whitelisted.com'] + ) + + response = deliver_mail to: 'original@whitelisted.com' + expect(response.to).to eq ['original@whitelisted.com'] + end + + it 'overrides the to field for a non-white-listed email' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + email_whitelist: ['original@whitelisted.com'] + ) + + response = deliver_mail to: 'original@blacklisted.com' + expect(response.to).to eq ['override@whitelisted.com'] + end + end + + context 'for emails with multiple recipients' do + it 'strips non-white-listed emails, leaving white-listed ones' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + email_whitelist: ['original@whitelisted.com'] + ) + + response = deliver_mail to: ['original@whitelisted.com', 'other@whitelisted.com'] + expect(response.to).to eq ['original@whitelisted.com'] + end + + it 'replaces all recipients when none is white-listed' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + email_whitelist: ['original@whitelisted.com'] + ) + + response = deliver_mail to: ['original@blacklisted.com', 'other@whitelisted.com'] + expect(response.to).to eq ['override@whitelisted.com'] + end + end + end + + context 'given an domain white-list' do + context 'for emails with one recipient' do + it 'does not override the to field for a white-listed email' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + domain_whitelist: ['whitelisted.com'] + ) + + response = deliver_mail to: 'original@whitelisted.com' + expect(response.to).to eq ['original@whitelisted.com'] + end + + it 'overrides the to field for a non-white-listed email' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + domain_whitelist: ['whitelisted.com'] + ) + + response = deliver_mail to: 'original@blacklisted.com' + expect(response.to).to eq ['override@whitelisted.com'] + end + end + + context 'for emails with multiple recipients' do + it 'strips non-white-listed emails, leaving white-listed ones' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + domain_whitelist: ['whitelisted.com'] + ) + + response = deliver_mail to: ['original@whitelisted.com', 'other@whitelisted.com', 'other@blacklisted.com'] + expect(response.to).to eq ['original@whitelisted.com', 'other@whitelisted.com'] + end + + it 'replaces all recipients when none is white-listed' do + Mail.register_interceptor RecipientInterceptor.new( + 'override@whitelisted.com', + domain_whitelist: ['whitelisted.com'] + ) + + response = deliver_mail to: ['original@blacklisted.com', 'other@blacklisted.com'] + expect(response.to).to eq ['override@whitelisted.com'] + end + end + end + it 'does not prefix subject by default' do Mail.register_interceptor RecipientInterceptor.new(recipient_string) @@ -67,17 +159,17 @@ def recipient_array ['one@example.com', 'two@example.com'] end - def deliver_mail + def deliver_mail(options = {}) Mail.defaults do delivery_method :test end Mail.deliver do - from 'original.from@example.com' - to 'original.to@example.com' - cc 'original.cc@example.com' - bcc 'original.bcc@example.com' - subject 'some subject' + from options.fetch(:from, 'original.from@example.com') + to options.fetch(:to, 'original.to@example.com') + cc options.fetch(:cc, 'original.cc@example.com') + bcc options.fetch(:bcc, 'original.bcc@example.com') + subject options.fetch(:subject, 'some subject') end end