Skip to content
This repository was archived by the owner on Jul 22, 2025. It is now read-only.

Commit 81b952d

Browse files
authored
FIX: only hide posts detected explicitly as spam (#1070)
When enabling spam scanner it there may be old unscanned posts this can create a risky situation where spam scanner operates on legit posts during false positives To keep this a lot safer we no longer try to hide old stuff by the spammers.
1 parent c881f8b commit 81b952d

File tree

2 files changed

+39
-17
lines changed

2 files changed

+39
-17
lines changed

lib/ai_moderation/spam_scanner.rb

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -377,26 +377,18 @@ def self.handle_spam(post, log)
377377
silencer.silence
378378

379379
# silencer will not hide tl1 posts, so we do this here
380-
hide_posts_and_topics(post.user)
380+
hide_post(post)
381381
end
382382

383-
def self.hide_posts_and_topics(user)
384-
Post
385-
.where(user_id: user.id)
386-
.where("created_at > ?", 24.hours.ago)
387-
.update_all(
388-
[
389-
"hidden = true, hidden_reason_id = COALESCE(hidden_reason_id, ?)",
390-
Post.hidden_reasons[:new_user_spam_threshold_reached],
391-
],
392-
)
393-
topic_ids =
394-
Post
395-
.where(user_id: user.id, post_number: 1)
396-
.where("created_at > ?", 24.hours.ago)
397-
.select(:topic_id)
383+
def self.hide_post(post)
384+
Post.where(id: post.id).update_all(
385+
[
386+
"hidden = true, hidden_reason_id = COALESCE(hidden_reason_id, ?)",
387+
Post.hidden_reasons[:new_user_spam_threshold_reached],
388+
],
389+
)
398390

399-
Topic.where(id: topic_ids).update_all(visible: false)
391+
Topic.where(id: post.topic_id).update_all(visible: false) if post.post_number == 1
400392
end
401393
end
402394
end

spec/lib/modules/ai_moderation/spam_scanner_spec.rb

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
require "rails_helper"
44

55
RSpec.describe DiscourseAi::AiModeration::SpamScanner do
6+
fab!(:moderator)
67
fab!(:user) { Fabricate(:user, trust_level: TrustLevel[0]) }
78
fab!(:topic)
89
fab!(:post) { Fabricate(:post, user: user, topic: topic) }
@@ -183,6 +184,29 @@
183184
end
184185
end
185186

187+
describe ".hide_post" do
188+
fab!(:spam_post) { Fabricate(:post, user: user) }
189+
fab!(:second_spam_post) { Fabricate(:post, topic: spam_post.topic, user: user) }
190+
191+
it "hides spam post and topic for first post" do
192+
described_class.hide_post(spam_post)
193+
194+
expect(spam_post.reload.hidden).to eq(true)
195+
expect(second_spam_post.reload.hidden).to eq(false)
196+
expect(spam_post.reload.hidden_reason_id).to eq(
197+
Post.hidden_reasons[:new_user_spam_threshold_reached],
198+
)
199+
end
200+
201+
it "doesn't hide the topic for non-first posts" do
202+
described_class.hide_post(second_spam_post)
203+
204+
expect(spam_post.reload.hidden).to eq(false)
205+
expect(second_spam_post.reload.hidden).to eq(true)
206+
expect(spam_post.topic.reload.visible).to eq(true)
207+
end
208+
end
209+
186210
describe "integration test" do
187211
fab!(:llm_model)
188212
let(:api_audit_log) { Fabricate(:api_audit_log) }
@@ -257,6 +281,12 @@
257281

258282
expect(log.reviewable).to be_present
259283
expect(log.reviewable.created_by_id).to eq(described_class.flagging_user.id)
284+
285+
log.reviewable.perform(moderator, :disagree_and_restore)
286+
287+
expect(post.reload.hidden?).to eq(false)
288+
expect(post.topic.reload.visible).to eq(true)
289+
expect(post.user.reload.silenced?).to eq(false)
260290
end
261291
end
262292
end

0 commit comments

Comments
 (0)