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