From 4aa0d5d709d144c2df22489e2c6e079d4c00c394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 24 Jul 2026 00:58:58 +0200 Subject: [PATCH 1/5] Allow disabling Chats feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- config/config.exs | 2 ++ config/description.exs | 13 +++++++++++++ lib/pleroma/chat.ex | 2 ++ lib/pleroma/web/activity_pub/views/user_view.ex | 2 +- lib/pleroma/web/mastodon_api/mastodon_api.ex | 9 +++++++++ lib/pleroma/web/mastodon_api/views/account_view.ex | 4 +++- .../web/mastodon_api/views/instance_view.ex | 3 +++ .../web/pleroma_api/controllers/chat_controller.ex | 13 +++++++++++++ lib/pleroma/web/streamer.ex | 14 ++++++++------ 9 files changed, 54 insertions(+), 8 deletions(-) diff --git a/config/config.exs b/config/config.exs index e6a4eb3e6..f13c12fb9 100644 --- a/config/config.exs +++ b/config/config.exs @@ -979,6 +979,8 @@ config :pleroma, :database_config_whitelist, [ {:web_push_encryption, :vapid_details} ] +config :pleroma, Pleroma.Chat, enabled: true + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env()}.exs" diff --git a/config/description.exs b/config/description.exs index 7c377588c..8ad640869 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2726,6 +2726,19 @@ config :pleroma, :config_description, [ } ] }, + %{ + group: :pleroma, + key: Pleroma.Chat, + type: :group, + description: "Pleroma Chat settings", + children: [ + %{ + key: :enabled, + type: :boolean, + description: "Enables the backend chats API." + } + ] + }, %{ group: :pleroma, key: :http, diff --git a/lib/pleroma/chat.ex b/lib/pleroma/chat.ex index 926176bfa..6ac1b24b8 100644 --- a/lib/pleroma/chat.ex +++ b/lib/pleroma/chat.ex @@ -108,4 +108,6 @@ defmodule Pleroma.Chat do |> cast(%{pinned: false}, [:pinned]) |> Repo.update() end + + def enabled?, do: Pleroma.Config.get([__MODULE__, :enabled], true) end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 8847692c8..c273043e1 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -68,7 +68,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do capabilities = if is_boolean(user.accepts_chat_messages) do %{ - "acceptsChatMessages" => user.accepts_chat_messages + "acceptsChatMessages" => Pleroma.Chat.enabled?() and user.accepts_chat_messages } else %{} diff --git a/lib/pleroma/web/mastodon_api/mastodon_api.ex b/lib/pleroma/web/mastodon_api/mastodon_api.ex index d6f2dd3a3..a65326226 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api.ex @@ -385,6 +385,15 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPI do |> cast_params() |> Map.update(:include_types, [], fn include_types -> include_types end) + if "pleroma:chat_mention" in options.include_types and not Pleroma.Chat.enabled?() do + options + |> Map.update(:include_types, [], fn include_types -> + List.delete(include_types, "pleroma:chat_mention") + end) + else + options + end + if ("pleroma:report" not in options.include_types and User.privileged?(user, :reports_manage_reports)) or User.privileged?(user, :reports_manage_reports) do diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 5386c5a6c..407328372 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -287,6 +287,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do user.last_status_at && user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601() + accepts_chat_messages = Pleroma.Chat.enabled?() and user.accepts_chat_messages + %{ id: to_string(user.id), username: username_from_nickname(user.nickname), @@ -336,7 +338,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do relationship: relationship, skip_thread_containment: user.skip_thread_containment, background_image: image_url(user.background) |> MediaProxy.url(), - accepts_chat_messages: user.accepts_chat_messages, + accepts_chat_messages: accepts_chat_messages, favicon: favicon, avatar_description: avatar_description, header_description: header_description diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index 1a0f63ffa..efb15d26e 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -167,6 +167,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do def features do [ "pleroma_api", + if Config.get([Pleroma.Chat, :enabled], true) do + "chat" + end, "mastodon_api", "mastodon_api_grouped_notifications", "mastodon_api_streaming", diff --git a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex index ac9bb2779..9c9f17e86 100644 --- a/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/chat_controller.ex @@ -41,6 +41,7 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do ) plug(Pleroma.Web.ApiSpec.CastAndValidate, replace_params: false) + plug(:ensure_chats_enabled) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.ChatOperation @@ -244,4 +245,16 @@ defmodule Pleroma.Web.PleromaAPI.ChatController do _ -> nil end end + + defp ensure_chats_enabled(conn, _opts) do + if Chat.enabled?() do + conn + else + conn + |> put_status(:not_found) + |> put_view(Pleroma.Web.ErrorView) + |> render("404.json") + |> halt() + end + end end diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex index 120e94751..14d942c9f 100644 --- a/lib/pleroma/web/streamer.ex +++ b/lib/pleroma/web/streamer.ex @@ -289,15 +289,17 @@ defmodule Pleroma.Web.Streamer do defp do_stream(topic, {user, %MessageReference{} = cm_ref}) when topic in ["user", "user:pleroma_chat"] do - topic = "#{topic}:#{user.id}" + if Pleroma.Chat.enabled?() do + topic = "#{topic}:#{user.id}" - text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}, topic) + text = StreamerView.render("chat_update.json", %{chat_message_reference: cm_ref}, topic) - Registry.dispatch(@registry, topic, fn list -> - Enum.each(list, fn {pid, _auth} -> - send(pid, {:text, text}) + Registry.dispatch(@registry, topic, fn list -> + Enum.each(list, fn {pid, _auth} -> + send(pid, {:text, text}) + end) end) - end) + end end defp do_stream("user", %Activity{} = item) do From efb43a02fab5a69bfb59c07c5c4017ff4ab86eee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 24 Jul 2026 00:59:15 +0200 Subject: [PATCH 2/5] changelog MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- changelog.d/disabling-chats.change | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelog.d/disabling-chats.change diff --git a/changelog.d/disabling-chats.change b/changelog.d/disabling-chats.change new file mode 100644 index 000000000..579679a03 --- /dev/null +++ b/changelog.d/disabling-chats.change @@ -0,0 +1 @@ +Allow disabling Chats feature From 6ffa90a42a5cc0278c305ecb4305745650c5f26b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 24 Jul 2026 01:00:46 +0200 Subject: [PATCH 3/5] Include actual accepts_chat_messages in source field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- config/description.exs | 2 +- lib/pleroma/web/mastodon_api/views/account_view.ex | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/config/description.exs b/config/description.exs index 8ad640869..1293179b9 100644 --- a/config/description.exs +++ b/config/description.exs @@ -2735,7 +2735,7 @@ config :pleroma, :config_description, [ %{ key: :enabled, type: :boolean, - description: "Enables the backend chats API." + description: "Enables the chats API." } ] }, diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 407328372..1e3882fc6 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -393,6 +393,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do |> Kernel.put_in([:source, :pleroma, :show_role], user.show_role) |> Kernel.put_in([:source, :pleroma, :no_rich_text], user.no_rich_text) |> Kernel.put_in([:source, :pleroma, :show_birthday], user.show_birthday) + |> Kernel.put_in([:source, :pleroma, :accepts_chat_messages], user.accepts_chat_messages) end defp maybe_put_settings(data, _, _, _), do: data From 97b94a2f43d10f23c6227797e2660db2409409ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Fri, 24 Jul 2026 01:05:12 +0200 Subject: [PATCH 4/5] Update tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- .../web/api_spec/operations/chat_operation.ex | 28 +++++++++++++------ .../web/activity_pub/views/user_view_test.exs | 8 ++++++ .../controllers/chat_controller_test.exs | 8 ++++++ 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/chat_operation.ex b/lib/pleroma/web/api_spec/operations/chat_operation.ex index 76c2db57e..7bc39acc6 100644 --- a/lib/pleroma/web/api_spec/operations/chat_operation.ex +++ b/lib/pleroma/web/api_spec/operations/chat_operation.ex @@ -31,7 +31,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "The updated chat", "application/json", Chat - ) + ), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -56,7 +57,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "The read ChatMessage", "application/json", ChatMessage - ) + ), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -87,7 +89,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "The existing chat", "application/json", Chat - ) + ), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -118,7 +121,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "The created or existing chat", "application/json", Chat - ) + ), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -146,7 +150,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do Operation.parameter(:pinned, :query, BooleanLike.schema(), "Include only pinned chats") ], responses: %{ - 200 => Operation.response("The chats of the user", "application/json", chats_response()) + 200 => Operation.response("The chats of the user", "application/json", chats_response()), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -172,7 +177,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do | pagination_params() ], responses: %{ - 200 => Operation.response("The chats of the user", "application/json", chats_response()) + 200 => Operation.response("The chats of the user", "application/json", chats_response()), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -224,6 +230,7 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do ChatMessage ), 400 => Operation.response("Bad Request", "application/json", ApiError), + 404 => Operation.response("Not Found", "application/json", ApiError), 422 => Operation.response("MRF Rejection", "application/json", ApiError) }, security: [ @@ -249,7 +256,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do "The deleted ChatMessage", "application/json", ChatMessage - ) + ), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -268,7 +276,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do Operation.parameter(:id, :path, :string, "The id of the chat", required: true) ], responses: %{ - 200 => Operation.response("The existing chat", "application/json", Chat) + 200 => Operation.response("The existing chat", "application/json", Chat), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ @@ -287,7 +296,8 @@ defmodule Pleroma.Web.ApiSpec.ChatOperation do Operation.parameter(:id, :path, :string, "The id of the chat", required: true) ], responses: %{ - 200 => Operation.response("The existing chat", "application/json", Chat) + 200 => Operation.response("The existing chat", "application/json", Chat), + 404 => Operation.response("Not Found", "application/json", ApiError) }, security: [ %{ diff --git a/test/pleroma/web/activity_pub/views/user_view_test.exs b/test/pleroma/web/activity_pub/views/user_view_test.exs index a3f807ca9..1aed28d5b 100644 --- a/test/pleroma/web/activity_pub/views/user_view_test.exs +++ b/test/pleroma/web/activity_pub/views/user_view_test.exs @@ -220,5 +220,13 @@ defmodule Pleroma.Web.ActivityPub.UserViewTest do "acceptsChatMessages" ) end + + test "it returns false if chat is disabled" do + clear_config([Pleroma.Chat, :enabled], false) + user = insert(:user, accepts_chat_messages: true) + + assert %{"capabilities" => %{"acceptsChatMessages" => false}} = + UserView.render("user.json", user: user) + end end end diff --git a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs index 0dc0e7014..8244ba434 100644 --- a/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs +++ b/test/pleroma/web/pleroma_api/controllers/chat_controller_test.exs @@ -546,6 +546,14 @@ defmodule Pleroma.Web.PleromaAPI.ChatControllerTest do account_ids = Enum.map(result, &get_in(&1, ["account", "id"])) assert Enum.sort(account_ids) == Enum.sort([user2.id, user3.id]) end + + test "it returns 404 when chats are disabled", %{conn: conn} do + clear_config([Pleroma.Chat, :enabled], false) + + conn + |> get(unquote(tested_endpoint)) + |> json_response_and_validate_schema(404) + end end end end From 0862c8b88d2a5b48478cbb1e59b1c0314ebace53 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 24 Jul 2026 16:53:36 +0400 Subject: [PATCH 5/5] fix: advertise Chats feature flags correctly --- .../web/mastodon_api/views/instance_view.ex | 11 ++++--- .../mastodon_api/views/instance_view_test.exs | 31 +++++++++++++++++-- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex index efb15d26e..437e42580 100644 --- a/lib/pleroma/web/mastodon_api/views/instance_view.ex +++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex @@ -167,9 +167,6 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do def features do [ "pleroma_api", - if Config.get([Pleroma.Chat, :enabled], true) do - "chat" - end, "mastodon_api", "mastodon_api_grouped_notifications", "mastodon_api_streaming", @@ -205,8 +202,12 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do end, "pleroma_emoji_reactions", "pleroma_custom_emoji_reactions", - "pleroma_chat_messages", - "pleroma:pin_chats", + if Pleroma.Chat.enabled?() do + "pleroma_chat_messages" + end, + if Pleroma.Chat.enabled?() do + "pleroma:pin_chats" + end, if Config.get([:instance, :show_reactions]) do "exposable_reactions" end, diff --git a/test/pleroma/web/mastodon_api/views/instance_view_test.exs b/test/pleroma/web/mastodon_api/views/instance_view_test.exs index 66485be0e..5f1e21098 100644 --- a/test/pleroma/web/mastodon_api/views/instance_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/instance_view_test.exs @@ -114,8 +114,6 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do "quote_posting", "pleroma_emoji_reactions", "pleroma_custom_emoji_reactions", - "pleroma_chat_messages", - "pleroma:pin_chats", "pleroma:get:main/ostatus", "pleroma:group_actors", "pleroma:bookmark_folders", @@ -128,6 +126,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do "gopher", "chat", "shout", + "pleroma_chat_messages", + "pleroma:pin_chats", "relay", "safe_dm_mentions", "exposable_reactions", @@ -139,6 +139,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do [:media_proxy, :enabled], [:gopher, :enabled], [:shout, :enabled], + [Pleroma.Chat, :enabled], [:instance, :allow_relay], [:instance, :safe_dm_mentions], [:instance, :show_reactions], @@ -443,6 +444,32 @@ defmodule Pleroma.Web.MastodonAPI.InstanceViewTest do end end + describe "chat features" do + test "advertises Shout without Chats" do + clear_config([:shout, :enabled], true) + clear_config([Pleroma.Chat, :enabled], false) + + features = InstanceView.features() + + assert "chat" in features + assert "shout" in features + refute "pleroma_chat_messages" in features + refute "pleroma:pin_chats" in features + end + + test "advertises Chats without Shout" do + clear_config([:shout, :enabled], false) + clear_config([Pleroma.Chat, :enabled], true) + + features = InstanceView.features() + + refute "chat" in features + refute "shout" in features + assert "pleroma_chat_messages" in features + assert "pleroma:pin_chats" in features + end + end + describe "federation/0" do setup do: clear_config([:mrf, :transparency], true)