diff --git a/assets/javascripts/initializers/ai-bot-replies.js b/assets/javascripts/initializers/ai-bot-replies.js index b184aa1b..e4020e33 100644 --- a/assets/javascripts/initializers/ai-bot-replies.js +++ b/assets/javascripts/initializers/ai-bot-replies.js @@ -163,7 +163,7 @@ function initializeShareTopicButton(api) { displayed() { return ( currentUser?.can_share_ai_bot_conversations && - this.topic.ai_persona_name !== undefined + this.topic.ai_persona_name ); }, }); diff --git a/lib/ai_bot/entry_point.rb b/lib/ai_bot/entry_point.rb index 12a61381..0c0562a1 100644 --- a/lib/ai_bot/entry_point.rb +++ b/lib/ai_bot/entry_point.rb @@ -33,6 +33,10 @@ module DiscourseAi Bot = Struct.new(:id, :name, :llm) + def self.all_bot_ids + BOT_USER_IDS.concat(AiPersona.mentionables.map { |mentionable| mentionable[:user_id] }) + end + def self.find_bot_by_id(id) found = DiscourseAi::AiBot::EntryPoint::BOTS.find { |bot| bot[0] == id } return if !found diff --git a/lib/guardian_extensions.rb b/lib/guardian_extensions.rb index a35fe070..e8074b77 100644 --- a/lib/guardian_extensions.rb +++ b/lib/guardian_extensions.rb @@ -17,15 +17,22 @@ module DiscourseAi if target.is_a?(Topic) return false if !target.private_message? return false if target.topic_allowed_groups.exists? - return false if !target.topic_allowed_users.exists?(user_id: user.id) + allowed_user_ids = target.topic_allowed_users.pluck(:user_id) + + # not in PM + return false if !allowed_user_ids.include?(user.id) # other people in PM - if target.topic_allowed_users.where("user_id > 0 and user_id <> ?", user.id).exists? - return false - end + return false if allowed_user_ids.any? { |id| id > 0 && id != user.id } + + # no bot in the PM + bot_ids = DiscourseAi::AiBot::EntryPoint.all_bot_ids + return false if allowed_user_ids.none? { |id| bot_ids.include?(id) } # other content in PM return false if target.posts.where("user_id > 0 and user_id <> ?", user.id).exists? + else + return false end true diff --git a/spec/system/ai_bot/ai_share_conversation_spec.rb b/spec/system/ai_bot/ai_share_conversation_spec.rb new file mode 100644 index 00000000..2dee0851 --- /dev/null +++ b/spec/system/ai_bot/ai_share_conversation_spec.rb @@ -0,0 +1,31 @@ +# frozen_string_literal: true + +RSpec.describe "Share conversation via link", type: :system do + fab!(:admin) { Fabricate(:admin, username: "ai_sharer") } + let(:bot_user) { User.find(DiscourseAi::AiBot::EntryPoint::GPT4_ID) } + + let(:pm) do + Fabricate( + :private_message_topic, + title: "This is my special PM", + user: admin, + topic_allowed_users: [Fabricate.build(:topic_allowed_user, user: admin)], + ) + end + + let!(:op) { Fabricate(:post, topic: pm, user: admin, raw: "test test test user reply") } + + before do + SiteSetting.ai_bot_enabled = true + SiteSetting.ai_bot_enabled_chat_bots = "gpt-4" + SiteSetting.ai_bot_public_sharing_allowed_groups = "1" # admin + Group.refresh_automatic_groups! + sign_in(admin) + end + + it "does not show share button for my own PMs without bot" do + visit(pm.url) + expect(Guardian.new(admin).can_share_ai_bot_conversation?(pm)).to eq(false) + expect(page).not_to have_selector(".share-ai-conversation-button") + end +end