From d310f99d6aa777aa03215c29f469140221716f9f Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Mon, 22 May 2023 23:53:44 +0100 Subject: [PATCH 01/10] Add MRFs for direct message manipulation --- .../akkoma/translators/libre_translate.ex | 4 +- lib/pleroma/user.ex | 15 ++++++ lib/pleroma/web/activity_pub/mrf.ex | 3 +- .../mrf/direct_message_disabled_policy.ex | 46 +++++++++++++++++ ...eject_newly_created_account_note_policy.ex | 49 +++++++++++++++++++ .../api_spec/operations/account_operation.ex | 11 +++++ ...2213837_add_unfollowed_dm_restrictions.exs | 10 ++++ .../translators/libre_translate_test.exs | 3 +- test/pleroma/user_test.exs | 32 ++++++++++++ .../direct_message_disabled_policy_test.exs | 42 ++++++++++++++++ 10 files changed, 210 insertions(+), 5 deletions(-) create mode 100644 lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex create mode 100644 lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex create mode 100644 priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs create mode 100644 test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs diff --git a/lib/pleroma/akkoma/translators/libre_translate.ex b/lib/pleroma/akkoma/translators/libre_translate.ex index 5b08a6384..80956ab66 100644 --- a/lib/pleroma/akkoma/translators/libre_translate.ex +++ b/lib/pleroma/akkoma/translators/libre_translate.ex @@ -39,9 +39,9 @@ def translate(string, from_language, to_language) do detected = if Map.has_key?(body, "detectedLanguage") do get_in(body, ["detectedLanguage", "language"]) - else + else from_language || "" - end + end {:ok, detected, translated} else diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index ead37ccca..7f4dccf27 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -158,6 +158,8 @@ defmodule Pleroma.User do field(:last_status_at, :naive_datetime) field(:language, :string) field(:status_ttl_days, :integer, default: nil) + field(:accepts_direct_messages_from_followed, :boolean) + field(:accepts_direct_messages_from_not_followed, :boolean) embeds_one( :notification_settings, @@ -2722,4 +2724,17 @@ def unfollow_hashtag(%User{} = user, %Hashtag{} = hashtag) do def following_hashtag?(%User{} = user, %Hashtag{} = hashtag) do not is_nil(HashtagFollow.get(user, hashtag)) end + + def accepts_direct_messages?(%User{} = receiver, %User{} = sender) do + cond do + User.following?(receiver, sender) && receiver.accepts_direct_messages_from_followed == true -> + true + + receiver.accepts_direct_messages_from_not_followed == true -> + true + + true -> + false + end + end end diff --git a/lib/pleroma/web/activity_pub/mrf.ex b/lib/pleroma/web/activity_pub/mrf.ex index 6ecd62c99..88a58421e 100644 --- a/lib/pleroma/web/activity_pub/mrf.ex +++ b/lib/pleroma/web/activity_pub/mrf.ex @@ -147,7 +147,8 @@ def get_policies do |> Enum.concat([ Pleroma.Web.ActivityPub.MRF.HashtagPolicy, Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy, - Pleroma.Web.ActivityPub.MRF.NormalizeMarkup + Pleroma.Web.ActivityPub.MRF.NormalizeMarkup, + Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy ]) |> Enum.uniq() end diff --git a/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex new file mode 100644 index 000000000..27a59c4f1 --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex @@ -0,0 +1,46 @@ +defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do + @behaviour Pleroma.Web.ActivityPub.MRF.Policy + + alias Pleroma.User + alias Pleroma.Web.ActivityPub.Visibility + + @moduledoc """ + Removes entries from the "To" field from direct messages if the user has requested to not + allow direct messages + """ + + @impl true + def filter( + %{ + "type" => "Note", + "actor" => actor + } = activity + ) do + with true <- Visibility.is_direct?(%{data: activity}), + recipients <- Map.get(activity, "to"), + sender <- User.get_cached_by_ap_id(actor) do + new_to = + Enum.filter(recipients, fn recv -> + should_filter?(sender, recv) + end) + + {:ok, Map.put(activity, :to, new_to)} + else + _ -> {:ok, activity} + end + end + + @impl true + def filter(object), do: {:ok, object} + + @impl true + def describe, do: {:ok, %{}} + + defp should_filter?(sender, receiver_ap_id) do + with %User{local: true} = receiver <- User.get_cached_by_ap_id(receiver_ap_id) do + User.accepts_direct_messages?(receiver, sender) + else + _ -> false + end + end +end diff --git a/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex new file mode 100644 index 000000000..4a2ab759a --- /dev/null +++ b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex @@ -0,0 +1,49 @@ +defmodule Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy do + @behaviour Pleroma.Web.ActivityPub.MRF.Policy + + alias Pleroma.User + + @moduledoc """ + Rejects notes from accounts that were created below a certain threshold of time ago + """ + @impl true + def filter( + %{ + "type" => type, + "actor" => actor + } = activity + ) when type in ["Note", "Create"] do + min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age]) + + with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor), + true <- Timex.diff(Timex.now(), user.inserted_at, :seconds) < min_age do + {:reject, "Account created too recently"} + else + _ -> {:ok, activity} + end + end + + @impl true + def filter(object), do: {:ok, object} + + @impl true + def describe, do: {:ok, %{}} + + @impl true + def config_description do + %{ + key: :mrf_reject_newly_created_account_notes, + related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy", + label: "MRF Reject New Accounts", + description: "Reject notes from accounts created too recently", + children: [ + %{ + key: :age, + type: :integer, + description: "Time below which to reject (in seconds)", + suggestions: [86_400] + } + ] + } + end +end diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 894ad5db0..7971b5363 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -708,6 +708,17 @@ defp update_credentials_request do nullable: true, description: "Number of days after which statuses will be deleted. Set to -1 to disable." + }, + accepts_direct_messages_from_followed: %Schema{ + type: :boolean, + nullable: true, + description: + "Whether to accept DMs from people you follow (will be overridden by accepts_direct_messages_from_not_followed if true)" + }, + accepts_direct_messages_from_not_followed: %Schema{ + type: :boolean, + nullable: true, + description: "Whether to accept DMs from everyone" } }, example: %{ diff --git a/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs b/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs new file mode 100644 index 000000000..a373b11ee --- /dev/null +++ b/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs @@ -0,0 +1,10 @@ +defmodule Pleroma.Repo.Migrations.AddUnfollowedDmRestrictions do + use Ecto.Migration + + def change do + alter table(:users) do + add(:accepts_direct_messages_from_followed, :boolean, default: true) + add(:accepts_direct_messages_from_not_followed, :boolean, default: true) + end + end +end diff --git a/test/pleroma/translators/libre_translate_test.exs b/test/pleroma/translators/libre_translate_test.exs index a93f408f5..2ba75ec0e 100644 --- a/test/pleroma/translators/libre_translate_test.exs +++ b/test/pleroma/translators/libre_translate_test.exs @@ -146,8 +146,7 @@ test "should work when no detected language is received" do } end) - assert {:ok, "", "I will crush you"} = - LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") + assert {:ok, "", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en") end end end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 12ccc6bf4..094799968 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -2756,4 +2756,36 @@ test "should not error when trying to unfollow a hashtag twice" do assert user.followed_hashtags |> Enum.count() == 0 end end + + describe "accepts_direct_messages?/2" do + test "should return true if the recipient follows the sender and has turned on 'accept from follows'" do + recipient = + insert(:user, %{ + accepts_direct_messages_from_followed: true, + accepts_direct_messages_from_not_followed: false + }) + + sender = insert(:user) + + refute User.accepts_direct_messages?(recipient, sender) + + CommonAPI.follow(recipient, sender) + + assert User.accepts_direct_messages?(recipient, sender) + end + + test "should return true if the recipient has 'accept from everyone' on" do + recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true}) + sender = insert(:user) + + assert User.accepts_direct_messages?(recipient, sender) + end + + test "should return false if the receipient has 'accept from everyone' off" do + recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false}) + sender = insert(:user) + + refute User.accepts_direct_messages?(recipient, sender) + end + end end diff --git a/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs new file mode 100644 index 000000000..50ed36a0b --- /dev/null +++ b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs @@ -0,0 +1,42 @@ +defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicyTest do + use Pleroma.DataCase + import Pleroma.Factory + + alias Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy + alias Pleroma.User + + describe "strips recipients" do + test "when the user denies the direct message" do + sender = insert(:user) + recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false}) + + refute User.accepts_direct_messages?(recipient, sender) + + message = %{ + "actor" => sender.ap_id, + "to" => [recipient.ap_id], + "cc" => [], + "type" => "Note" + } + + assert {:ok, %{to: []}} = DirectMessageDisabledPolicy.filter(message) + end + + test "when the user does not deny the direct message" do + sender = insert(:user) + recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true}) + + assert User.accepts_direct_messages?(recipient, sender) + + message = %{ + "actor" => sender.ap_id, + "to" => [recipient.ap_id], + "cc" => [], + "type" => "Note" + } + + assert {:ok, message} = DirectMessageDisabledPolicy.filter(message) + assert message.to == [recipient.ap_id] + end + end +end From ab34680554adb8864e910eb59d6c9150263bc88c Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 10:29:08 +0100 Subject: [PATCH 02/10] switch to using an enum system for DM acceptance --- lib/pleroma/user.ex | 30 +++++++------ ...eject_newly_created_account_note_policy.ex | 3 +- .../api_spec/operations/account_operation.ex | 19 ++++---- .../controllers/account_controller.ex | 3 +- .../web/mastodon_api/views/account_view.ex | 1 + ...2213837_add_unfollowed_dm_restrictions.exs | 3 +- test/pleroma/user_test.exs | 13 +++--- .../mastodon_api/update_credentials_test.exs | 44 +++++++++++++++++++ 8 files changed, 82 insertions(+), 34 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 7f4dccf27..371dea85b 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -158,8 +158,10 @@ defmodule Pleroma.User do field(:last_status_at, :naive_datetime) field(:language, :string) field(:status_ttl_days, :integer, default: nil) - field(:accepts_direct_messages_from_followed, :boolean) - field(:accepts_direct_messages_from_not_followed, :boolean) + + field(:accepts_direct_messages_from, Ecto.Enum, + values: [:everybody, :people_i_follow, :nobody] + ) embeds_one( :notification_settings, @@ -538,7 +540,8 @@ def update_changeset(struct, params \\ %{}) do :is_discoverable, :actor_type, :disclose_client, - :status_ttl_days + :status_ttl_days, + :accepts_direct_messages_from ] ) |> unique_constraint(:nickname) @@ -2725,16 +2728,15 @@ def following_hashtag?(%User{} = user, %Hashtag{} = hashtag) do not is_nil(HashtagFollow.get(user, hashtag)) end - def accepts_direct_messages?(%User{} = receiver, %User{} = sender) do - cond do - User.following?(receiver, sender) && receiver.accepts_direct_messages_from_followed == true -> - true - - receiver.accepts_direct_messages_from_not_followed == true -> - true - - true -> - false - end + def accepts_direct_messages?( + %User{accepts_direct_messages_from: :people_i_follow} = receiver, + %User{} = sender + ) do + User.following?(receiver, sender) end + + def accepts_direct_messages?(%User{accepts_direct_messages_from: :everybody}, _), do: true + + def accepts_direct_messages?(%User{accepts_direct_messages_from: :nobody}, _), + do: false end diff --git a/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex index 4a2ab759a..5481f38de 100644 --- a/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex @@ -12,7 +12,8 @@ def filter( "type" => type, "actor" => actor } = activity - ) when type in ["Note", "Create"] do + ) + when type in ["Note", "Create"] do min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age]) with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor), diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 7971b5363..8a46ec32a 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -709,16 +709,16 @@ defp update_credentials_request do description: "Number of days after which statuses will be deleted. Set to -1 to disable." }, - accepts_direct_messages_from_followed: %Schema{ - type: :boolean, + accepts_direct_messages_from: %Schema{ + type: :string, + enum: [ + "everybody", + "nobody", + "people_i_follow" + ], nullable: true, description: - "Whether to accept DMs from people you follow (will be overridden by accepts_direct_messages_from_not_followed if true)" - }, - accepts_direct_messages_from_not_followed: %Schema{ - type: :boolean, - nullable: true, - description: "Whether to accept DMs from everyone" + "Who to accept DMs from" } }, example: %{ @@ -740,7 +740,8 @@ defp update_credentials_request do also_known_as: ["https://foo.bar/users/foo"], discoverable: false, actor_type: "Person", - status_ttl_days: 30 + status_ttl_days: 30, + accepts_direct_messages_from: "everybody" } } end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 678ec3a80..16b3e36a8 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -191,7 +191,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p :show_role, :skip_thread_containment, :allow_following_move, - :also_known_as + :also_known_as, ] |> Enum.reduce(%{}, fn key, acc -> Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)}) @@ -221,6 +221,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p |> Maps.put_if_present(:is_discoverable, params[:discoverable]) |> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language])) |> Maps.put_if_present(:status_ttl_days, params[:status_ttl_days], status_ttl_days_value) + |> Maps.put_if_present(:accepts_direct_messages_from, params[:accepts_direct_messages_from]) # What happens here: # diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 190d6ebf2..e0fa3b033 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -354,6 +354,7 @@ defp maybe_put_settings( |> Kernel.put_in([:source, :privacy], user.default_scope) |> 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([:accepts_direct_messages_from], user.accepts_direct_messages_from) end defp maybe_put_settings(data, _, _, _), do: data diff --git a/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs b/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs index a373b11ee..8947be738 100644 --- a/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs +++ b/priv/repo/migrations/20230522213837_add_unfollowed_dm_restrictions.exs @@ -3,8 +3,7 @@ defmodule Pleroma.Repo.Migrations.AddUnfollowedDmRestrictions do def change do alter table(:users) do - add(:accepts_direct_messages_from_followed, :boolean, default: true) - add(:accepts_direct_messages_from_not_followed, :boolean, default: true) + add(:accepts_direct_messages_from, :string, default: "everybody") end end end diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 094799968..f35a98f08 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -2758,11 +2758,10 @@ test "should not error when trying to unfollow a hashtag twice" do end describe "accepts_direct_messages?/2" do - test "should return true if the recipient follows the sender and has turned on 'accept from follows'" do + test "should return true if the recipient follows the sender and has set accept to :people_i_follow" do recipient = insert(:user, %{ - accepts_direct_messages_from_followed: true, - accepts_direct_messages_from_not_followed: false + accepts_direct_messages_from: :people_i_follow }) sender = insert(:user) @@ -2774,15 +2773,15 @@ test "should return true if the recipient follows the sender and has turned on ' assert User.accepts_direct_messages?(recipient, sender) end - test "should return true if the recipient has 'accept from everyone' on" do - recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true}) + test "should return true if the recipient has set accept to :everyone" do + recipient = insert(:user, %{accepts_direct_messages_from: :everybody}) sender = insert(:user) assert User.accepts_direct_messages?(recipient, sender) end - test "should return false if the receipient has 'accept from everyone' off" do - recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false}) + test "should return false if the receipient set accept to :nobody" do + recipient = insert(:user, %{accepts_direct_messages_from: :nobody}) sender = insert(:user) refute User.accepts_direct_messages?(recipient, sender) diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index 4aec31eac..925ea25aa 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -727,4 +727,48 @@ test "actor_type field has a higher priority than bot", %{conn: conn} do assert account["source"]["pleroma"]["actor_type"] == "Person" end end + + describe "Updating direct message settings" do + setup do: oauth_access(["write:accounts"]) + setup :request_content_type + + test "changing to :everybody", %{conn: conn} do + account = + conn + |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "everybody"}) + |> json_response_and_validate_schema(200) + + assert account["accepts_direct_messages_from"] + assert account["accepts_direct_messages_from"] == "everybody" + assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :everybody + end + + test "changing to :nobody", %{conn: conn} do + account = + conn + |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "nobody"}) + |> json_response_and_validate_schema(200) + + assert account["accepts_direct_messages_from"] + assert account["accepts_direct_messages_from"] == "nobody" + assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :nobody + end + + test "changing to :people_i_follow", %{conn: conn} do + account = + conn + |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "people_i_follow"}) + |> json_response_and_validate_schema(200) + + assert account["accepts_direct_messages_from"] + assert account["accepts_direct_messages_from"] == "people_i_follow" + assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :people_i_follow + end + + test "changing to an unsupported value", %{conn: conn} do + conn + |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "unsupported"}) + |> json_response(400) + end + end end From 037f881187f1d7ec29efbf75f76dbc8b135b65cd Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 13:16:20 +0100 Subject: [PATCH 03/10] Fix create processing in direct message disabled --- CHANGELOG.md | 9 ++++ config/config.exs | 2 + lib/pleroma/user.ex | 3 +- .../mrf/direct_message_disabled_policy.ex | 16 +++++-- ...eject_newly_created_account_note_policy.ex | 4 +- .../api_spec/operations/account_operation.ex | 3 +- .../controllers/account_controller.ex | 2 +- .../direct_message_disabled_policy_test.exs | 12 ++--- ...newly_created_account_note_policy_test.exs | 45 +++++++++++++++++++ test/pleroma/web/activity_pub/mrf_test.exs | 16 ++++++- .../transmogrifier/note_handling_test.exs | 8 ++-- .../mastodon_api/update_credentials_test.exs | 16 +++++-- 12 files changed, 111 insertions(+), 25 deletions(-) create mode 100644 test/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy_test.exs diff --git a/CHANGELOG.md b/CHANGELOG.md index bb5b8fa04..207c99d67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,8 +6,17 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## Unreleased +## Added +- Custom options for users to accept/reject private messages + - options: everybody, nobody, people\_i\_follow +- MRF to reject notes from accounts newer than a given age + - this will have the side-effect of rejecting legitimate messages if your + post gets boosted outside of your local bubble and people your instance + does not know about reply to it. + ## Fixed - Support for `streams` public key URIs +- Bookmarks are cleaned up on DB prune now ## 2023.04 diff --git a/config/config.exs b/config/config.exs index 95c576385..ca397a8fd 100644 --- a/config/config.exs +++ b/config/config.exs @@ -418,6 +418,8 @@ config :pleroma, :mrf_follow_bot, follower_nickname: nil +config :pleroma, :mrf_reject_newly_created_account_notes, age: 86_400 + config :pleroma, :rich_media, enabled: true, ignore_hosts: [], diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 371dea85b..273bdf337 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -160,7 +160,8 @@ defmodule Pleroma.User do field(:status_ttl_days, :integer, default: nil) field(:accepts_direct_messages_from, Ecto.Enum, - values: [:everybody, :people_i_follow, :nobody] + values: [:everybody, :people_i_follow, :nobody], + default: :everybody ) embeds_one( diff --git a/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex index 27a59c4f1..ec6fa70e2 100644 --- a/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex @@ -12,7 +12,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do @impl true def filter( %{ - "type" => "Note", + "type" => "Create", "actor" => actor } = activity ) do @@ -24,9 +24,13 @@ def filter( should_filter?(sender, recv) end) - {:ok, Map.put(activity, :to, new_to)} + {:ok, + activity + |> Map.put("to", new_to) + |> maybe_replace_object_to(new_to)} else - _ -> {:ok, activity} + _ -> + {:ok, activity} end end @@ -43,4 +47,10 @@ defp should_filter?(sender, receiver_ap_id) do _ -> false end end + + defp maybe_replace_object_to(%{"object" => %{"to" => _}} = activity, to) do + Kernel.put_in(activity, ["object", "to"], to) + end + + defp maybe_replace_object_to(other, _), do: other end diff --git a/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex index 5481f38de..01a846831 100644 --- a/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy.ex @@ -16,9 +16,9 @@ def filter( when type in ["Note", "Create"] do min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age]) - with %User{} = user <- Pleroma.User.get_cached_by_ap_id(actor), + with %User{local: false} = user <- Pleroma.User.get_cached_by_ap_id(actor), true <- Timex.diff(Timex.now(), user.inserted_at, :seconds) < min_age do - {:reject, "Account created too recently"} + {:reject, "[RejectNewlyCreatedAccountNotesPolicy] Account created too recently"} else _ -> {:ok, activity} end diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 8a46ec32a..8a6851d52 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -717,8 +717,7 @@ defp update_credentials_request do "people_i_follow" ], nullable: true, - description: - "Who to accept DMs from" + description: "Who to accept DMs from" } }, example: %{ diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 16b3e36a8..057af762a 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -191,7 +191,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p :show_role, :skip_thread_containment, :allow_following_move, - :also_known_as, + :also_known_as ] |> Enum.reduce(%{}, fn key, acc -> Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)}) diff --git a/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs index 50ed36a0b..072fe0576 100644 --- a/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs @@ -8,7 +8,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicyTest do describe "strips recipients" do test "when the user denies the direct message" do sender = insert(:user) - recipient = insert(:user, %{accepts_direct_messages_from_not_followed: false}) + recipient = insert(:user, %{accepts_direct_messages_from: :nobody}) refute User.accepts_direct_messages?(recipient, sender) @@ -16,15 +16,15 @@ test "when the user denies the direct message" do "actor" => sender.ap_id, "to" => [recipient.ap_id], "cc" => [], - "type" => "Note" + "type" => "Create" } - assert {:ok, %{to: []}} = DirectMessageDisabledPolicy.filter(message) + assert {:ok, %{"to" => []}} = DirectMessageDisabledPolicy.filter(message) end test "when the user does not deny the direct message" do sender = insert(:user) - recipient = insert(:user, %{accepts_direct_messages_from_not_followed: true}) + recipient = insert(:user, %{accepts_direct_messages_from: :everybody}) assert User.accepts_direct_messages?(recipient, sender) @@ -32,11 +32,11 @@ test "when the user does not deny the direct message" do "actor" => sender.ap_id, "to" => [recipient.ap_id], "cc" => [], - "type" => "Note" + "type" => "Create" } assert {:ok, message} = DirectMessageDisabledPolicy.filter(message) - assert message.to == [recipient.ap_id] + assert message["to"] == [recipient.ap_id] end end end diff --git a/test/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy_test.exs b/test/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy_test.exs new file mode 100644 index 000000000..2fc65e6d6 --- /dev/null +++ b/test/pleroma/web/activity_pub/mrf/reject_newly_created_account_note_policy_test.exs @@ -0,0 +1,45 @@ +defmodule Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicyTest do + use Pleroma.DataCase + import Pleroma.Factory + + alias Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy + + describe "reject notes from new accounts" do + test "rejects notes from accounts created more recently than `age`" do + clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400) + sender = insert(:user, %{inserted_at: Timex.now(), local: false}) + + message = %{ + "actor" => sender.ap_id, + "type" => "Create" + } + + assert {:reject, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message) + end + + test "does not reject notes from accounts created longer ago" do + clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400) + a_day_ago = Timex.shift(Timex.now(), days: -1) + sender = insert(:user, %{inserted_at: a_day_ago, local: false}) + + message = %{ + "actor" => sender.ap_id, + "type" => "Create" + } + + assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message) + end + + test "does not affect local users" do + clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400) + sender = insert(:user, %{inserted_at: Timex.now(), local: true}) + + message = %{ + "actor" => sender.ap_id, + "type" => "Create" + } + + assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message) + end + end +end diff --git a/test/pleroma/web/activity_pub/mrf_test.exs b/test/pleroma/web/activity_pub/mrf_test.exs index 7359398fe..51af672cd 100644 --- a/test/pleroma/web/activity_pub/mrf_test.exs +++ b/test/pleroma/web/activity_pub/mrf_test.exs @@ -102,7 +102,13 @@ test "it works as expected with noop policy" do clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.NoOpPolicy]) expected = %{ - mrf_policies: ["NoOpPolicy", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"], + mrf_policies: [ + "NoOpPolicy", + "HashtagPolicy", + "InlineQuotePolicy", + "NormalizeMarkup", + "DirectMessageDisabledPolicy" + ], mrf_hashtag: %{ federated_timeline_removal: [], reject: [], @@ -118,7 +124,13 @@ test "it works as expected with mock policy" do clear_config([:mrf, :policies], [MRFModuleMock]) expected = %{ - mrf_policies: ["MRFModuleMock", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"], + mrf_policies: [ + "MRFModuleMock", + "HashtagPolicy", + "InlineQuotePolicy", + "NormalizeMarkup", + "DirectMessageDisabledPolicy" + ], mrf_module_mock: "some config data", mrf_hashtag: %{ federated_timeline_removal: [], diff --git a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs index 002042802..9faee7aa3 100644 --- a/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier/note_handling_test.exs @@ -316,7 +316,7 @@ test "it strips internal reactions" do test "it correctly processes messages with non-array to field" do data = File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("to", "https://www.w3.org/ns/activitystreams#Public") |> put_in(["object", "to"], "https://www.w3.org/ns/activitystreams#Public") @@ -333,7 +333,7 @@ test "it correctly processes messages with non-array to field" do test "it correctly processes messages with non-array cc field" do data = File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("cc", "http://mastodon.example.org/users/admin/followers") |> put_in(["object", "cc"], "http://mastodon.example.org/users/admin/followers") @@ -346,7 +346,7 @@ test "it correctly processes messages with non-array cc field" do test "it correctly processes messages with weirdness in address fields" do data = File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Map.put("cc", ["http://mastodon.example.org/users/admin/followers", ["¿"]]) |> put_in(["object", "cc"], ["http://mastodon.example.org/users/admin/followers", ["¿"]]) @@ -412,7 +412,7 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth activity = File.read!("test/fixtures/mastodon-post-activity.json") - |> Poison.decode!() + |> Jason.decode!() |> Kernel.put_in(["object", "replies"], replies) %{activity: activity} diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index 925ea25aa..70566f5d0 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -735,7 +735,9 @@ test "actor_type field has a higher priority than bot", %{conn: conn} do test "changing to :everybody", %{conn: conn} do account = conn - |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "everybody"}) + |> patch("/api/v1/accounts/update_credentials", %{ + accepts_direct_messages_from: "everybody" + }) |> json_response_and_validate_schema(200) assert account["accepts_direct_messages_from"] @@ -757,17 +759,23 @@ test "changing to :nobody", %{conn: conn} do test "changing to :people_i_follow", %{conn: conn} do account = conn - |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "people_i_follow"}) + |> patch("/api/v1/accounts/update_credentials", %{ + accepts_direct_messages_from: "people_i_follow" + }) |> json_response_and_validate_schema(200) assert account["accepts_direct_messages_from"] assert account["accepts_direct_messages_from"] == "people_i_follow" - assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :people_i_follow + + assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == + :people_i_follow end test "changing to an unsupported value", %{conn: conn} do conn - |> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "unsupported"}) + |> patch("/api/v1/accounts/update_credentials", %{ + accepts_direct_messages_from: "unsupported" + }) |> json_response(400) end end From 8c208f751d619f6015378dff34933e036f05ee9f Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 13:46:25 +0100 Subject: [PATCH 04/10] Fix filtering out incorrect addresses --- .../mrf/direct_message_disabled_policy.ex | 23 +++++++++++++------ .../direct_message_disabled_policy_test.exs | 16 ++++++++++--- 2 files changed, 29 insertions(+), 10 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex index ec6fa70e2..7a834f6ae 100644 --- a/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/direct_message_disabled_policy.ex @@ -2,7 +2,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do @behaviour Pleroma.Web.ActivityPub.MRF.Policy alias Pleroma.User - alias Pleroma.Web.ActivityPub.Visibility + require Pleroma.Constants @moduledoc """ Removes entries from the "To" field from direct messages if the user has requested to not @@ -13,15 +13,19 @@ defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do def filter( %{ "type" => "Create", - "actor" => actor + "actor" => actor, + "object" => %{ + "type" => "Note" + } } = activity ) do - with true <- Visibility.is_direct?(%{data: activity}), - recipients <- Map.get(activity, "to"), + with recipients <- Map.get(activity, "to", []), + cc <- Map.get(activity, "cc", []), + true <- is_direct?(recipients, cc), sender <- User.get_cached_by_ap_id(actor) do new_to = Enum.filter(recipients, fn recv -> - should_filter?(sender, recv) + should_include?(sender, recv) end) {:ok, @@ -40,11 +44,11 @@ def filter(object), do: {:ok, object} @impl true def describe, do: {:ok, %{}} - defp should_filter?(sender, receiver_ap_id) do + defp should_include?(sender, receiver_ap_id) do with %User{local: true} = receiver <- User.get_cached_by_ap_id(receiver_ap_id) do User.accepts_direct_messages?(receiver, sender) else - _ -> false + _ -> true end end @@ -53,4 +57,9 @@ defp maybe_replace_object_to(%{"object" => %{"to" => _}} = activity, to) do end defp maybe_replace_object_to(other, _), do: other + + defp is_direct?(to, cc) do + !(Enum.member?(to, Pleroma.Constants.as_public()) || + Enum.member?(cc, Pleroma.Constants.as_public())) + end end diff --git a/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs index 072fe0576..02ae24a4d 100644 --- a/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/direct_message_disabled_policy_test.exs @@ -16,10 +16,15 @@ test "when the user denies the direct message" do "actor" => sender.ap_id, "to" => [recipient.ap_id], "cc" => [], - "type" => "Create" + "type" => "Create", + "object" => %{ + "type" => "Note", + "to" => [recipient.ap_id] + } } - assert {:ok, %{"to" => []}} = DirectMessageDisabledPolicy.filter(message) + assert {:ok, %{"to" => [], "object" => %{"to" => []}}} = + DirectMessageDisabledPolicy.filter(message) end test "when the user does not deny the direct message" do @@ -32,11 +37,16 @@ test "when the user does not deny the direct message" do "actor" => sender.ap_id, "to" => [recipient.ap_id], "cc" => [], - "type" => "Create" + "type" => "Create", + "object" => %{ + "type" => "Note", + "to" => [recipient.ap_id] + } } assert {:ok, message} = DirectMessageDisabledPolicy.filter(message) assert message["to"] == [recipient.ap_id] + assert message["object"]["to"] == [recipient.ap_id] end end end From 2fc26609f6a413adec812c16f31c7bbc2ec21dbd Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 13:53:54 +0100 Subject: [PATCH 05/10] ensure we depend on poison --- mix.exs | 1 + 1 file changed, 1 insertion(+) diff --git a/mix.exs b/mix.exs index 2f318fea0..f81a1a8a9 100644 --- a/mix.exs +++ b/mix.exs @@ -190,6 +190,7 @@ defp deps do {:mfm_parser, git: "https://akkoma.dev/AkkomaGang/mfm-parser.git", ref: "912fba81152d4d572e457fd5427f9875b2bc3dbe"}, + {:poison, "~> 5.0"}, ## dev & test {:ex_doc, "~> 0.22", only: :dev, runtime: false}, From 9e9cf58fdfb99e0d2e6112d824cc56daef9f8cd8 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 13:54:22 +0100 Subject: [PATCH 06/10] or not --- mix.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/mix.exs b/mix.exs index f81a1a8a9..2f318fea0 100644 --- a/mix.exs +++ b/mix.exs @@ -190,7 +190,6 @@ defp deps do {:mfm_parser, git: "https://akkoma.dev/AkkomaGang/mfm-parser.git", ref: "912fba81152d4d572e457fd5427f9875b2bc3dbe"}, - {:poison, "~> 5.0"}, ## dev & test {:ex_doc, "~> 0.22", only: :dev, runtime: false}, From 82ca7a64705daf780e03d329b73fed4fed16af06 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Tue, 23 May 2023 14:10:01 +0100 Subject: [PATCH 07/10] bump version --- CHANGELOG.md | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 207c99d67..f6dd45e17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,7 +4,7 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## Unreleased +## 2023.05 ## Added - Custom options for users to accept/reject private messages diff --git a/mix.exs b/mix.exs index 2f318fea0..11fc15639 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do def project do [ app: :pleroma, - version: version("3.8.0"), + version: version("3.9.0"), elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix] ++ Mix.compilers(), From 9d83a1e23f3fde933ec990736fd77a8adb2e4803 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Fri, 26 May 2023 11:41:22 +0100 Subject: [PATCH 08/10] Add csp --- lib/pleroma/reverse_proxy.ex | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/pleroma/reverse_proxy.ex b/lib/pleroma/reverse_proxy.ex index 91cf1bba3..b44f0b90a 100644 --- a/lib/pleroma/reverse_proxy.ex +++ b/lib/pleroma/reverse_proxy.ex @@ -251,6 +251,7 @@ defp build_resp_headers(headers, opts) do |> Enum.filter(fn {k, _} -> k in @keep_resp_headers end) |> build_resp_cache_headers(opts) |> build_resp_content_disposition_header(opts) + |> build_csp_headers() |> Keyword.merge(Keyword.get(opts, :resp_headers, [])) end @@ -316,6 +317,10 @@ defp build_resp_content_disposition_header(headers, opts) do end end + defp build_csp_headers(headers) do + List.keystore(headers, "content-security-policy", 0, {"content-security-policy", "sandbox"}) + end + defp header_length_constraint(headers, limit) when is_integer(limit) and limit > 0 do with {_, size} <- List.keyfind(headers, "content-length", 0), {size, _} <- Integer.parse(size), From 7fb9960ccddfc078be28c1b2716eff07a90fa7b3 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Fri, 26 May 2023 11:46:18 +0100 Subject: [PATCH 09/10] Add CSP to mediaproxy links --- CHANGELOG.md | 3 +++ lib/pleroma/web/plugs/uploaded_media.ex | 2 +- mix.exs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f6dd45e17..97c73a267 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Support for `streams` public key URIs - Bookmarks are cleaned up on DB prune now +## Security +- Fixed mediaproxy being a bit of a silly billy + ## 2023.04 ## Added diff --git a/lib/pleroma/web/plugs/uploaded_media.ex b/lib/pleroma/web/plugs/uploaded_media.ex index 72f20e8de..cccbfe350 100644 --- a/lib/pleroma/web/plugs/uploaded_media.ex +++ b/lib/pleroma/web/plugs/uploaded_media.ex @@ -42,7 +42,7 @@ def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do conn -> conn end - |> merge_resp_headers([{"content-security-policy", "sandbox"}]) + |> merge_resp_headers([{"content-security-policy", "script-src none"}]) config = Pleroma.Config.get(Pleroma.Upload) diff --git a/mix.exs b/mix.exs index 11fc15639..b74f568c8 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do def project do [ app: :pleroma, - version: version("3.9.0"), + version: version("3.9.1"), elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix] ++ Mix.compilers(), From a388d2503e1563bc2441f859a254f0d7e868d095 Mon Sep 17 00:00:00 2001 From: FloatingGhost Date: Fri, 26 May 2023 12:06:41 +0100 Subject: [PATCH 10/10] revert uploaded-media --- lib/pleroma/web/plugs/uploaded_media.ex | 2 +- mix.exs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/plugs/uploaded_media.ex b/lib/pleroma/web/plugs/uploaded_media.ex index cccbfe350..72f20e8de 100644 --- a/lib/pleroma/web/plugs/uploaded_media.ex +++ b/lib/pleroma/web/plugs/uploaded_media.ex @@ -42,7 +42,7 @@ def call(%{request_path: <<"/", @path, "/", file::binary>>} = conn, opts) do conn -> conn end - |> merge_resp_headers([{"content-security-policy", "script-src none"}]) + |> merge_resp_headers([{"content-security-policy", "sandbox"}]) config = Pleroma.Config.get(Pleroma.Upload) diff --git a/mix.exs b/mix.exs index b74f568c8..5c97c4e8e 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do def project do [ app: :pleroma, - version: version("3.9.1"), + version: version("3.9.2"), elixir: "~> 1.14", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix] ++ Mix.compilers(),