Merge pull request from GHSA-5fq7-3p3j-9vrf

pull/30483/head
Claire 2024-05-30 14:03:13 +02:00 committed by GitHub
parent d20a5c3ec9
commit 3ea4275ae3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 25 additions and 8 deletions

View File

@ -147,6 +147,9 @@ class NotifyService < BaseService
end end
def statuses_that_mention_sender def statuses_that_mention_sender
# This queries private mentions from the recipient to the sender up in the thread.
# This allows up to 100 messages that do not match in the thread, allowing conversations
# involving multiple people.
Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100]) Status.count_by_sql([<<-SQL.squish, id: @notification.target_status.in_reply_to_id, recipient_id: @recipient.id, sender_id: @sender.id, depth_limit: 100])
WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS ( WITH RECURSIVE ancestors(id, in_reply_to_id, mention_id, path, depth) AS (
SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0 SELECT s.id, s.in_reply_to_id, m.id, ARRAY[s.id], 0
@ -154,16 +157,17 @@ class NotifyService < BaseService
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id
WHERE s.id = :id WHERE s.id = :id
UNION ALL UNION ALL
SELECT s.id, s.in_reply_to_id, m.id, st.path || s.id, st.depth + 1 SELECT s.id, s.in_reply_to_id, m.id, ancestors.path || s.id, ancestors.depth + 1
FROM ancestors st FROM ancestors
JOIN statuses s ON s.id = st.in_reply_to_id JOIN statuses s ON s.id = ancestors.in_reply_to_id
LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id /* early exit if we already have a mention matching our requirements */
WHERE st.mention_id IS NULL AND NOT s.id = ANY(path) AND st.depth < :depth_limit LEFT JOIN mentions m ON m.silent = FALSE AND m.account_id = :sender_id AND m.status_id = s.id AND s.account_id = :recipient_id
WHERE ancestors.mention_id IS NULL AND NOT s.id = ANY(path) AND ancestors.depth < :depth_limit
) )
SELECT COUNT(*) SELECT COUNT(*)
FROM ancestors st FROM ancestors
JOIN statuses s ON s.id = st.id JOIN statuses s ON s.id = ancestors.id
WHERE st.mention_id IS NOT NULL AND s.visibility = 3 WHERE ancestors.mention_id IS NOT NULL AND s.account_id = :recipient_id AND s.visibility = 3
SQL SQL
end end
end end

View File

@ -309,6 +309,19 @@ RSpec.describe NotifyService do
expect(subject.filter?).to be false expect(subject.filter?).to be false
end end
end end
context 'when the sender is mentioned in an unrelated message chain' do
before do
original_status = Fabricate(:status, visibility: :direct)
intermediary_status = Fabricate(:status, visibility: :direct, thread: original_status)
notification.target_status.update(thread: intermediary_status)
Fabricate(:mention, status: original_status, account: notification.from_account)
end
it 'returns true' do
expect(subject.filter?).to be true
end
end
end end
end end
end end