mirror of
https://github.com/discourse/discourse.git
synced 2024-11-24 17:15:32 +08:00
3c5fb871c0
There is an edge case where the following occurs: 1. The user sets a bookmark reminder on a post/topic 2. The post/topic is changed to a PM before or after the reminder fires, and the notification remains unread by the user 3. The user opens their bookmark reminder notification list and they can still see the notification even though they cannot access the topic anymore There is a very low chance for information leaking here, since the only thing that could be exposed is the topic title if it changes to something sensitive. This commit filters the bookmark unread notifications by using the bookmarkable can_see? methods and also prevents sending reminder notifications for bookmarks the user can no longer see.
140 lines
5.1 KiB
Ruby
140 lines
5.1 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
require "rails_helper"
|
|
|
|
RSpec.describe TopicBookmarkable do
|
|
subject(:registered_bookmarkable) { RegisteredBookmarkable.new(TopicBookmarkable) }
|
|
|
|
fab!(:user) { Fabricate(:user) }
|
|
fab!(:private_category) { Fabricate(:private_category, group: Fabricate(:group)) }
|
|
|
|
let(:guardian) { Guardian.new(user) }
|
|
|
|
let!(:topic1) { Fabricate(:topic) }
|
|
let!(:topic2) { Fabricate(:topic) }
|
|
let!(:post) { Fabricate(:post, topic: topic1) }
|
|
let!(:bookmark1) do
|
|
Fabricate(:bookmark, user: user, bookmarkable: topic1, name: "something i gotta do")
|
|
end
|
|
let!(:bookmark2) { Fabricate(:bookmark, user: user, bookmarkable: topic2) }
|
|
let!(:bookmark3) { Fabricate(:bookmark) }
|
|
let!(:topic_user1) { Fabricate(:topic_user, user: user, topic: topic1) }
|
|
let!(:topic_user2) { Fabricate(:topic_user, user: user, topic: topic2) }
|
|
|
|
describe "#perform_list_query" do
|
|
it "returns all the user's bookmarks" do
|
|
expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array(
|
|
[bookmark1.id, bookmark2.id],
|
|
)
|
|
end
|
|
|
|
it "does not return bookmarks for posts where the user does not have access to the topic category" do
|
|
bookmark1.bookmarkable.update!(category: private_category)
|
|
expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array(
|
|
[bookmark2.id],
|
|
)
|
|
end
|
|
|
|
it "does not return bookmarks for posts where the user does not have access to the private message" do
|
|
bookmark1.update!(bookmarkable: Fabricate(:private_message_topic))
|
|
expect(registered_bookmarkable.perform_list_query(user, guardian).map(&:id)).to match_array(
|
|
[bookmark2.id],
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#perform_search_query" do
|
|
before { SearchIndexer.enable }
|
|
|
|
it "returns bookmarks that match by name" do
|
|
ts_query = Search.ts_query(term: "gotta", ts_config: "simple")
|
|
expect(
|
|
registered_bookmarkable.perform_search_query(
|
|
registered_bookmarkable.perform_list_query(user, guardian),
|
|
"%gotta%",
|
|
ts_query,
|
|
).map(&:id),
|
|
).to match_array([bookmark1.id])
|
|
end
|
|
|
|
it "returns bookmarks that match by post search data (topic title or post content)" do
|
|
post.update(raw: "some post content")
|
|
topic1.update(title: "a great topic title")
|
|
|
|
ts_query = Search.ts_query(term: "post content", ts_config: "simple")
|
|
expect(
|
|
registered_bookmarkable.perform_search_query(
|
|
registered_bookmarkable.perform_list_query(user, guardian),
|
|
"%post content%",
|
|
ts_query,
|
|
).map(&:id),
|
|
).to match_array([bookmark1.id])
|
|
|
|
ts_query = Search.ts_query(term: "great topic", ts_config: "simple")
|
|
expect(
|
|
registered_bookmarkable.perform_search_query(
|
|
registered_bookmarkable.perform_list_query(user, guardian),
|
|
"%great topic%",
|
|
ts_query,
|
|
).map(&:id),
|
|
).to match_array([bookmark1.id])
|
|
|
|
ts_query = Search.ts_query(term: "blah", ts_config: "simple")
|
|
expect(
|
|
registered_bookmarkable.perform_search_query(
|
|
registered_bookmarkable.perform_list_query(user, guardian),
|
|
"%blah%",
|
|
ts_query,
|
|
).map(&:id),
|
|
).to eq([])
|
|
end
|
|
end
|
|
|
|
describe "#can_send_reminder?" do
|
|
it "cannot send reminder if the topic is deleted" do
|
|
expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(true)
|
|
bookmark1.bookmarkable.trash!
|
|
bookmark1.reload
|
|
expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false)
|
|
end
|
|
|
|
it "cannot send reminder if the user cannot access the topic" do
|
|
expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(true)
|
|
bookmark1.bookmarkable.update!(category: private_category)
|
|
bookmark1.reload
|
|
expect(registered_bookmarkable.can_send_reminder?(bookmark1)).to eq(false)
|
|
end
|
|
end
|
|
|
|
describe "#reminder_handler" do
|
|
it "creates a notification for the user with the correct details" do
|
|
expect { registered_bookmarkable.send_reminder_notification(bookmark1) }.to change {
|
|
Notification.count
|
|
}.by(1)
|
|
notif = user.notifications.last
|
|
expect(notif.notification_type).to eq(Notification.types[:bookmark_reminder])
|
|
expect(notif.topic_id).to eq(bookmark1.bookmarkable_id)
|
|
expect(notif.post_number).to eq(1)
|
|
expect(notif.data).to eq(
|
|
{
|
|
title: bookmark1.bookmarkable.title,
|
|
bookmarkable_url: bookmark1.bookmarkable.first_post.url,
|
|
display_username: bookmark1.user.username,
|
|
bookmark_name: bookmark1.name,
|
|
bookmark_id: bookmark1.id,
|
|
}.to_json,
|
|
)
|
|
end
|
|
end
|
|
|
|
describe "#can_see?" do
|
|
it "returns false if the post is in a private category or private message the user cannot see" do
|
|
expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(true)
|
|
bookmark1.bookmarkable.update!(category: private_category)
|
|
expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false)
|
|
bookmark1.update!(bookmarkable: Fabricate(:private_message_topic))
|
|
expect(registered_bookmarkable.can_see?(guardian, bookmark1)).to eq(false)
|
|
end
|
|
end
|
|
end
|