 ### Snyk has created this PR to fix 1 vulnerabilities in the rubygems dependencies of this project. #### Snyk changed the following file(s): - `Gemfile` <details> <summary>⚠️ <b>Warning</b></summary> ``` Failed to update the Gemfile.lock, please update manually before merging. ``` </details> #### Vulnerabilities that will be fixed with an upgrade: | | Issue | Score | :-------------------------:|:-------------------------|:-------------------------  | Web Cache Poisoning <br/>[SNYK-RUBY-RACK-1061917](https://snyk.io/vuln/SNYK-RUBY-RACK-1061917) | **616** --- > [!IMPORTANT] > > - Check the changes in this PR to ensure they won't cause issues with your project. > - Max score is 1000. Note that the real score may have changed since the PR was raised. > - This PR was automatically created by Snyk using the credentials of a real user. --- **Note:** _You are seeing this because you or someone else with access to this repository has authorized Snyk to open fix PRs._ For more information: <img src="https://api.segment.io/v1/pixel/track?data=eyJ3cml0ZUtleSI6InJyWmxZcEdHY2RyTHZsb0lYd0dUcVg4WkFRTnNCOUEwIiwiYW5vbnltb3VzSWQiOiJhMWE2MzkzZS03ODdhLTRmYWItOGY1MS0zZjdmN2YzNzVlZDYiLCJldmVudCI6IlBSIHZpZXdlZCIsInByb3BlcnRpZXMiOnsicHJJZCI6ImExYTYzOTNlLTc4N2EtNGZhYi04ZjUxLTNmN2Y3ZjM3NWVkNiJ9fQ==" width="0" height="0"/> 🧐 [View latest project report](https://app.snyk.io/org/chatwoot/project/b7197bbd-6200-4f23-931d-c39928584360?utm_source=github&utm_medium=referral&page=fix-pr) 📜 [Customise PR templates](https://docs.snyk.io/scan-using-snyk/pull-requests/snyk-fix-pull-or-merge-requests/customize-pr-templates) 🛠 [Adjust project settings](https://app.snyk.io/org/chatwoot/project/b7197bbd-6200-4f23-931d-c39928584360?utm_source=github&utm_medium=referral&page=fix-pr/settings) 📚 [Read about Snyk's upgrade logic](https://support.snyk.io/hc/en-us/articles/360003891078-Snyk-patches-to-fix-vulnerabilities) --- **Learn how to fix vulnerabilities with free interactive lessons:** 🦉 [Learn about vulnerability in an interactive lesson of Snyk Learn.](https://learn.snyk.io/?loc=fix-pr) [//]: # 'snyk:metadata:{"customTemplate":{"variablesUsed":[],"fieldsUsed":[]},"dependencies":[{"name":"rspec-rails","from":"6.1.4","to":"6.1.5"}],"env":"prod","issuesToFix":[{"exploit_maturity":"Proof of Concept","id":"SNYK-RUBY-RACK-1061917","priority_score":616,"priority_score_factors":[{"type":"exploit","label":"Proof of Concept","score":107},{"type":"fixability","label":true,"score":214},{"type":"cvssScore","label":"5.9","score":295},{"type":"scoreVersion","label":"v1","score":1}],"severity":"medium","title":"Web Cache Poisoning"},{"exploit_maturity":"Proof of Concept","id":"SNYK-RUBY-RACK-1061917","priority_score":616,"priority_score_factors":[{"type":"exploit","label":"Proof of Concept","score":107},{"type":"fixability","label":true,"score":214},{"type":"cvssScore","label":"5.9","score":295},{"type":"scoreVersion","label":"v1","score":1}],"severity":"medium","title":"Web Cache Poisoning"},{"exploit_maturity":"Proof of Concept","id":"SNYK-RUBY-RACK-1061917","priority_score":616,"priority_score_factors":[{"type":"exploit","label":"Proof of Concept","score":107},{"type":"fixability","label":true,"score":214},{"type":"cvssScore","label":"5.9","score":295},{"type":"scoreVersion","label":"v1","score":1}],"severity":"medium","title":"Web Cache Poisoning"},{"exploit_maturity":"Proof of Concept","id":"SNYK-RUBY-RACK-1061917","priority_score":616,"priority_score_factors":[{"type":"exploit","label":"Proof of Concept","score":107},{"type":"fixability","label":true,"score":214},{"type":"cvssScore","label":"5.9","score":295},{"type":"scoreVersion","label":"v1","score":1}],"severity":"medium","title":"Web Cache Poisoning"}],"prId":"a1a6393e-787a-4fab-8f51-3f7f7f375ed6","prPublicId":"a1a6393e-787a-4fab-8f51-3f7f7f375ed6","packageManager":"rubygems","priorityScoreList":[616],"projectPublicId":"b7197bbd-6200-4f23-931d-c39928584360","projectUrl":"https://app.snyk.io/org/chatwoot/project/b7197bbd-6200-4f23-931d-c39928584360?utm_source=github&utm_medium=referral&page=fix-pr","prType":"fix","templateFieldSources":{"branchName":"default","commitMessage":"default","description":"default","title":"default"},"templateVariants":["updated-fix-title","pr-warning-shown","priorityScore"],"type":"auto","upgrade":["SNYK-RUBY-RACK-1061917"],"vulns":["SNYK-RUBY-RACK-1061917"],"patch":[],"isBreakingChange":false,"remediationStrategy":"vuln"}' --------- Co-authored-by: snyk-bot <snyk-bot@snyk.io>
