Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ gem 'csv' # LOCKED: csv was loaded from the standard library, but is not part of
gem 'delayed_job'
gem 'delayed_job_active_record'
gem 'drb' # LOCKED: Added because of pry-remote
gem 'email_validator'
gem 'font_awesome5_rails'
gem 'bootstrap', '~> 5'
gem 'friendly_id'
Expand Down
3 changes: 3 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,8 @@ GEM
dotenv (= 3.2.0)
railties (>= 6.1)
drb (2.2.3)
email_validator (2.2.4)
activemodel
erb (6.0.2)
erubi (1.13.1)
execjs (2.10.1)
Expand Down Expand Up @@ -635,6 +637,7 @@ DEPENDENCIES
delayed_job_active_record
dotenv-rails
drb
email_validator
fabrication
faker
faraday
Expand Down
9 changes: 9 additions & 0 deletions app/helpers/email_header_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,19 @@ module EmailHeaderHelper
private

def mail_args(member, subject, from_email = 'meetings@codebar.io', cc = '', bcc = '')
return nil if invalid_email?(member.email, member.id)

{ from: "codebar.io <#{from_email}>",
to: member.email,
cc: cc,
bcc: bcc,
subject: subject }
end

def invalid_email?(email, member_id)
return false if EmailValidator.valid?(email, mode: :strict)

Rails.logger.warn("[EmailHeaderHelper] Invalid email for member_id=#{member_id}: #{email}")
true
end
end
1 change: 1 addition & 0 deletions app/models/member.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class Member < ApplicationRecord
validates :auth_services, presence: true
validates :name, :surname, :email, :about_you, presence: true, if: :can_log_in?
validates :email, uniqueness: true
validates :email, email: { mode: :strict }, if: :can_log_in?
validates :about_you, length: { maximum: 255 }

DIETARY_RESTRICTIONS = %w[vegan vegetarian pescetarian halal gluten_free dairy_free other].freeze
Expand Down
60 changes: 60 additions & 0 deletions spec/helpers/email_header_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
RSpec.describe EmailHeaderHelper, type: :helper do
before { EmailHeaderHelper.module_eval { public :mail_args } }

describe '#mail_args' do
let(:member) { Struct.new(:id, :email).new(1, 'test@example.com') }

it 'returns mail arguments for valid email' do
result = helper.mail_args(member, 'Test Subject')
expect(result[:to]).to eq('test@example.com')
expect(result[:subject]).to eq('Test Subject')
end

it 'returns nil for nil email' do
member = Struct.new(:id, :email).new(1, nil)
result = helper.mail_args(member, 'Test Subject')
expect(result).to be_nil
end

it 'returns nil for blank email' do
member = Struct.new(:id, :email).new(1, '')
result = helper.mail_args(member, 'Test Subject')
expect(result).to be_nil
end

it 'returns nil for invalid email format' do
member = Struct.new(:id, :email).new(1, 'invalid-email')
result = helper.mail_args(member, 'Test Subject')
expect(result).to be_nil
end

it 'returns nil for email missing @ symbol' do
member = Struct.new(:id, :email).new(1, 'invalidexample.com')
result = helper.mail_args(member, 'Test Subject')
expect(result).to be_nil
end

it 'returns nil for email missing TLD' do
member = Struct.new(:id, :email).new(1, 'invalid@example')
result = helper.mail_args(member, 'Test Subject')
expect(result).to be_nil
end

it 'returns mail arguments for valid email with plus addressing' do
member = Struct.new(:id, :email).new(1, 'user+tag@example.com')
result = helper.mail_args(member, 'Test Subject')
expect(result[:to]).to eq('user+tag@example.com')
end

it 'includes from email when provided' do
result = helper.mail_args(member, 'Test Subject', 'custom@codebar.io')
expect(result[:from]).to eq('codebar.io <custom@codebar.io>')
end

it 'includes cc and bcc when provided' do
result = helper.mail_args(member, 'Test Subject', 'from@codebar.io', 'cc@codebar.io', 'bcc@codebar.io')
expect(result[:cc]).to eq('cc@codebar.io')
expect(result[:bcc]).to eq('bcc@codebar.io')
end
end
end
31 changes: 31 additions & 0 deletions spec/models/member_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,37 @@
it { expect(member).to validate_presence_of(:surname) }
it { expect(member).to validate_presence_of(:email) }
it { expect(member).to validate_presence_of(:about_you) }

it 'accepts valid email format' do
member.email = 'valid@example.com'
expect(member).to be_valid
end

it 'rejects invalid email format' do
member.email = 'invalid-email'
expect(member).not_to be_valid
expect(member.errors[:email]).to include('is invalid')
end

it 'rejects email missing @ symbol' do
member.email = 'invalidexample.com'
expect(member).not_to be_valid
end

it 'rejects email missing TLD' do
member.email = 'invalid@example'
expect(member).not_to be_valid
end

it 'accepts email with valid subdomains' do
member.email = 'user@mail.example.com'
expect(member).to be_valid
end

it 'accepts email with plus addressing' do
member.email = 'user+tag@example.com'
expect(member).to be_valid
end
end
end

Expand Down