From d017156f32e9a02a43f06d014df24d1025713606 Mon Sep 17 00:00:00 2001 From: Pranav Date: Wed, 5 Mar 2025 17:10:24 -0800 Subject: [PATCH 1/3] fix: Disable syncing IMAP if the account is suspended (#11031) This PR disables the IMAP syncing if the account is suspended. --- Gemfile.lock | 2 +- .../inboxes/fetch_imap_email_inboxes_job.rb | 11 +++++-- .../fetch_imap_email_inboxes_job_spec.rb | 33 ++++++++++++++++--- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 8591a0c34..857319fc4 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -561,7 +561,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.8.1) - rack (2.2.11) + rack (2.2.12) rack-attack (6.7.0) rack (>= 1.0, < 4) rack-contrib (2.5.0) diff --git a/app/jobs/inboxes/fetch_imap_email_inboxes_job.rb b/app/jobs/inboxes/fetch_imap_email_inboxes_job.rb index b360940e3..56e8c2235 100644 --- a/app/jobs/inboxes/fetch_imap_email_inboxes_job.rb +++ b/app/jobs/inboxes/fetch_imap_email_inboxes_job.rb @@ -2,8 +2,15 @@ class Inboxes::FetchImapEmailInboxesJob < ApplicationJob queue_as :scheduled_jobs def perform - Inbox.where(channel_type: 'Channel::Email').all.find_each(batch_size: 100) do |inbox| - ::Inboxes::FetchImapEmailsJob.perform_later(inbox.channel) if inbox.channel.imap_enabled + email_inboxes = Inbox.where(channel_type: 'Channel::Email') + email_inboxes.find_each(batch_size: 100) do |inbox| + ::Inboxes::FetchImapEmailsJob.perform_later(inbox.channel) if should_fetch_emails?(inbox) end end + + private + + def should_fetch_emails?(inbox) + inbox.channel.imap_enabled && !inbox.account.suspended? + end end diff --git a/spec/jobs/inboxes/fetch_imap_email_inboxes_job_spec.rb b/spec/jobs/inboxes/fetch_imap_email_inboxes_job_spec.rb index ae4f540d4..18685a649 100644 --- a/spec/jobs/inboxes/fetch_imap_email_inboxes_job_spec.rb +++ b/spec/jobs/inboxes/fetch_imap_email_inboxes_job_spec.rb @@ -2,11 +2,19 @@ require 'rails_helper' RSpec.describe Inboxes::FetchImapEmailInboxesJob do let(:account) { create(:account) } + let(:suspended_account) { create(:account, status: 'suspended') } + let(:imap_email_channel) do - create(:channel_email, imap_enabled: true, imap_address: 'imap.gmail.com', imap_port: 993, imap_login: 'imap@gmail.com', - imap_password: 'password', account: account) + create(:channel_email, imap_enabled: true, account: account) + end + + let(:imap_email_channel_suspended) do + create(:channel_email, imap_enabled: true, account: suspended_account) + end + + let(:disabled_imap_channel) do + create(:channel_email, imap_enabled: false, account: account) end - let(:email_inbox) { create(:inbox, channel: imap_email_channel, account: account) } it 'enqueues the job' do expect { described_class.perform_later }.to have_enqueued_job(described_class) @@ -14,9 +22,26 @@ RSpec.describe Inboxes::FetchImapEmailInboxesJob do end context 'when called' do - it 'fetch all the email channels' do + it 'fetches emails only for active accounts with imap enabled' do + # Should call perform_later only once for the active, imap-enabled inbox expect(Inboxes::FetchImapEmailsJob).to receive(:perform_later).with(imap_email_channel).once + # Should not call for suspended account or disabled IMAP channels + expect(Inboxes::FetchImapEmailsJob).not_to receive(:perform_later).with(imap_email_channel_suspended) + expect(Inboxes::FetchImapEmailsJob).not_to receive(:perform_later).with(disabled_imap_channel) + + described_class.perform_now + end + + it 'skips suspended accounts' do + expect(Inboxes::FetchImapEmailsJob).not_to receive(:perform_later).with(imap_email_channel_suspended) + + described_class.perform_now + end + + it 'skips disabled imap channels' do + expect(Inboxes::FetchImapEmailsJob).not_to receive(:perform_later).with(disabled_imap_channel) + described_class.perform_now end end From 7e1458fd32f8c24e4da84097f6510b120e22907b Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Thu, 6 Mar 2025 10:53:02 +0530 Subject: [PATCH 2/3] fix: Issue when saving hotkeys (#11026) # Pull Request Template ## Description This PR fixes an issue when saving send message button hotkeys, where a TypeError occurs: `this.updateUISettings is not a function`. This issue arises after merging this PR https://github.com/chatwoot/chatwoot/pull/10974 Fixes https://chatwoot-p3.sentry.io/issues/6339976939/events/ca9946f92cb74428a72f1f74976a56a3/ ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] My code follows the style guidelines of this project - [x] I have performed a self-review of my code - [ ] I have commented on my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [x] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [x] New and existing unit tests pass locally with my changes - [ ] Any dependent changes have been merged and published in downstream modules --- .../dashboard/routes/dashboard/settings/profile/Index.vue | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue b/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue index 85204627a..45a060e05 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/profile/Index.vue @@ -39,13 +39,14 @@ export default { }, mixins: [globalConfigMixin], setup() { - const { isEditorHotKeyEnabled } = useUISettings(); + const { isEditorHotKeyEnabled, updateUISettings } = useUISettings(); const { currentFontSize, updateFontSize } = useFontSize(); return { currentFontSize, updateFontSize, isEditorHotKeyEnabled, + updateUISettings, }; }, data() { From 8d85a02ca9a7a4f81fb58e987758103219642801 Mon Sep 17 00:00:00 2001 From: Shivam Mishra Date: Thu, 6 Mar 2025 20:09:47 +0530 Subject: [PATCH 3/3] feat: handle Channel errors (#11015) This PR adds missing error handlers for the following channels and cases 1. WhatsApp - Generic Handlers for both Cloud and 360Dialog (Deprecated) 2. Instagram - Handler for a case where there is an HTTP error instead of an `:error` in the 200 response 3. Facebook - Errors from the two sentry issues ([Net::OpenTimeout](https://chatwoot-p3.sentry.io/issues/6164805227) & [JSON::ParserError](https://chatwoot-p3.sentry.io/issues/5903200786)) 4. SMS: Generic handlers for Bandwidth SMS #### Checklist - [x] Bandwidth SMS - [x] Whatsapp Cloud + 360 Dialog - [x] Twilio SMS - [x] Line - [x] Telegram - [x] Instagram - [x] Facebook - [x] GMail - [x] 365 Mail - [x] SMTP Mail --------- Co-authored-by: Muhsin Keloth --- .../components-next/message/MessageError.vue | 2 +- .../components-next/message/MessageMeta.vue | 1 + app/models/channel/sms.rb | 21 +++- .../facebook/send_on_facebook_service.rb | 21 +++- .../instagram/send_on_instagram_service.rb | 28 +++-- .../whatsapp/providers/base_service.rb | 27 ++++ .../providers/whatsapp_360_dialog_service.rb | 12 +- .../providers/whatsapp_cloud_service.rb | 12 +- .../facebook/send_on_facebook_service_spec.rb | 49 ++++++++ .../send_on_instagram_service_spec.rb | 108 +++++++++++----- .../providers/whatsapp_cloud_service_spec.rb | 52 ++++++++ .../whatsapp/send_on_whatsapp_service_spec.rb | 115 +++++++++--------- 12 files changed, 324 insertions(+), 124 deletions(-) diff --git a/app/javascript/dashboard/components-next/message/MessageError.vue b/app/javascript/dashboard/components-next/message/MessageError.vue index e113ada71..d3a03e746 100644 --- a/app/javascript/dashboard/components-next/message/MessageError.vue +++ b/app/javascript/dashboard/components-next/message/MessageError.vue @@ -26,7 +26,7 @@ const { t } = useI18n(); />