124 lines
4.7 KiB
Ruby
124 lines
4.7 KiB
Ruby
require 'rails_helper'
|
|
|
|
RSpec.describe Inboxes::FetchImapEmailsJob do
|
|
include ActiveJob::TestHelper
|
|
include ActionMailbox::TestHelper
|
|
|
|
let(:account) { create(:account) }
|
|
let(:imap_email_channel) { create(:channel_email, :imap_email, account: account) }
|
|
let(:channel_with_imap_disabled) { create(:channel_email, :imap_email, imap_enabled: false, account: account) }
|
|
let(:microsoft_imap_email_channel) { create(:channel_email, :microsoft_email) }
|
|
|
|
describe '#perform' do
|
|
it 'enqueues the job' do
|
|
expect do
|
|
described_class.perform_later(imap_email_channel, 1)
|
|
end.to have_enqueued_job(described_class).on_queue('scheduled_jobs')
|
|
end
|
|
|
|
context 'when IMAP is disabled' do
|
|
it 'does not fetch emails' do
|
|
expect(Imap::FetchEmailService).not_to receive(:new)
|
|
expect(Imap::MicrosoftFetchEmailService).not_to receive(:new)
|
|
described_class.perform_now(channel_with_imap_disabled)
|
|
end
|
|
end
|
|
|
|
context 'when IMAP reauthorization is required' do
|
|
it 'does not fetch emails' do
|
|
10.times do
|
|
imap_email_channel.authorization_error!
|
|
end
|
|
|
|
expect(Imap::FetchEmailService).not_to receive(:new)
|
|
# Confirm the imap_enabled flag is true to avoid false positives.
|
|
expect(imap_email_channel.imap_enabled?).to be true
|
|
|
|
described_class.perform_now(imap_email_channel)
|
|
end
|
|
end
|
|
|
|
context 'when the channel is regular imap' do
|
|
it 'calls the imap fetch service' do
|
|
fetch_service = double
|
|
allow(Imap::FetchEmailService).to receive(:new).with(channel: imap_email_channel, interval: 1).and_return(fetch_service)
|
|
allow(fetch_service).to receive(:perform).and_return([])
|
|
|
|
described_class.perform_now(imap_email_channel)
|
|
expect(fetch_service).to have_received(:perform)
|
|
end
|
|
|
|
it 'calls the imap fetch service with the correct interval' do
|
|
fetch_service = double
|
|
allow(Imap::FetchEmailService).to receive(:new).with(channel: imap_email_channel, interval: 4).and_return(fetch_service)
|
|
allow(fetch_service).to receive(:perform).and_return([])
|
|
|
|
described_class.perform_now(imap_email_channel, 4)
|
|
expect(fetch_service).to have_received(:perform)
|
|
end
|
|
end
|
|
|
|
context 'when the channel is Microsoft' do
|
|
it 'calls the Microsoft fetch service' do
|
|
fetch_service = double
|
|
allow(Imap::MicrosoftFetchEmailService).to receive(:new).with(channel: microsoft_imap_email_channel, interval: 1).and_return(fetch_service)
|
|
allow(fetch_service).to receive(:perform).and_return([])
|
|
|
|
described_class.perform_now(microsoft_imap_email_channel)
|
|
expect(fetch_service).to have_received(:perform)
|
|
end
|
|
end
|
|
|
|
context 'when IMAP OAuth errors out' do
|
|
it 'marks the connection as requiring authorization' do
|
|
error_response = double
|
|
oauth_error = OAuth2::Error.new(error_response)
|
|
|
|
allow(Imap::MicrosoftFetchEmailService).to receive(:new)
|
|
.with(channel: microsoft_imap_email_channel, interval: 1)
|
|
.and_raise(oauth_error)
|
|
|
|
allow(Redis::Alfred).to receive(:incr)
|
|
|
|
expect(Redis::Alfred).to receive(:incr)
|
|
.with("AUTHORIZATION_ERROR_COUNT:channel_email:#{microsoft_imap_email_channel.id}")
|
|
|
|
described_class.perform_now(microsoft_imap_email_channel)
|
|
end
|
|
end
|
|
|
|
context 'when the fetch service returns the email objects' do
|
|
let(:inbound_mail) { create_inbound_email_from_fixture('welcome.eml').mail }
|
|
let(:mailbox) { double }
|
|
let(:exception_tracker) { double }
|
|
let(:fetch_service) { double }
|
|
|
|
before do
|
|
allow(Imap::ImapMailbox).to receive(:new).and_return(mailbox)
|
|
allow(ChatwootExceptionTracker).to receive(:new).and_return(exception_tracker)
|
|
|
|
allow(Imap::FetchEmailService).to receive(:new).with(channel: imap_email_channel, interval: 1).and_return(fetch_service)
|
|
allow(fetch_service).to receive(:perform).and_return([inbound_mail])
|
|
end
|
|
|
|
it 'calls the mailbox to create emails' do
|
|
allow(mailbox).to receive(:process)
|
|
|
|
expect(Imap::FetchEmailService).to receive(:new).with(channel: imap_email_channel, interval: 1).and_return(fetch_service)
|
|
expect(fetch_service).to receive(:perform).and_return([inbound_mail])
|
|
expect(mailbox).to receive(:process).with(inbound_mail, imap_email_channel)
|
|
|
|
described_class.perform_now(imap_email_channel)
|
|
end
|
|
|
|
it 'logs errors if mailbox returns errors' do
|
|
allow(mailbox).to receive(:process).and_raise(StandardError)
|
|
|
|
expect(exception_tracker).to receive(:capture_exception)
|
|
|
|
described_class.perform_now(imap_email_channel)
|
|
end
|
|
end
|
|
end
|
|
end
|