mirror of
https://github.com/lingble/chatwoot.git
synced 2025-10-30 10:42:38 +00:00
chore: Add validation to prevent message flooding (#9254)
- Add a validation to limit messages created per minute to avoid message flooding cases.
This commit is contained in:
@@ -59,6 +59,7 @@ class Message < ApplicationRecord
|
|||||||
}.to_json.freeze
|
}.to_json.freeze
|
||||||
|
|
||||||
before_validation :ensure_content_type
|
before_validation :ensure_content_type
|
||||||
|
before_validation :prevent_message_flooding
|
||||||
before_save :ensure_processed_message_content
|
before_save :ensure_processed_message_content
|
||||||
before_save :ensure_in_reply_to
|
before_save :ensure_in_reply_to
|
||||||
|
|
||||||
@@ -227,6 +228,18 @@ class Message < ApplicationRecord
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
|
def prevent_message_flooding
|
||||||
|
# Added this to cover the validation specs in messages
|
||||||
|
# We can revisit and see if we can remove this later
|
||||||
|
return if conversation.blank?
|
||||||
|
|
||||||
|
# there are cases where automations can result in message loops, we need to prevent such cases.
|
||||||
|
if conversation.messages.where('created_at >= ?', 1.minute.ago).count >= Limits.conversation_message_per_minute_limit
|
||||||
|
Rails.logger.error "Too many message: Account Id - #{account_id} : Conversation id - #{conversation_id}"
|
||||||
|
errors.add(:base, 'Too many messages')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def ensure_processed_message_content
|
def ensure_processed_message_content
|
||||||
text_content_quoted = content_attributes.dig(:email, :text_content, :quoted)
|
text_content_quoted = content_attributes.dig(:email, :text_content, :quoted)
|
||||||
html_content_quoted = content_attributes.dig(:email, :html_content, :quoted)
|
html_content_quoted = content_attributes.dig(:email, :html_content, :quoted)
|
||||||
|
|||||||
@@ -4,4 +4,8 @@ module Limits
|
|||||||
URL_LENGTH_LIMIT = 2048 # https://stackoverflow.com/questions/417142
|
URL_LENGTH_LIMIT = 2048 # https://stackoverflow.com/questions/417142
|
||||||
OUT_OF_OFFICE_MESSAGE_MAX_LENGTH = 10_000
|
OUT_OF_OFFICE_MESSAGE_MAX_LENGTH = 10_000
|
||||||
GREETING_MESSAGE_MAX_LENGTH = 10_000
|
GREETING_MESSAGE_MAX_LENGTH = 10_000
|
||||||
|
|
||||||
|
def self.conversation_message_per_minute_limit
|
||||||
|
ENV.fetch('CONVERSATION_MESSAGE_PER_MINUTE_LIMIT', '200').to_i
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ RSpec.describe Message do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe 'length validations' do
|
describe 'length validations' do
|
||||||
let(:message) { create(:message) }
|
let!(:message) { create(:message) }
|
||||||
|
|
||||||
context 'when it validates name length' do
|
context 'when it validates name length' do
|
||||||
it 'valid when within limit' do
|
it 'valid when within limit' do
|
||||||
@@ -27,6 +27,17 @@ RSpec.describe Message do
|
|||||||
expect(message.errors[:processed_message_content]).to include('is too long (maximum is 150000 characters)')
|
expect(message.errors[:processed_message_content]).to include('is too long (maximum is 150000 characters)')
|
||||||
expect(message.errors[:content]).to include('is too long (maximum is 150000 characters)')
|
expect(message.errors[:content]).to include('is too long (maximum is 150000 characters)')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'adds error in case of message flooding' do
|
||||||
|
with_modified_env 'CONVERSATION_MESSAGE_PER_MINUTE_LIMIT': '2' do
|
||||||
|
conversation = message.conversation
|
||||||
|
create(:message, conversation: conversation)
|
||||||
|
conv_new_message = build(:message, conversation: message.conversation)
|
||||||
|
|
||||||
|
expect(conv_new_message.valid?).to be false
|
||||||
|
expect(conv_new_message.errors[:base]).to eq(['Too many messages'])
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user