fix: Disable enqueueing Avatar jobs if the URL is invalid (#12035)

- Add a new queue purgable
- Disable enqueuing the job if URL is invalid
This commit is contained in:
Pranav
2025-07-24 12:56:39 +04:00
committed by GitHub
parent 2a5ecf84a1
commit 9acb0d86b5
7 changed files with 21 additions and 6 deletions

View File

@@ -6,6 +6,7 @@
# We don't want to update the name of the identified original contact. # We don't want to update the name of the identified original contact.
class ContactIdentifyAction class ContactIdentifyAction
include UrlHelper
pattr_initialize [:contact!, :params!, { retain_original_contact_name: false, discard_invalid_attrs: false }] pattr_initialize [:contact!, :params!, { retain_original_contact_name: false, discard_invalid_attrs: false }]
def perform def perform
@@ -104,7 +105,14 @@ class ContactIdentifyAction
# TODO: replace reject { |_k, v| v.blank? } with compact_blank when rails is upgraded # TODO: replace reject { |_k, v| v.blank? } with compact_blank when rails is upgraded
@contact.discard_invalid_attrs if discard_invalid_attrs @contact.discard_invalid_attrs if discard_invalid_attrs
@contact.save! @contact.save!
Avatar::AvatarFromUrlJob.perform_later(@contact, params[:avatar_url]) if params[:avatar_url].present? && !@contact.avatar.attached? enqueue_avatar_job
end
def enqueue_avatar_job
return unless params[:avatar_url].present? && !@contact.avatar.attached?
return unless url_valid?(params[:avatar_url])
Avatar::AvatarFromUrlJob.perform_later(@contact, params[:avatar_url])
end end
def merge_contact(base_contact, merge_contact) def merge_contact(base_contact, merge_contact)

View File

@@ -1,5 +1,5 @@
class Avatar::AvatarFromGravatarJob < ApplicationJob class Avatar::AvatarFromGravatarJob < ApplicationJob
queue_as :low queue_as :purgable
def perform(avatarable, email) def perform(avatarable, email)
return if GlobalConfigService.load('DISABLE_GRAVATAR', '').present? return if GlobalConfigService.load('DISABLE_GRAVATAR', '').present?

View File

@@ -1,5 +1,5 @@
class Avatar::AvatarFromUrlJob < ApplicationJob class Avatar::AvatarFromUrlJob < ApplicationJob
queue_as :low queue_as :purgable
def perform(avatarable, avatar_url) def perform(avatarable, avatar_url)
return unless avatarable.respond_to?(:avatar) return unless avatarable.respond_to?(:avatar)

View File

@@ -24,6 +24,7 @@
- low - low
- scheduled_jobs - scheduled_jobs
- deferred - deferred
- purgable
- housekeeping - housekeeping
- async_database_migration - async_database_migration
- active_storage_analysis - active_storage_analysis

View File

@@ -36,12 +36,18 @@ describe ContactIdentifyAction do
expect(result.additional_attributes['social_profiles']).to eq({ 'linkedin' => 'saras', 'twitter' => 'saras' }) expect(result.additional_attributes['social_profiles']).to eq({ 'linkedin' => 'saras', 'twitter' => 'saras' })
end end
it 'enques avatar job when avatar url parameter is passed' do it 'enqueues avatar job when valid avatar url parameter is passed' do
params = { name: 'test', avatar_url: 'https://chatwoot-assets.local/sample.png' } params = { name: 'test', avatar_url: 'https://chatwoot-assets.local/sample.png' }
expect(Avatar::AvatarFromUrlJob).to receive(:perform_later).with(contact, params[:avatar_url]).once expect(Avatar::AvatarFromUrlJob).to receive(:perform_later).with(contact, params[:avatar_url]).once
described_class.new(contact: contact, params: params).perform described_class.new(contact: contact, params: params).perform
end end
it 'does not enqueue avatar job when invalid avatar url parameter is passed' do
params = { name: 'test', avatar_url: 'invalid-url' }
expect(Avatar::AvatarFromUrlJob).not_to receive(:perform_later)
described_class.new(contact: contact, params: params).perform
end
context 'when contact with same identifier exists' do context 'when contact with same identifier exists' do
it 'merges the current contact to identified contact' do it 'merges the current contact to identified contact' do
existing_identified_contact = create(:contact, account: account, identifier: 'test_id') existing_identified_contact = create(:contact, account: account, identifier: 'test_id')

View File

@@ -7,7 +7,7 @@ RSpec.describe Avatar::AvatarFromGravatarJob do
it 'enqueues the job' do it 'enqueues the job' do
expect { described_class.perform_later(avatarable, email) }.to have_enqueued_job(described_class) expect { described_class.perform_later(avatarable, email) }.to have_enqueued_job(described_class)
.on_queue('low') .on_queue('purgable')
end end
it 'will call AvatarFromUrlJob with gravatar url' do it 'will call AvatarFromUrlJob with gravatar url' do

View File

@@ -6,7 +6,7 @@ RSpec.describe Avatar::AvatarFromUrlJob do
it 'enqueues the job' do it 'enqueues the job' do
expect { described_class.perform_later(avatarable, avatar_url) }.to have_enqueued_job(described_class) expect { described_class.perform_later(avatarable, avatar_url) }.to have_enqueued_job(described_class)
.on_queue('low') .on_queue('purgable')
end end
it 'will attach avatar from url' do it 'will attach avatar from url' do