diff --git a/app/jobs/avatar/avatar_from_url_job.rb b/app/jobs/avatar/avatar_from_url_job.rb index f1efea225..f0d877b54 100644 --- a/app/jobs/avatar/avatar_from_url_job.rb +++ b/app/jobs/avatar/avatar_from_url_job.rb @@ -8,8 +8,21 @@ class Avatar::AvatarFromUrlJob < ApplicationJob avatar_url, max_size: 15 * 1024 * 1024 ) - avatarable.avatar.attach(io: avatar_file, filename: avatar_file.original_filename, content_type: avatar_file.content_type) + if valid_image?(avatar_file) + avatarable.avatar.attach(io: avatar_file, filename: avatar_file.original_filename, + content_type: avatar_file.content_type) + end rescue Down::NotFound, Down::Error => e Rails.logger.error "Exception: invalid avatar url #{avatar_url} : #{e.message}" end + + private + + def valid_image?(file) + return false if file.original_filename.blank? + + # TODO: check if the file is an actual image + + true + end end diff --git a/spec/jobs/avatar/avatar_from_url_job_spec.rb b/spec/jobs/avatar/avatar_from_url_job_spec.rb index b9886316a..25276bc67 100644 --- a/spec/jobs/avatar/avatar_from_url_job_spec.rb +++ b/spec/jobs/avatar/avatar_from_url_job_spec.rb @@ -17,4 +17,20 @@ RSpec.describe Avatar::AvatarFromUrlJob do described_class.perform_now(avatarable, avatar_url) expect(avatarable.avatar).to be_attached end + + # ref: https://github.com/chatwoot/chatwoot/issues/10449 + it 'will not throw error if the avatar url is not valid and the file does not have a filename' do + # Create a temporary file with no filename and content type application/xml + temp_file = Tempfile.new(['invalid', '.xml']) + temp_file.write('content') + temp_file.rewind + + expect(Down).to receive(:download).with(avatar_url, max_size: 15 * 1024 * 1024) + .and_return(ActionDispatch::Http::UploadedFile.new(tempfile: temp_file, type: 'application/xml')) + + expect { described_class.perform_now(avatarable, avatar_url) }.not_to raise_error + + temp_file.close + temp_file.unlink # deletes the temp file + end end