diff options
Diffstat (limited to 'lib')
58 files changed, 530 insertions, 308 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex index 389c80691..8a512dc57 100644 --- a/lib/pleroma/activity.ex +++ b/lib/pleroma/activity.ex @@ -361,9 +361,11 @@ defmodule Pleroma.Activity do    end    def restrict_deactivated_users(query) do -    deactivated_users_query = from(u in User.Query.build(%{deactivated: true}), select: u.ap_id) - -    from(activity in query, where: activity.actor not in subquery(deactivated_users_query)) +    query +    |> join(:inner, [activity], user in User, +      as: :user, +      on: activity.actor == user.ap_id and user.is_active == true +    )    end    defdelegate search(user, query, options \\ []), to: Pleroma.Search.DatabaseSearch diff --git a/lib/pleroma/config/deprecation_warnings.ex b/lib/pleroma/config/deprecation_warnings.ex index 599f1d3cf..b53b15d95 100644 --- a/lib/pleroma/config/deprecation_warnings.ex +++ b/lib/pleroma/config/deprecation_warnings.ex @@ -311,7 +311,7 @@ defmodule Pleroma.Config.DeprecationWarnings do      warning_preface = """      !!!DEPRECATION WARNING!!! -    Your config is using old setting name `timeout` instead of `recv_timeout` in pool settings. Setting should work for now, but you are advised to change format to scheme with port to prevent possible issues later. +    Your config is using old setting name `timeout` instead of `recv_timeout` in pool settings. The setting will not take effect until updated.      """      updated_config = diff --git a/lib/pleroma/config/transfer_task.ex b/lib/pleroma/config/transfer_task.ex index 4199630af..44a984019 100644 --- a/lib/pleroma/config/transfer_task.ex +++ b/lib/pleroma/config/transfer_task.ex @@ -47,7 +47,7 @@ defmodule Pleroma.Config.TransferTask do        {logger, other} =          (Repo.all(ConfigDB) ++ deleted_settings)          |> Enum.map(&merge_with_default/1) -        |> Enum.split_with(fn {group, _, _, _} -> group in [:logger, :quack] end) +        |> Enum.split_with(fn {group, _, _, _} -> group in [:logger] end)        logger        |> Enum.sort() @@ -104,11 +104,6 @@ defmodule Pleroma.Config.TransferTask do    end    # change logger configuration in runtime, without restart -  defp configure({:quack, key, _, merged}) do -    Logger.configure_backend(Quack.Logger, [{key, merged}]) -    :ok = update_env(:quack, key, merged) -  end -    defp configure({_, :backends, _, merged}) do      # removing current backends      Enum.each(Application.get_env(:logger, :backends), &Logger.remove_backend/1) diff --git a/lib/pleroma/config_db.ex b/lib/pleroma/config_db.ex index 6befbbe19..846cede04 100644 --- a/lib/pleroma/config_db.ex +++ b/lib/pleroma/config_db.ex @@ -163,7 +163,6 @@ defmodule Pleroma.ConfigDB do    defp only_full_update?(%ConfigDB{group: group, key: key}) do      full_key_update = [        {:pleroma, :ecto_repos}, -      {:quack, :meta},        {:mime, :types},        {:cors_plug, [:max_age, :methods, :expose, :headers]},        {:swarm, :node_blacklist}, @@ -386,7 +385,7 @@ defmodule Pleroma.ConfigDB do    @spec module_name?(String.t()) :: boolean()    def module_name?(string) do -    Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Quack|Ueberauth|Swoosh)\./, string) or +    Regex.match?(~r/^(Pleroma|Phoenix|Tesla|Ueberauth|Swoosh)\./, string) or        string in ["Oban", "Ueberauth", "ExSyslogger", "ConcurrentLimiter"]    end  end diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex index 2e82ceff2..d41061538 100644 --- a/lib/pleroma/http.ex +++ b/lib/pleroma/http.ex @@ -106,5 +106,12 @@ defmodule Pleroma.HTTP do      [Tesla.Middleware.FollowRedirects, Pleroma.Tesla.Middleware.ConnectionPool]    end -  defp adapter_middlewares(_), do: [] +  defp adapter_middlewares(_) do +    if Pleroma.Config.get(:env) == :test do +      # Emulate redirects in test env, which are handled by adapters in other environments +      [Tesla.Middleware.FollowRedirects] +    else +      [] +    end +  end  end diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex index d81fdcf24..a9a9eeeed 100644 --- a/lib/pleroma/object/fetcher.ex +++ b/lib/pleroma/object/fetcher.ex @@ -4,6 +4,7 @@  defmodule Pleroma.Object.Fetcher do    alias Pleroma.HTTP +  alias Pleroma.Instances    alias Pleroma.Maps    alias Pleroma.Object    alias Pleroma.Object.Containment @@ -234,6 +235,10 @@ defmodule Pleroma.Object.Fetcher do           {:ok, body} <- get_object(id),           {:ok, data} <- safe_json_decode(body),           :ok <- Containment.contain_origin_from_id(id, data) do +      if not Instances.reachable?(id) do +        Instances.set_reachable(id) +      end +        {:ok, data}      else        {:scheme, _} -> diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 85d3382cb..4f91b3ffc 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -611,7 +611,13 @@ defmodule Pleroma.User do           {:ok, new_value} <- value_function.(value) do        put_change(changeset, map_field, new_value)      else -      _ -> changeset +      {:error, :file_too_large} -> +        Ecto.Changeset.validate_change(changeset, map_field, fn map_field, _value -> +          [{map_field, "file is too large"}] +        end) + +      _ -> +        changeset      end    end @@ -905,7 +911,7 @@ defmodule Pleroma.User do      end    end -  defp send_user_approval_email(user) do +  defp send_user_approval_email(%User{email: email} = user) when is_binary(email) do      user      |> Pleroma.Emails.UserEmail.approval_pending_email()      |> Pleroma.Emails.Mailer.deliver_async() @@ -913,6 +919,10 @@ defmodule Pleroma.User do      {:ok, :enqueued}    end +  defp send_user_approval_email(_user) do +    {:ok, :skipped} +  end +    defp send_admin_approval_emails(user) do      all_superusers()      |> Enum.filter(fn user -> not is_nil(user.email) end) @@ -2126,7 +2136,8 @@ defmodule Pleroma.User do    @doc "Gets or fetch a user by uri or nickname."    @spec get_or_fetch(String.t()) :: {:ok, User.t()} | {:error, String.t()} -  def get_or_fetch("http" <> _host = uri), do: get_or_fetch_by_ap_id(uri) +  def get_or_fetch("http://" <> _host = uri), do: get_or_fetch_by_ap_id(uri) +  def get_or_fetch("https://" <> _host = uri), do: get_or_fetch_by_ap_id(uri)    def get_or_fetch(nickname), do: get_or_fetch_by_nickname(nickname)    # wait a period of time and return newest version of the User structs diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index cdc70aacf..6887710dc 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1242,15 +1242,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      end    end +  defp exclude_invisible_actors(query, %{type: "Flag"}), do: query    defp exclude_invisible_actors(query, %{invisible_actors: true}), do: query    defp exclude_invisible_actors(query, _opts) do -    invisible_ap_ids = -      User.Query.build(%{invisible: true, select: [:ap_id]}) -      |> Repo.all() -      |> Enum.map(fn %{ap_id: ap_id} -> ap_id end) - -    from([activity] in query, where: activity.actor not in ^invisible_ap_ids) +    query +    |> join(:inner, [activity], u in User, +      as: :u, +      on: activity.actor == u.ap_id and u.invisible == false +    )    end    defp exclude_id(query, %{exclude_id: id}) when is_binary(id) do @@ -1380,7 +1380,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do        |> restrict_instance(opts)        |> restrict_announce_object_actor(opts)        |> restrict_filtered(opts) -      |> Activity.restrict_deactivated_users() +      |> maybe_restrict_deactivated_users(opts)        |> exclude_poll_votes(opts)        |> exclude_chat_messages(opts)        |> exclude_invisible_actors(opts) @@ -1485,7 +1485,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    defp normalize_image(urls) when is_list(urls), do: urls |> List.first() |> normalize_image()    defp normalize_image(_), do: nil -  defp object_to_user_data(data) do +  defp object_to_user_data(data, additional) do      fields =        data        |> Map.get("attachment", []) @@ -1517,15 +1517,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      public_key =        if is_map(data["publicKey"]) && is_binary(data["publicKey"]["publicKeyPem"]) do          data["publicKey"]["publicKeyPem"] -      else -        nil        end      shared_inbox =        if is_map(data["endpoints"]) && is_binary(data["endpoints"]["sharedInbox"]) do          data["endpoints"]["sharedInbox"] -      else -        nil        end      birthday = @@ -1534,13 +1530,15 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do            {:ok, date} -> date            {:error, _} -> nil          end -      else -        nil        end      show_birthday = !!birthday -    user_data = %{ +    # if WebFinger request was already done, we probably have acct, otherwise +    # we request WebFinger here +    nickname = additional[:nickname_from_acct] || generate_nickname(data) + +    %{        ap_id: data["id"],        uri: get_actor_url(data["url"]),        ap_enabled: true, @@ -1562,23 +1560,29 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do        inbox: data["inbox"],        shared_inbox: shared_inbox,        accepts_chat_messages: accepts_chat_messages, -      pinned_objects: pinned_objects,        birthday: birthday, -      show_birthday: show_birthday +      show_birthday: show_birthday, +      pinned_objects: pinned_objects, +      nickname: nickname      } +  end -    # nickname can be nil because of virtual actors -    if data["preferredUsername"] do -      Map.put( -        user_data, -        :nickname, -        "#{data["preferredUsername"]}@#{URI.parse(data["id"]).host}" -      ) +  defp generate_nickname(%{"preferredUsername" => username} = data) when is_binary(username) do +    generated = "#{username}@#{URI.parse(data["id"]).host}" + +    if Config.get([WebFinger, :update_nickname_on_user_fetch]) do +      case WebFinger.finger(generated) do +        {:ok, %{"subject" => "acct:" <> acct}} -> acct +        _ -> generated +      end      else -      Map.put(user_data, :nickname, nil) +      generated      end    end +  # nickname can be nil because of virtual actors +  defp generate_nickname(_), do: nil +    def fetch_follow_information_for_user(user) do      with {:ok, following_data} <-             Fetcher.fetch_and_contain_remote_object_from_id(user.following_address), @@ -1650,17 +1654,17 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    defp collection_private(_data), do: {:ok, true} -  def user_data_from_user_object(data) do +  def user_data_from_user_object(data, additional \\ []) do      with {:ok, data} <- MRF.filter(data) do -      {:ok, object_to_user_data(data)} +      {:ok, object_to_user_data(data, additional)}      else        e -> {:error, e}      end    end -  def fetch_and_prepare_user_from_ap_id(ap_id) do +  def fetch_and_prepare_user_from_ap_id(ap_id, additional \\ []) do      with {:ok, data} <- Fetcher.fetch_and_contain_remote_object_from_id(ap_id), -         {:ok, data} <- user_data_from_user_object(data) do +         {:ok, data} <- user_data_from_user_object(data, additional) do        {:ok, maybe_update_follow_information(data)}      else        # If this has been deleted, only log a debug and not an error @@ -1738,13 +1742,13 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      end    end -  def make_user_from_ap_id(ap_id) do +  def make_user_from_ap_id(ap_id, additional \\ []) do      user = User.get_cached_by_ap_id(ap_id)      if user && !User.ap_enabled?(user) do        Transmogrifier.upgrade_user_from_ap_id(ap_id)      else -      with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id) do +      with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do          {:ok, _pid} = Task.start(fn -> pinned_fetch_task(data) end)          if user do @@ -1764,8 +1768,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do    end    def make_user_from_nickname(nickname) do -    with {:ok, %{"ap_id" => ap_id}} when not is_nil(ap_id) <- WebFinger.finger(nickname) do -      make_user_from_ap_id(ap_id) +    with {:ok, %{"ap_id" => ap_id, "subject" => "acct:" <> acct}} when not is_nil(ap_id) <- +           WebFinger.finger(nickname) do +      make_user_from_ap_id(ap_id, nickname_from_acct: acct)      else        _e -> {:error, "No AP id in WebFinger"}      end @@ -1787,4 +1792,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do      |> restrict_visibility(%{visibility: "direct"})      |> order_by([activity], asc: activity.id)    end + +  defp maybe_restrict_deactivated_users(activity, %{type: "Flag"}), do: activity + +  defp maybe_restrict_deactivated_users(activity, _opts), +    do: Activity.restrict_deactivated_users(activity)  end diff --git a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex index 0e9d25a0a..df1a6dcbb 100644 --- a/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/object_age_policy.ex @@ -131,7 +131,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.ObjectAgePolicy do            type: {:list, :atom},            description:              "A list of actions to apply to the post. `:delist` removes the post from public timelines; " <> -              "`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; " <> +              "`:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message; " <>                "`:reject` rejects the message entirely",            suggestions: [:delist, :strip_followers, :reject]          } diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index c0c7f3806..829ddeaea 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -40,9 +40,9 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    defp check_media_removal(           %{host: actor_host} = _actor_info, -         %{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object +         %{"type" => type, "object" => %{"attachment" => child_attachment}} = object         ) -       when length(child_attachment) > 0 do +       when length(child_attachment) > 0 and type in ["Create", "Update"] do      media_removal =        instance_list(:media_removal)        |> MRF.subdomains_regex() @@ -63,10 +63,11 @@ defmodule Pleroma.Web.ActivityPub.MRF.SimplePolicy do    defp check_media_nsfw(           %{host: actor_host} = _actor_info,           %{ -           "type" => "Create", +           "type" => type,             "object" => %{} = _child_object           } = object -       ) do +       ) +       when type in ["Create", "Update"] do      media_nsfw =        instance_list(:media_nsfw)        |> MRF.subdomains_regex() diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 10072b693..73760ca8f 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -27,22 +27,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do    defp process_tag(           "mrf_tag:media-force-nsfw",           %{ -           "type" => "Create", +           "type" => type,             "object" => %{"attachment" => child_attachment}           } = message         ) -       when length(child_attachment) > 0 do +       when length(child_attachment) > 0 and type in ["Create", "Update"] do      {:ok, Kernel.put_in(message, ["object", "sensitive"], true)}    end    defp process_tag(           "mrf_tag:media-strip",           %{ -           "type" => "Create", +           "type" => type,             "object" => %{"attachment" => child_attachment} = object           } = message         ) -       when length(child_attachment) > 0 do +       when length(child_attachment) > 0 and type in ["Create", "Update"] do      object = Map.delete(object, "attachment")      message = Map.put(message, "object", object) @@ -152,7 +152,7 @@ defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do      do: filter_message(target_actor, message)    @impl true -  def filter(%{"actor" => actor, "type" => "Create"} = message), +  def filter(%{"actor" => actor, "type" => type} = message) when type in ["Create", "Update"],      do: filter_message(actor, message)    @impl true diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex index 14f51e2c5..398020bff 100644 --- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex @@ -45,9 +45,9 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do      struct      |> cast(data, [:id, :type, :mediaType, :name, :blurhash]) -    |> cast_embed(:url, with: &url_changeset/2) +    |> cast_embed(:url, with: &url_changeset/2, required: true)      |> validate_inclusion(:type, ~w[Link Document Audio Image Video]) -    |> validate_required([:type, :mediaType, :url]) +    |> validate_required([:type, :mediaType])    end    def url_changeset(struct, data) do @@ -91,6 +91,6 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do    defp validate_data(cng) do      cng      |> validate_inclusion(:type, ~w[Document Audio Image Video]) -    |> validate_required([:mediaType, :url, :type]) +    |> validate_required([:mediaType, :type])    end  end diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex index 432bd9039..671a7ef0c 100644 --- a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex @@ -104,14 +104,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do      struct      |> cast(data, __schema__(:fields) -- [:attachment, :tag]) -    |> cast_embed(:attachment) +    |> cast_embed(:attachment, required: true)      |> cast_embed(:tag)    end    defp validate_data(data_cng) do      data_cng      |> validate_inclusion(:type, ["Audio", "Video"]) -    |> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment]) +    |> validate_required([:id, :actor, :attributedTo, :type, :context])      |> CommonValidations.validate_any_presence([:cc, :to])      |> CommonValidations.validate_fields_match([:actor, :attributedTo])      |> CommonValidations.validate_actor_presence() diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex index 644e62630..c3879f638 100644 --- a/lib/pleroma/web/activity_pub/side_effects.ex +++ b/lib/pleroma/web/activity_pub/side_effects.ex @@ -285,7 +285,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do    # Tasks this handles:    # - Delete and unpins the create activity    # - Replace object with Tombstone -  # - Set up notification    # - Reduce the user note count    # - Reduce the reply count    # - Stream out the activity @@ -328,8 +327,6 @@ defmodule Pleroma.Web.ActivityPub.SideEffects do        end      if result == :ok do -      Notification.create_notifications(object) -        # Only remove from index when deleting actual objects, not users or anything else        with %Pleroma.Object{} <- deleted_object do          Pleroma.Search.remove_from_index(deleted_object) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index d3b7d804f..b898d6fe8 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -695,20 +695,24 @@ defmodule Pleroma.Web.ActivityPub.Utils do      Enum.map(statuses || [], &build_flag_object/1)    end -  defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do -    activity_actor = User.get_by_ap_id(data["actor"]) +  defp build_flag_object(%Activity{} = activity) do +    object = Object.normalize(activity, fetch: false) + +    # Do not allow people to report Creates. Instead, report the Object that is Created. +    if activity.data["type"] != "Create" do +      build_flag_object_with_actor_and_id( +        object, +        User.get_by_ap_id(activity.data["actor"]), +        activity.data["id"] +      ) +    else +      build_flag_object(object) +    end +  end -    %{ -      "type" => "Note", -      "id" => id, -      "content" => data["content"], -      "published" => data["published"], -      "actor" => -        AccountView.render( -          "show.json", -          %{user: activity_actor, skip_visibility_check: true} -        ) -    } +  defp build_flag_object(%Object{} = object) do +    actor = User.get_by_ap_id(object.data["actor"]) +    build_flag_object_with_actor_and_id(object, actor, object.data["id"])    end    defp build_flag_object(act) when is_map(act) or is_binary(act) do @@ -720,12 +724,12 @@ defmodule Pleroma.Web.ActivityPub.Utils do        end      case Activity.get_by_ap_id_with_object(id) do -      %Activity{} = activity -> -        build_flag_object(activity) +      %Activity{object: object} = _ -> +        build_flag_object(object)        nil -> -        if activity = Activity.get_by_object_ap_id_with_object(id) do -          build_flag_object(activity) +        if %Object{} = object = Object.get_by_ap_id(id) do +          build_flag_object(object)          else            %{"id" => id, "deleted" => true}          end @@ -734,6 +738,20 @@ defmodule Pleroma.Web.ActivityPub.Utils do    defp build_flag_object(_), do: [] +  defp build_flag_object_with_actor_and_id(%Object{data: data}, actor, id) do +    %{ +      "type" => "Note", +      "id" => id, +      "content" => data["content"], +      "published" => data["published"], +      "actor" => +        AccountView.render( +          "show.json", +          %{user: actor, skip_visibility_check: true} +        ) +    } +  end +    #### Report-related helpers    def get_reports(params, page, page_size) do      params = @@ -748,22 +766,21 @@ defmodule Pleroma.Web.ActivityPub.Utils do      ActivityPub.fetch_activities([], params, :offset)    end -  def update_report_state(%Activity{} = activity, state) -      when state in @strip_status_report_states do -    {:ok, stripped_activity} = strip_report_status_data(activity) +  defp maybe_strip_report_status(data, state) do +    with true <- Config.get([:instance, :report_strip_status]), +         true <- state in @strip_status_report_states, +         {:ok, stripped_activity} = strip_report_status_data(%Activity{data: data}) do +      data |> Map.put("object", stripped_activity.data["object"]) +    else +      _ -> data +    end +  end +  def update_report_state(%Activity{} = activity, state) when state in @supported_report_states do      new_data =        activity.data        |> Map.put("state", state) -      |> Map.put("object", stripped_activity.data["object"]) - -    activity -    |> Changeset.change(data: new_data) -    |> Repo.update() -  end - -  def update_report_state(%Activity{} = activity, state) when state in @supported_report_states do -    new_data = Map.put(activity.data, "state", state) +      |> maybe_strip_report_status(state)      activity      |> Changeset.change(data: new_data) diff --git a/lib/pleroma/web/admin_api/controllers/chat_controller.ex b/lib/pleroma/web/admin_api/controllers/chat_controller.ex index c3e9e12ce..298543fcf 100644 --- a/lib/pleroma/web/admin_api/controllers/chat_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/chat_controller.ex @@ -8,7 +8,6 @@ defmodule Pleroma.Web.AdminAPI.ChatController do    alias Pleroma.Activity    alias Pleroma.Chat    alias Pleroma.Chat.MessageReference -  alias Pleroma.ModerationLog    alias Pleroma.Pagination    alias Pleroma.Web.AdminAPI    alias Pleroma.Web.CommonAPI @@ -42,12 +41,6 @@ defmodule Pleroma.Web.AdminAPI.ChatController do           ^chat_id <- to_string(cm_ref.chat_id),           %Activity{id: activity_id} <- Activity.get_create_by_object_ap_id(object_ap_id),           {:ok, _} <- CommonAPI.delete(activity_id, user) do -      ModerationLog.insert_log(%{ -        action: "chat_message_delete", -        actor: user, -        subject_id: message_id -      }) -        conn        |> put_view(MessageReferenceView)        |> render("show.json", chat_message_reference: cm_ref) diff --git a/lib/pleroma/web/admin_api/controllers/status_controller.ex b/lib/pleroma/web/admin_api/controllers/status_controller.ex index c9a4bfde9..9a3d49b57 100644 --- a/lib/pleroma/web/admin_api/controllers/status_controller.ex +++ b/lib/pleroma/web/admin_api/controllers/status_controller.ex @@ -65,12 +65,6 @@ defmodule Pleroma.Web.AdminAPI.StatusController do    def delete(%{assigns: %{user: user}} = conn, %{id: id}) do      with {:ok, %Activity{}} <- CommonAPI.delete(id, user) do -      ModerationLog.insert_log(%{ -        action: "status_delete", -        actor: user, -        subject_id: id -      }) -        json(conn, %{})      end    end diff --git a/lib/pleroma/web/admin_api/report.ex b/lib/pleroma/web/admin_api/report.ex index 8d1abfa56..c79bee27e 100644 --- a/lib/pleroma/web/admin_api/report.ex +++ b/lib/pleroma/web/admin_api/report.ex @@ -4,6 +4,7 @@  defmodule Pleroma.Web.AdminAPI.Report do    alias Pleroma.Activity +  alias Pleroma.Object    alias Pleroma.User    def extract_report_info( @@ -16,10 +17,44 @@ defmodule Pleroma.Web.AdminAPI.Report do        status_ap_ids        |> Enum.reject(&is_nil(&1))        |> Enum.map(fn -        act when is_map(act) -> Activity.get_by_ap_id_with_object(act["id"]) -        act when is_binary(act) -> Activity.get_by_ap_id_with_object(act) +        act when is_map(act) -> +          Activity.get_create_by_object_ap_id_with_object(act["id"]) || +            Activity.get_by_ap_id_with_object(act["id"]) || make_fake_activity(act, user) + +        act when is_binary(act) -> +          Activity.get_create_by_object_ap_id_with_object(act) || +            Activity.get_by_ap_id_with_object(act)        end)      %{report: report, user: user, account: account, statuses: statuses}    end + +  defp make_fake_activity(act, user) do +    %Activity{ +      id: "pleroma:fake", +      data: %{ +        "actor" => user.ap_id, +        "type" => "Create", +        "to" => [], +        "cc" => [], +        "object" => act["id"], +        "published" => act["published"], +        "id" => act["id"], +        "context" => "pleroma:fake" +      }, +      recipients: [user.ap_id], +      object: %Object{ +        data: %{ +          "actor" => user.ap_id, +          "type" => "Note", +          "content" => act["content"], +          "published" => act["published"], +          "to" => [], +          "cc" => [], +          "id" => act["id"], +          "context" => "pleroma:fake" +        } +      } +    } +  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 aed59293c..aabe988f7 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -64,7 +64,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do        requestBody: request_body("Parameters", update_credentials_request(), required: true),        responses: %{          200 => Operation.response("Account", "application/json", Account), -        403 => Operation.response("Error", "application/json", ApiError) +        403 => Operation.response("Error", "application/json", ApiError), +        413 => Operation.response("Error", "application/json", ApiError)        }      }    end @@ -223,12 +224,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do              type: :object,              properties: %{                reblogs: %Schema{ -                type: :boolean, +                allOf: [BooleanLike],                  description: "Receive this account's reblogs in home timeline? Defaults to true.",                  default: true                },                notify: %Schema{ -                type: :boolean, +                allOf: [BooleanLike],                  description:                    "Receive notifications for all statuses posted by the account? Defaults to false.",                  default: false diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex index 89f5dd606..62ab6b69c 100644 --- a/lib/pleroma/web/common_api.ex +++ b/lib/pleroma/web/common_api.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.CommonAPI do    alias Pleroma.Activity    alias Pleroma.Conversation.Participation    alias Pleroma.Formatter +  alias Pleroma.ModerationLog    alias Pleroma.Object    alias Pleroma.ThreadMute    alias Pleroma.User @@ -147,6 +148,21 @@ defmodule Pleroma.Web.CommonAPI do           true <- User.superuser?(user) || user.ap_id == object.data["actor"],           {:ok, delete_data, _} <- Builder.delete(user, object.data["id"]),           {:ok, delete, _} <- Pipeline.common_pipeline(delete_data, local: true) do +      if User.superuser?(user) and user.ap_id != object.data["actor"] do +        action = +          if object.data["type"] == "ChatMessage" do +            "chat_message_delete" +          else +            "status_delete" +          end + +        ModerationLog.insert_log(%{ +          action: action, +          actor: user, +          subject_id: activity_id +        }) +      end +        {:ok, delete}      else        {:find_activity, _} -> diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index 3be71c1b6..318b6cb11 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -47,10 +47,15 @@ defmodule Pleroma.Web.Federator do    end    @impl true -  def publish(activity) do -    PublisherWorker.enqueue("publish", %{"activity_id" => activity.id}) +  def publish(%Pleroma.Activity{data: %{"type" => type}} = activity) do +    PublisherWorker.enqueue("publish", %{"activity_id" => activity.id}, +      priority: publish_priority(type) +    )    end +  defp publish_priority("Delete"), do: 3 +  defp publish_priority(_), do: 0 +    # Job Worker Callbacks    @spec perform(atom(), module(), any()) :: {:ok, any()} | {:error, any()} diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 35a5f9482..449659f4b 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -14,14 +14,8 @@ defmodule Pleroma.Web.Feed.FeedView do    require Pleroma.Constants -  @spec pub_date(String.t() | DateTime.t()) :: String.t() -  def pub_date(date) when is_binary(date) do -    date -    |> Timex.parse!("{ISO:Extended}") -    |> pub_date -  end - -  def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}") +  @days ~w(Mon Tue Wed Thu Fri Sat Sun) +  @months ~w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)    def prepare_activity(activity, opts \\ []) do      object = Object.normalize(activity, fetch: false) @@ -41,13 +35,18 @@ defmodule Pleroma.Web.Feed.FeedView do    def most_recent_update(activities) do      with %{updated_at: updated_at} <- List.first(activities) do -      NaiveDateTime.to_iso8601(updated_at) +      to_rfc3339(updated_at)      end    end -  def most_recent_update(activities, user) do +  def most_recent_update(activities, user, :atom) do      (List.first(activities) || user).updated_at -    |> NaiveDateTime.to_iso8601() +    |> to_rfc3339() +  end + +  def most_recent_update(activities, user, :rss) do +    (List.first(activities) || user).updated_at +    |> to_rfc2822()    end    def feed_logo do @@ -61,6 +60,10 @@ defmodule Pleroma.Web.Feed.FeedView do      |> MediaProxy.url()    end +  def email(user) do +    user.nickname <> "@" <> Pleroma.Web.Endpoint.host() +  end +    def logo(user) do      user      |> User.avatar_url() @@ -69,18 +72,34 @@ defmodule Pleroma.Web.Feed.FeedView do    def last_activity(activities), do: List.last(activities) -  def activity_title(%{"content" => content}, opts \\ %{}) do -    content +  def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ %{}) do +    title = +      cond do +        summary != "" -> summary +        content != "" -> activity_content(data) +        true -> "a post" +      end + +    title      |> Pleroma.Web.Metadata.Utils.scrub_html()      |> Pleroma.Emoji.Formatter.demojify()      |> Formatter.truncate(opts[:max_length], opts[:omission]) -    |> escape() +  end + +  def activity_description(data) do +    content = activity_content(data) +    summary = data["summary"] + +    cond do +      content != "" -> escape(content) +      summary != "" -> escape(summary) +      true -> escape(data["type"]) +    end    end    def activity_content(%{"content" => content}) do      content      |> String.replace(~r/[\n\r]/, "") -    |> escape()    end    def activity_content(_), do: "" @@ -112,4 +131,60 @@ defmodule Pleroma.Web.Feed.FeedView do      |> html_escape()      |> safe_to_string()    end + +  @spec to_rfc3339(String.t() | NativeDateTime.t()) :: String.t() +  def to_rfc3339(date) when is_binary(date) do +    date +    |> Timex.parse!("{ISO:Extended}") +    |> to_rfc3339() +  end + +  def to_rfc3339(nd) do +    nd +    |> Timex.to_datetime() +    |> Timex.format!("{RFC3339}") +  end + +  @spec to_rfc2822(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t() +  def to_rfc2822(datestr) when is_binary(datestr) do +    datestr +    |> Timex.parse!("{ISO:Extended}") +    |> to_rfc2822() +  end + +  def to_rfc2822(%DateTime{} = date) do +    date +    |> DateTime.to_naive() +    |> NaiveDateTime.to_erl() +    |> rfc2822_from_erl() +  end + +  def to_rfc2822(nd) do +    nd +    |> Timex.to_datetime() +    |> DateTime.to_naive() +    |> NaiveDateTime.to_erl() +    |> rfc2822_from_erl() +  end + +  @doc """ +  Builds a RFC2822 timestamp from an Erlang timestamp +  [RFC2822 3.3 - Date and Time Specification](https://tools.ietf.org/html/rfc2822#section-3.3) +  This function always assumes the Erlang timestamp is in Universal time, not Local time +  """ +  def rfc2822_from_erl({{year, month, day} = date, {hour, minute, second}}) do +    day_name = Enum.at(@days, :calendar.day_of_the_week(date) - 1) +    month_name = Enum.at(@months, month - 1) + +    date_part = "#{day_name}, #{day} #{month_name} #{year}" +    time_part = "#{pad(hour)}:#{pad(minute)}:#{pad(second)}" + +    date_part <> " " <> time_part <> " +0000" +  end + +  defp pad(num) do +    num +    |> Integer.to_string() +    |> String.pad_leading(2, "0") +  end  end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 7c24c35d2..ea6e593d9 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -254,7 +254,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do          with_pleroma_settings: true        )      else -      _e -> render_error(conn, :forbidden, "Invalid request") +      {:error, %Ecto.Changeset{errors: [avatar: {"file is too large", _}]}} -> +        render_error(conn, :request_entity_too_large, "File is too large") + +      {:error, %Ecto.Changeset{errors: [banner: {"file is too large", _}]}} -> +        render_error(conn, :request_entity_too_large, "File is too large") + +      {:error, %Ecto.Changeset{errors: [background: {"file is too large", _}]}} -> +        render_error(conn, :request_entity_too_large, "File is too large") + +      _e -> +        render_error(conn, :forbidden, "Invalid request")      end    end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index b949d8f9a..0a8c98b44 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -65,7 +65,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do    # This should be removed in a future version of Pleroma. Pleroma-FE currently    # depends on this field, as well.    defp get_context_id(%{data: %{"context" => context}}) when is_binary(context) do -    use Bitwise +    import Bitwise      :erlang.crc32(context)      |> band(bnot(0x8000_0000)) diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex index bf0a12212..2dac22ee2 100644 --- a/lib/pleroma/web/metadata/providers/twitter_card.ex +++ b/lib/pleroma/web/metadata/providers/twitter_card.ex @@ -20,12 +20,12 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do      [        title_tag(user), -      {:meta, [property: "twitter:description", content: scrubbed_content], []} +      {:meta, [name: "twitter:description", content: scrubbed_content], []}      ] ++        if attachments == [] or Metadata.activity_nsfw?(object) do          [            image_tag(user), -          {:meta, [property: "twitter:card", content: "summary"], []} +          {:meta, [name: "twitter:card", content: "summary"], []}          ]        else          attachments @@ -37,20 +37,19 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do      with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do        [          title_tag(user), -        {:meta, [property: "twitter:description", content: truncated_bio], []}, +        {:meta, [name: "twitter:description", content: truncated_bio], []},          image_tag(user), -        {:meta, [property: "twitter:card", content: "summary"], []} +        {:meta, [name: "twitter:card", content: "summary"], []}        ]      end    end    defp title_tag(user) do -    {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []} +    {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}    end    def image_tag(user) do -    {:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], -     []} +    {:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []}    end    defp build_attachments(id, %{data: %{"attachment" => attachments}}) do @@ -60,10 +59,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do            case Utils.fetch_media_type(@media_types, url["mediaType"]) do              "audio" ->                [ -                {:meta, [property: "twitter:card", content: "player"], []}, -                {:meta, [property: "twitter:player:width", content: "480"], []}, -                {:meta, [property: "twitter:player:height", content: "80"], []}, -                {:meta, [property: "twitter:player", content: player_url(id)], []} +                {:meta, [name: "twitter:card", content: "player"], []}, +                {:meta, [name: "twitter:player:width", content: "480"], []}, +                {:meta, [name: "twitter:player:height", content: "80"], []}, +                {:meta, [name: "twitter:player", content: player_url(id)], []}                  | acc                ] @@ -74,10 +73,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do              # workaround.              "image" ->                [ -                {:meta, [property: "twitter:card", content: "summary_large_image"], []}, +                {:meta, [name: "twitter:card", content: "summary_large_image"], []},                  {:meta,                   [ -                   property: "twitter:player", +                   name: "twitter:player",                     content: MediaProxy.url(url["href"])                   ], []}                  | acc @@ -90,14 +89,14 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do                width = url["width"] || 480                [ -                {:meta, [property: "twitter:card", content: "player"], []}, -                {:meta, [property: "twitter:player", content: player_url(id)], []}, -                {:meta, [property: "twitter:player:width", content: "#{width}"], []}, -                {:meta, [property: "twitter:player:height", content: "#{height}"], []}, -                {:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])], +                {:meta, [name: "twitter:card", content: "player"], []}, +                {:meta, [name: "twitter:player", content: player_url(id)], []}, +                {:meta, [name: "twitter:player:width", content: "#{width}"], []}, +                {:meta, [name: "twitter:player:height", content: "#{height}"], []}, +                {:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])],                   []}, -                {:meta, -                 [property: "twitter:player:stream:content_type", content: url["mediaType"]], []} +                {:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]], +                 []}                  | acc                ] @@ -123,8 +122,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do        !is_nil(url["height"]) && !is_nil(url["width"]) ->          metadata ++            [ -            {:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []}, -            {:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []} +            {:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []}, +            {:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []}            ]        true -> diff --git a/lib/pleroma/web/plugs/http_security_plug.ex b/lib/pleroma/web/plugs/http_security_plug.ex index b89948cec..34895c8d5 100644 --- a/lib/pleroma/web/plugs/http_security_plug.ex +++ b/lib/pleroma/web/plugs/http_security_plug.ex @@ -68,7 +68,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do          ]        } -      [{"reply-to", Jason.encode!(report_group)} | headers] +      [{"report-to", Jason.encode!(report_group)} | headers]      else        headers      end @@ -117,7 +117,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do        if Config.get(:env) == :dev do          "script-src 'self' 'unsafe-eval'"        else -        "script-src 'self'" +        "script-src 'self' 'wasm-unsafe-eval'"        end      report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"] diff --git a/lib/pleroma/web/push/impl.ex b/lib/pleroma/web/push/impl.ex index daf3eeb9e..3c5f00764 100644 --- a/lib/pleroma/web/push/impl.ex +++ b/lib/pleroma/web/push/impl.ex @@ -16,7 +16,7 @@ defmodule Pleroma.Web.Push.Impl do    require Logger    import Ecto.Query -  @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact"] +  @types ["Create", "Follow", "Announce", "Like", "Move", "EmojiReact", "Update"]    @doc "Performs sending notifications for user subscriptions"    @spec perform(Notification.t()) :: list(any) | :error | {:error, :unknown_type} @@ -174,6 +174,15 @@ defmodule Pleroma.Web.Push.Impl do      end    end +  def format_body( +        %{activity: %{data: %{"type" => "Update"}}}, +        actor, +        _object, +        _mastodon_type +      ) do +    "@#{actor.nickname} edited a status" +  end +    def format_title(activity, mastodon_type \\ nil)    def format_title(%{activity: %{data: %{"directMessage" => true}}}, _mastodon_type) do @@ -187,6 +196,7 @@ defmodule Pleroma.Web.Push.Impl do        "follow_request" -> "New Follow Request"        "reblog" -> "New Repeat"        "favourite" -> "New Favorite" +      "update" -> "New Update"        "pleroma:chat_mention" -> "New Chat Message"        "pleroma:emoji_reaction" -> "New Reaction"        type -> "New #{String.capitalize(type || "event")}" diff --git a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex index 57bd92468..260338772 100644 --- a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex @@ -3,15 +3,15 @@    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>    <id><%= @data["id"] %></id>    <title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title> -  <content type="html"><%= activity_content(@data) %></content> -  <published><%= @activity.data["published"] %></published> -  <updated><%= @activity.data["published"] %></updated> +  <content type="html"><%= activity_description(@data) %></content> +  <published><%= to_rfc3339(@activity.data["published"]) %></published> +  <updated><%= to_rfc3339(@activity.data["published"]) %></updated>    <ostatus:conversation ref="<%= activity_context(@activity) %>">      <%= activity_context(@activity) %>    </ostatus:conversation>    <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/> -  <%= if @data["summary"] do %> +  <%= if @data["summary"] != "" do %>      <summary><%= escape(@data["summary"]) %></summary>    <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex index 279f2171d..5c8f35fe4 100644 --- a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex @@ -3,17 +3,12 @@    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>    <guid><%= @data["id"] %></guid>    <title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title> -  <description><%= activity_content(@data) %></description> -  <pubDate><%= @activity.data["published"] %></pubDate> -  <updated><%= @activity.data["published"] %></updated> +  <description><%= activity_description(@data) %></description> +  <pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate>    <ostatus:conversation ref="<%= activity_context(@activity) %>">      <%= activity_context(@activity) %>    </ostatus:conversation> -  <%= if @data["summary"] do %> -    <description><%= escape(@data["summary"]) %></description> -  <% end %> -    <%= if @activity.local do %>      <link><%= @data["id"] %></link>    <% else %> @@ -27,7 +22,7 @@    <% end %>    <%= for attachment <- @data["attachment"] || [] do %> -    <link type="<%= attachment_type(attachment) %>"><%= attachment_href(attachment) %></link> +    <enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>" />    <% end %>    <%= if @data["inReplyTo"] do %> diff --git a/lib/pleroma/web/templates/feed/feed/_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_author.atom.eex index 25cbffada..90be8a559 100644 --- a/lib/pleroma/web/templates/feed/feed/_author.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_author.atom.eex @@ -1,17 +1,14 @@  <author> -  <id><%= @user.ap_id %></id> -  <activity:object>http://activitystrea.ms/schema/1.0/person</activity:object>    <uri><%= @user.ap_id %></uri> +  <name><%= @user.nickname %></name> +  <activity:object>http://activitystrea.ms/schema/1.0/person</activity:object> +  <activity:displayName><%= @user.name %></activity:displayName> +  <activity:image><%= User.avatar_url(@user) %></activity:image> +  <activity:id><%= @user.ap_id %></activity:id> +  <activity:published><%= to_rfc3339(@user.inserted_at) %></activity:published> +  <activity:updated><%= to_rfc3339(@user.updated_at) %></activity:updated> +  <activity:url><%= @user.ap_id %></activity:url>    <poco:preferredUsername><%= @user.nickname %></poco:preferredUsername>    <poco:displayName><%= @user.name %></poco:displayName>    <poco:note><%= escape(@user.bio) %></poco:note> -  <summary><%= escape(@user.bio) %></summary> -  <name><%= @user.nickname %></name> -  <link rel="avatar" href="<%= User.avatar_url(@user) %>"/> -  <%= if User.banner_url(@user) do %> -    <link rel="header" href="<%= User.banner_url(@user) %>"/> -  <% end %> -  <%= if @user.local do %> -    <ap_enabled>true</ap_enabled> -  <% end %>  </author> diff --git a/lib/pleroma/web/templates/feed/feed/_author.rss.eex b/lib/pleroma/web/templates/feed/feed/_author.rss.eex index 526aeddcf..22477e6b1 100644 --- a/lib/pleroma/web/templates/feed/feed/_author.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/_author.rss.eex @@ -1,17 +1,10 @@ -<managingEditor> -  <guid><%= @user.ap_id %></guid> -  <activity:object>http://activitystrea.ms/schema/1.0/person</activity:object> -  <uri><%= @user.ap_id %></uri> -  <poco:preferredUsername><%= @user.nickname %></poco:preferredUsername> -  <poco:displayName><%= @user.name %></poco:displayName> -  <poco:note><%= escape(@user.bio) %></poco:note> -  <description><%= escape(@user.bio) %></description> -  <name><%= @user.nickname %></name> -  <link rel="avatar"><%= User.avatar_url(@user) %></link> -  <%= if User.banner_url(@user) do %> -    <link rel="header"><%= User.banner_url(@user) %></link> -  <% end %> -  <%= if @user.local do %> -    <ap_enabled>true</ap_enabled> -  <% end %> -</managingEditor> +<managingEditor><%= "#{email(@user)} (#{escape(@user.name)})" %></managingEditor> +<activity:object>http://activitystrea.ms/schema/1.0/person</activity:object> +<activity:displayName><%= @user.name %></activity:displayName> +<activity:image><%= User.avatar_url(@user) %></activity:image> +<activity:id><%= @user.ap_id %></activity:id> +<activity:published><%= to_rfc3339(@user.inserted_at) %></activity:published> +<activity:updated><%= to_rfc3339(@user.updated_at) %></activity:updated> +<poco:preferredUsername><%= @user.nickname %></poco:preferredUsername> +<poco:displayName><%= @user.name %></poco:displayName> +<poco:note><%= escape(@user.bio) %></poco:note> diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex index aa3035bca..25980c1e4 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex @@ -1,12 +1,22 @@  <entry> -    <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type> -    <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb> - -    <%= render @view_module, "_tag_author.atom", assigns %> - -    <id><%= @data["id"] %></id> -    <title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title> -    <content type="html"><%= activity_content(@data) %></content> +  <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type> +  <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb> + +    <%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %> + +  <id><%= @data["id"] %></id> +  <title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title> +  <content type="html"><%= activity_description(@data) %></content> +  <published><%= to_rfc3339(@activity.data["published"]) %></published> +  <updated><%= to_rfc3339(@activity.data["published"]) %></updated> +  <ostatus:conversation ref="<%= activity_context(@activity) %>"> +    <%= activity_context(@activity) %> +  </ostatus:conversation> +  <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/> + +  <%= if @data["summary"] != "" do %> +    <summary><%= @data["summary"] %></summary> +  <% end %>    <%= if @activity.local do %>      <link type="application/atom+xml" href='<%= @data["id"] %>' rel="self"/> @@ -15,37 +25,25 @@      <link type="text/html" href='<%= @data["external_url"] %>' rel="alternate"/>    <% end %> -    <published><%= @activity.data["published"] %></published> -    <updated><%= @activity.data["published"] %></updated> - -    <ostatus:conversation ref="<%= activity_context(@activity) %>"> -      <%= activity_context(@activity) %> -    </ostatus:conversation> -    <link href="<%= activity_context(@activity) %>" rel="ostatus:conversation"/> - -   <%= if @data["summary"] do %> -    <summary><%= @data["summary"] %></summary> -   <% end %> - -    <%= for id <- @activity.recipients do %> -      <%= if id == Pleroma.Constants.as_public() do %> +  <%= for id <- @activity.recipients do %> +    <%= if id == Pleroma.Constants.as_public() do %> +      <link rel="mentioned" +            ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" +            href="http://activityschema.org/collection/public"/> +    <% else %> +      <%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %>          <link rel="mentioned" -          ostatus:object-type="http://activitystrea.ms/schema/1.0/collection" -          href="http://activityschema.org/collection/public"/> -      <% else %> -        <%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %> -          <link rel="mentioned" -            ostatus:object-type="http://activitystrea.ms/schema/1.0/person" -            href="<%= id %>" /> -        <% end %> +              ostatus:object-type="http://activitystrea.ms/schema/1.0/person" +              href="<%= id %>" />        <% end %>      <% end %> +  <% end %> -    <%= for tag <- Pleroma.Object.hashtags(@object) do %> -      <category term="<%= tag %>"></category> -    <% end %> +  <%= for tag <- Pleroma.Object.hashtags(@object) do %> +    <category term="<%= tag %>"></category> +  <% end %> -    <%= for {emoji, file} <- @data["emoji"] || %{} do %> -      <link name="<%= emoji %>" rel="emoji" href="<%= file %>"/> -    <% end %> +  <%= for {emoji, file} <- @data["emoji"] || %{} do %> +    <link name="<%= emoji %>" rel="emoji" href="<%= file %>"/> +  <% end %>  </entry> diff --git a/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex index 2334e24a2..d582c83e8 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex @@ -4,9 +4,9 @@    <guid isPermalink="true"><%= activity_context(@activity) %></guid>    <link><%= activity_context(@activity) %></link> -  <pubDate><%= pub_date(@activity.data["published"]) %></pubDate> +  <pubDate><%= to_rfc2822(@activity.data["published"]) %></pubDate> -  <description><%= activity_content(@data) %></description> +  <description><%= activity_description(@data) %></description>    <%= for attachment <- @data["attachment"] || [] do %>      <enclosure url="<%= attachment_href(attachment) %>" type="<%= attachment_type(attachment) %>"/>    <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex index 997c4936e..71c696832 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex @@ -1,18 +1,14 @@  <author> -    <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type> -    <id><%= @actor.ap_id %></id> -    <uri><%= @actor.ap_id %></uri> -    <name><%= @actor.nickname %></name> -    <summary><%= escape(@actor.bio) %></summary> -    <link rel="avatar" href="<%= User.avatar_url(@actor) %>"/> -    <%= if User.banner_url(@actor) do %> -      <link rel="header" href="<%= User.banner_url(@actor) %>"/> -    <% end %> -    <%= if @actor.local do %> -      <ap_enabled>true</ap_enabled> -    <% end %> -   -    <poco:preferredUsername><%= @actor.nickname %></poco:preferredUsername>         -    <poco:displayName><%= @actor.name %></poco:displayName> -    <poco:note><%= escape(@actor.bio) %></poco:note>     +  <uri><%= @actor.ap_id %></uri> +  <name><%= @actor.nickname %></name> +  <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type> +  <activity:displayName><%= @actor.name %></activity:displayName> +  <activity:image><%= User.avatar_url(@actor) %></activity:image> +  <activity:id><%= @actor.ap_id %></activity:id> +  <activity:published><%= to_rfc3339(@actor.inserted_at) %></activity:published> +  <activity:updated><%= to_rfc3339(@actor.updated_at) %></activity:updated> +  <activity:url><%= @actor.ap_id %></activity:url> +  <poco:preferredUsername><%= @actor.nickname %></poco:preferredUsername> +  <poco:displayName><%= @actor.name %></poco:displayName> +  <poco:note><%= escape(@actor.bio) %></poco:note>  </author> diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 6d497e84c..14b0ee594 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -1,22 +1,20 @@  <?xml version="1.0" encoding="UTF-8"?> +<feed +  xmlns="http://www.w3.org/2005/Atom" +  xmlns:thr="http://purl.org/syndication/thread/1.0" +  xmlns:activity="http://activitystrea.ms/spec/1.0/" +  xmlns:poco="http://portablecontacts.net/spec/1.0" +  xmlns:ostatus="http://ostatus.org/schema/1.0" +  xmlns:statusnet="http://status.net/schema/api/1/"> -<feed xml:lang="<%= Gettext.language_tag() %>" xmlns="http://www.w3.org/2005/Atom" -      xmlns:thr="http://purl.org/syndication/thread/1.0" -      xmlns:georss="http://www.georss.org/georss" -      xmlns:activity="http://activitystrea.ms/spec/1.0/" -      xmlns:media="http://purl.org/syndication/atommedia" -      xmlns:poco="http://portablecontacts.net/spec/1.0" -      xmlns:ostatus="http://ostatus.org/schema/1.0" -      xmlns:statusnet="http://status.net/schema/api/1/"> +  <id><%= Routes.tag_feed_url(@conn, :feed, @tag) <> ".atom" %></id> +  <title>#<%= @tag %></title> +  <subtitle><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></subtitle> +  <logo><%= feed_logo() %></logo> +  <updated><%= most_recent_update(@activities) %></updated> +  <link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom'  %>" type="application/atom+xml"/> -    <id><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></id> -    <title>#<%= @tag %></title> - -    <subtitle><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></subtitle> -    <logo><%= feed_logo() %></logo> -    <updated><%= most_recent_update(@activities) %></updated> -    <link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom'  %>" type="application/atom+xml"/> -    <%= for activity <- @activities do %> -    <%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> -    <% end %> +  <%= for activity <- @activities do %> +  <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> +  <% end %>  </feed> diff --git a/lib/pleroma/web/templates/feed/feed/tag.rss.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex index edcc3e436..27dde5627 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.rss.eex @@ -1,15 +1,16 @@  <?xml version="1.0" encoding="UTF-8"?> -<rss version="2.0" xmlns:webfeeds="http://webfeeds.org/rss/1.0"> +<rss version="2.0" +     xmlns:webfeeds="http://webfeeds.org/rss/1.0" +     xmlns:thr="http://purl.org/syndication/thread/1.0">    <channel> -      <title>#<%= @tag %></title>      <description><%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %></description>      <link><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></link>      <webfeeds:logo><%= feed_logo() %></webfeeds:logo>      <webfeeds:accentColor>2b90d9</webfeeds:accentColor>      <%= for activity <- @activities do %> -    <%= render @view_module, "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> +    <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %>      <% end %>    </channel>  </rss> diff --git a/lib/pleroma/web/templates/feed/feed/user.atom.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex index 5c1f0ecbc..e36bfc66c 100644 --- a/lib/pleroma/web/templates/feed/feed/user.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -8,17 +8,18 @@    <id><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %></id>    <title><%= @user.nickname <> "'s timeline" %></title> -  <updated><%= most_recent_update(@activities, @user) %></updated> +  <subtitle><%= escape(@user.bio) %></subtitle> +  <updated><%= most_recent_update(@activities, @user, :atom) %></updated>    <logo><%= logo(@user) %></logo>    <link rel="self" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom' %>" type="application/atom+xml"/> -  <%= render @view_module, "_author.atom", assigns %> +  <%= render Phoenix.Controller.view_module(@conn), "_author.atom", assigns %>    <%= if last_activity(@activities) do %>      <link rel="next" href="<%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.atom?max_id=#{last_activity(@activities).id}' %>" type="application/atom+xml"/>    <% end %>    <%= for activity <- @activities do %> -  <%= render @view_module, "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> +  <%= render Phoenix.Controller.view_module(@conn), "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %>    <% end %>  </feed> diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex index 6b842a085..fae3fcf3d 100644 --- a/lib/pleroma/web/templates/feed/feed/user.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -1,20 +1,30 @@  <?xml version="1.0" encoding="UTF-8" ?> -<rss version="2.0"> +<rss version="2.0" +     xmlns:atom="http://www.w3.org/2005/Atom" +     xmlns:thr="http://purl.org/syndication/thread/1.0" +     xmlns:activity="http://activitystrea.ms/spec/1.0/" +     xmlns:ostatus="http://ostatus.org/schema/1.0" +     xmlns:poco="http://portablecontacts.net/spec/1.0">    <channel> -    <guid><%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %></guid>      <title><%= @user.nickname <> "'s timeline" %></title> -    <updated><%= most_recent_update(@activities, @user) %></updated> -    <image><%= logo(@user) %></image>      <link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link> +    <atom:link href="<%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %>" +               rel="self" type="application/rss+xml" /> +    <description><%= escape(@user.bio) %></description> +    <image> +      <url><%= logo(@user) %></url> +      <title><%= @user.nickname <> "'s timeline" %></title> +      <link><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %></link> +    </image> -    <%= render @view_module, "_author.rss", assigns %> +    <%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %>      <%= if last_activity(@activities) do %>        <link rel="next"><%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %></link>      <% end %>      <%= for activity <- @activities do %> -    <%= render @view_module, "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> +    <%= render Phoenix.Controller.view_module(@conn), "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %>      <% end %>    </channel>  </rss> diff --git a/lib/pleroma/web/templates/layout/email.html.eex b/lib/pleroma/web/templates/layout/email.html.eex index 087aa4fc0..5858e48b4 100644 --- a/lib/pleroma/web/templates/layout/email.html.eex +++ b/lib/pleroma/web/templates/layout/email.html.eex @@ -5,6 +5,6 @@      <title><%= @email.subject %></title>    </head>    <body> -    <%= render @view_module, @view_template, assigns %> +    <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %>    </body>  </html> diff --git a/lib/pleroma/web/templates/layout/embed.html.eex b/lib/pleroma/web/templates/layout/embed.html.eex index 8b905f070..1197288e5 100644 --- a/lib/pleroma/web/templates/layout/embed.html.eex +++ b/lib/pleroma/web/templates/layout/embed.html.eex @@ -10,6 +10,6 @@      <base target="_parent">    </head>    <body> -    <%= render @view_module, @view_template, assigns %> +    <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %>    </body>  </html> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex index 8b894cd58..98904ad64 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -2,7 +2,7 @@  <%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>    <div style="display: none"> -    <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> +    <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %>    </div>    <%= hidden_input f, :client_id, value: @client_id %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index a2f41618e..b3654f3eb 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -21,7 +21,7 @@  <div class="container__content">    <%= if @app do %>      <p><%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application <strong>%{client_name}</strong> is requesting access to your account.", client_name: safe_to_string(html_escape(@app.client_name))) %></p> -    <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> +    <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %>    <% end %>    <%= if @user do %> @@ -63,5 +63,5 @@  <% end %>  <%= if Pleroma.Config.oauth_consumer_enabled?() do %> -  <%= render @view_module, Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %> +  <%= render Phoenix.Controller.view_module(@conn), Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %>  <% end %> diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index 77ff40f46..f95dc2458 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -32,7 +32,13 @@ defmodule Pleroma.Web.WebFinger do    def webfinger(resource, fmt) when fmt in ["XML", "JSON"] do      host = Pleroma.Web.Endpoint.host() -    regex = ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@#{host}/ + +    regex = +      if webfinger_domain = Pleroma.Config.get([__MODULE__, :domain]) do +        ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@(#{host}|#{webfinger_domain})/ +      else +        ~r/(acct:)?(?<username>[a-z0-9A-Z_\.-]+)@#{host}/ +      end      with %{"username" => username} <- Regex.named_captures(regex, resource),           %User{} = user <- User.get_cached_by_nickname(username) do @@ -64,7 +70,7 @@ defmodule Pleroma.Web.WebFinger do    def represent_user(user, "JSON") do      %{ -      "subject" => "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}", +      "subject" => "acct:#{user.nickname}@#{domain()}",        "aliases" => gather_aliases(user),        "links" => gather_links(user)      } @@ -84,12 +90,16 @@ defmodule Pleroma.Web.WebFinger do        :XRD,        %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"},        [ -        {:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"} +        {:Subject, "acct:#{user.nickname}@#{domain()}"}        ] ++ aliases ++ links      }      |> XmlBuilder.to_doc()    end +  defp domain do +    Pleroma.Config.get([__MODULE__, :domain]) || Pleroma.Web.Endpoint.host() +  end +    defp webfinger_from_xml(body) do      with {:ok, doc} <- XML.parse_document(body) do        subject = XML.string_from_xpath("//Subject", doc) @@ -146,17 +156,15 @@ defmodule Pleroma.Web.WebFinger do    end    def find_lrdd_template(domain) do -    with {:ok, %{status: status, body: body}} when status in 200..299 <- -           HTTP.get("http://#{domain}/.well-known/host-meta") do +    # WebFinger is restricted to HTTPS - https://tools.ietf.org/html/rfc7033#section-9.1 +    meta_url = "https://#{domain}/.well-known/host-meta" + +    with {:ok, %{status: status, body: body}} when status in 200..299 <- HTTP.get(meta_url) do        get_template_from_xml(body)      else -      _ -> -        with {:ok, %{body: body, status: status}} when status in 200..299 <- -               HTTP.get("https://#{domain}/.well-known/host-meta") do -          get_template_from_xml(body) -        else -          e -> {:error, "Can't find LRDD template: #{inspect(e)}"} -        end +      error -> +        Logger.warn("Can't find LRDD template in #{inspect(meta_url)}: #{inspect(error)}") +        {:error, :lrdd_not_found}      end    end @@ -170,7 +178,7 @@ defmodule Pleroma.Web.WebFinger do      end    end -  defp get_address_from_domain(_, _), do: nil +  defp get_address_from_domain(_, _), do: {:error, :webfinger_no_domain}    @spec finger(String.t()) :: {:ok, map()} | {:error, any()}    def finger(account) do @@ -187,13 +195,11 @@ defmodule Pleroma.Web.WebFinger do      encoded_account = URI.encode("acct:#{account}")      with address when is_binary(address) <- get_address_from_domain(domain, encoded_account), -         response <- +         {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <-             HTTP.get(               address,               [{"accept", "application/xrd+xml,application/jrd+json"}] -           ), -         {:ok, %{status: status, body: body, headers: headers}} when status in 200..299 <- -           response do +           ) do        case List.keyfind(headers, "content-type", 0) do          {_, content_type} ->            case Plug.Conn.Utils.media_type(content_type) do @@ -211,10 +217,9 @@ defmodule Pleroma.Web.WebFinger do            {:error, {:content_type, nil}}        end      else -      e -> -        Logger.debug(fn -> "Couldn't finger #{account}" end) -        Logger.debug(fn -> inspect(e) end) -        {:error, e} +      error -> +        Logger.debug("Couldn't finger #{account}: #{inspect(error)}") +        error      end    end  end diff --git a/lib/pleroma/workers/attachments_cleanup_worker.ex b/lib/pleroma/workers/attachments_cleanup_worker.ex index 0a397eae0..4c1764053 100644 --- a/lib/pleroma/workers/attachments_cleanup_worker.ex +++ b/lib/pleroma/workers/attachments_cleanup_worker.ex @@ -31,6 +31,9 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do    def perform(%Job{args: %{"op" => "cleanup_attachments", "object" => _object}}), do: {:ok, :skip} +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(900) +    defp do_clean({object_ids, attachment_urls}) do      uploader = Pleroma.Config.get([Pleroma.Upload, :uploader]) diff --git a/lib/pleroma/workers/background_worker.ex b/lib/pleroma/workers/background_worker.ex index 91440cbe6..3805293bc 100644 --- a/lib/pleroma/workers/background_worker.ex +++ b/lib/pleroma/workers/background_worker.ex @@ -43,4 +43,7 @@ defmodule Pleroma.Workers.BackgroundWorker do    def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do      Instance.perform(:delete_instance, host)    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/backup_worker.ex b/lib/pleroma/workers/backup_worker.ex index 7657fa9ce..12ee70f00 100644 --- a/lib/pleroma/workers/backup_worker.ex +++ b/lib/pleroma/workers/backup_worker.ex @@ -30,6 +30,7 @@ defmodule Pleroma.Workers.BackupWorker do      |> Oban.insert()    end +  @impl Oban.Worker    def perform(%Job{          args: %{"op" => "process", "backup_id" => backup_id, "admin_user_id" => admin_user_id}        }) do @@ -49,6 +50,9 @@ defmodule Pleroma.Workers.BackupWorker do      end    end +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(900) +    defp has_email?(user) do      not is_nil(user.email) and user.email != ""    end diff --git a/lib/pleroma/workers/mailer_worker.ex b/lib/pleroma/workers/mailer_worker.ex index 81764ba72..940716558 100644 --- a/lib/pleroma/workers/mailer_worker.ex +++ b/lib/pleroma/workers/mailer_worker.ex @@ -12,4 +12,7 @@ defmodule Pleroma.Workers.MailerWorker do      |> :erlang.binary_to_term()      |> Pleroma.Emails.Mailer.deliver(config)    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/mute_expire_worker.ex b/lib/pleroma/workers/mute_expire_worker.ex index a7841d917..8ce458d48 100644 --- a/lib/pleroma/workers/mute_expire_worker.ex +++ b/lib/pleroma/workers/mute_expire_worker.ex @@ -17,4 +17,7 @@ defmodule Pleroma.Workers.MuteExpireWorker do      Pleroma.Web.CommonAPI.remove_mute(user_id, activity_id)      :ok    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/poll_worker.ex b/lib/pleroma/workers/poll_worker.ex index 4c7eab5c1..022d026f8 100644 --- a/lib/pleroma/workers/poll_worker.ex +++ b/lib/pleroma/workers/poll_worker.ex @@ -19,6 +19,9 @@ defmodule Pleroma.Workers.PollWorker do      end    end +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5) +    defp find_poll_activity(activity_id) do      with nil <- Activity.get_by_id(activity_id) do        {:error, :poll_activity_not_found} diff --git a/lib/pleroma/workers/publisher_worker.ex b/lib/pleroma/workers/publisher_worker.ex index 528a06bb3..598ae3779 100644 --- a/lib/pleroma/workers/publisher_worker.ex +++ b/lib/pleroma/workers/publisher_worker.ex @@ -22,4 +22,7 @@ defmodule Pleroma.Workers.PublisherWorker do      params = Map.new(params, fn {k, v} -> {String.to_atom(k), v} end)      Federator.perform(:publish_one, String.to_atom(module_name), params)    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(10)  end diff --git a/lib/pleroma/workers/purge_expired_activity.ex b/lib/pleroma/workers/purge_expired_activity.ex index 0545d3ece..e554684fe 100644 --- a/lib/pleroma/workers/purge_expired_activity.ex +++ b/lib/pleroma/workers/purge_expired_activity.ex @@ -35,6 +35,9 @@ defmodule Pleroma.Workers.PurgeExpiredActivity do      end    end +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5) +    defp enabled? do      with false <- Pleroma.Config.get([__MODULE__, :enabled], false) do        {:error, :expired_activities_disabled} diff --git a/lib/pleroma/workers/purge_expired_filter.ex b/lib/pleroma/workers/purge_expired_filter.ex index 933ecb3f6..9114aeb7f 100644 --- a/lib/pleroma/workers/purge_expired_filter.ex +++ b/lib/pleroma/workers/purge_expired_filter.ex @@ -31,6 +31,9 @@ defmodule Pleroma.Workers.PurgeExpiredFilter do      |> Repo.delete()    end +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5) +    @spec get_expiration(pos_integer()) :: Job.t() | nil    def get_expiration(id) do      from(j in Job, diff --git a/lib/pleroma/workers/purge_expired_token.ex b/lib/pleroma/workers/purge_expired_token.ex index 1d322b6b6..2ccd9e80b 100644 --- a/lib/pleroma/workers/purge_expired_token.ex +++ b/lib/pleroma/workers/purge_expired_token.ex @@ -26,4 +26,7 @@ defmodule Pleroma.Workers.PurgeExpiredToken do      |> Pleroma.Repo.get(id)      |> Pleroma.Repo.delete()    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/receiver_worker.ex b/lib/pleroma/workers/receiver_worker.ex index c41b44e14..4f513b907 100644 --- a/lib/pleroma/workers/receiver_worker.ex +++ b/lib/pleroma/workers/receiver_worker.ex @@ -17,4 +17,7 @@ defmodule Pleroma.Workers.ReceiverWorker do        e -> e      end    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/remote_fetcher_worker.ex b/lib/pleroma/workers/remote_fetcher_worker.ex index c3158bbbe..d2a77aa17 100644 --- a/lib/pleroma/workers/remote_fetcher_worker.ex +++ b/lib/pleroma/workers/remote_fetcher_worker.ex @@ -11,4 +11,7 @@ defmodule Pleroma.Workers.RemoteFetcherWorker do    def perform(%Job{args: %{"op" => "fetch_remote", "id" => id} = args}) do      {:ok, _object} = Fetcher.fetch_object_from_id(id, depth: args["depth"])    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(10)  end diff --git a/lib/pleroma/workers/scheduled_activity_worker.ex b/lib/pleroma/workers/scheduled_activity_worker.ex index 9a17330b6..4df84d00f 100644 --- a/lib/pleroma/workers/scheduled_activity_worker.ex +++ b/lib/pleroma/workers/scheduled_activity_worker.ex @@ -37,6 +37,9 @@ defmodule Pleroma.Workers.ScheduledActivityWorker do      end    end +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5) +    defp find_scheduled_activity(id) do      with nil <- Repo.get(ScheduledActivity, id) do        {:error, :scheduled_activity_not_found} diff --git a/lib/pleroma/workers/transmogrifier_worker.ex b/lib/pleroma/workers/transmogrifier_worker.ex index ed319c585..1f3f5385e 100644 --- a/lib/pleroma/workers/transmogrifier_worker.ex +++ b/lib/pleroma/workers/transmogrifier_worker.ex @@ -12,4 +12,7 @@ defmodule Pleroma.Workers.TransmogrifierWorker do      user = User.get_cached_by_id(user_id)      Pleroma.Web.ActivityPub.Transmogrifier.perform(:user_upgrade, user)    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end diff --git a/lib/pleroma/workers/web_pusher_worker.ex b/lib/pleroma/workers/web_pusher_worker.ex index 6447a5edc..67e84b0c9 100644 --- a/lib/pleroma/workers/web_pusher_worker.ex +++ b/lib/pleroma/workers/web_pusher_worker.ex @@ -17,4 +17,7 @@ defmodule Pleroma.Workers.WebPusherWorker do      Pleroma.Web.Push.Impl.perform(notification)    end + +  @impl Oban.Worker +  def timeout(_job), do: :timer.seconds(5)  end  | 
