From b31a934a804aed3f35442ceafe2080b0955e7317 Mon Sep 17 00:00:00 2001 From: dcc Date: Wed, 15 May 2024 00:57:23 -0700 Subject: total rebase --- patches/1(2.5.2).diff | 1184 -------------------------------------- patches/1(fix_searches_p1).patch | 27 + patches/2(fix_searches_p1).patch | 27 - patches/2(fix_searches_p2).patch | 57 ++ patches/3(fix_searches_p2).patch | 57 -- patches/3(fix_searches_p3).patch | 43 ++ patches/4(fix_searches_p3).patch | 43 -- patches/4i2psearch.diff | 28 + patches/5(search_i2p).diff | 1 - patches/5spoof.diff | 67 +++ patches/6(2.5.3).diff | 261 --------- patches/7(2.5.4).diff | 110 ---- patches/8(2.5.5).diff | 293 ---------- patches/9(2.6.0).diff | 392 ------------- 14 files changed, 222 insertions(+), 2368 deletions(-) delete mode 100755 patches/1(2.5.2).diff create mode 100755 patches/1(fix_searches_p1).patch delete mode 100755 patches/2(fix_searches_p1).patch create mode 100755 patches/2(fix_searches_p2).patch delete mode 100755 patches/3(fix_searches_p2).patch create mode 100755 patches/3(fix_searches_p3).patch delete mode 100755 patches/4(fix_searches_p3).patch create mode 100644 patches/4i2psearch.diff delete mode 100755 patches/5(search_i2p).diff create mode 100644 patches/5spoof.diff delete mode 100755 patches/6(2.5.3).diff delete mode 100755 patches/7(2.5.4).diff delete mode 100644 patches/8(2.5.5).diff delete mode 100644 patches/9(2.6.0).diff (limited to 'patches') diff --git a/patches/1(2.5.2).diff b/patches/1(2.5.2).diff deleted file mode 100755 index 29120f5..0000000 --- a/patches/1(2.5.2).diff +++ /dev/null @@ -1,1184 +0,0 @@ -diff --git a/CHANGELOG.md b/CHANGELOG.md -index 6a7ec1032876ec7c4aa4043bf095599749f68160..f6fc6aaee23c312a43f67b5210688b28e1060554 100644 ---- a/CHANGELOG.md -+++ b/CHANGELOG.md -@@ -14,6 +14,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - ### Removed - -+## 2.5.2 -+ -+### Security -+- `/proxy` endpoint now sets a Content-Security-Policy (sandbox) -+- WebSocket endpoint now respects unauthenticated restrictions for streams of public posts -+- OEmbed HTML tags are now filtered -+ -+### Changed -+- docs: Be more explicit about the level of compatibility of OTP releases -+- Set default background worker timeout to 15 minutes -+ -+### Fixed -+- Atom/RSS formatting (HTML truncation, published, missing summary) -+- Remove `static_fe` pipeline for `/users/:nickname/feed` -+- Stop oban from retrying if validating errors occur when processing incoming data -+- Make sure object refetching as used by already received polls follows MRF rules -+ -+### Removed -+- BREAKING: Support for passwords generated with `crypt(3)` (Gnu Social migration artifact) -+ - ## 2.5.1 - - ### Added -diff --git a/changelog.d/3126.fix b/changelog.d/3126.fix -new file mode 100644 -index 0000000000000000000000000000000000000000..91d396c89d4fbc9ee4c572006a56f376d309d241 ---- /dev/null -+++ b/changelog.d/3126.fix -@@ -0,0 +1 @@ -+MediaProxy responses now return a sandbox CSP header -diff --git a/changelog.d/3883.fix b/changelog.d/3883.fix -new file mode 100644 -index 0000000000000000000000000000000000000000..6824f201345db5fd24305782dc6b842692216f4e ---- /dev/null -+++ b/changelog.d/3883.fix -@@ -0,0 +1 @@ -+Fix abnormal behaviour when refetching a poll -diff --git a/changelog.d/3891.fix b/changelog.d/3891.fix -new file mode 100644 -index 0000000000000000000000000000000000000000..f1fb62d826a3a3f5e442a9f2a585550975175570 ---- /dev/null -+++ b/changelog.d/3891.fix -@@ -0,0 +1 @@ -+OEmbed HTML tags are now filtered -diff --git a/changelog.d/fix-object-test.fix b/changelog.d/fix-object-test.fix -new file mode 100644 -index 0000000000000000000000000000000000000000..5eea719f0bd89557ab2052d925036bf4802442bb ---- /dev/null -+++ b/changelog.d/fix-object-test.fix -@@ -0,0 +1 @@ -+Correctly handle the situation when a poll has both "anyOf" and "oneOf" but one of them being empty -diff --git a/docs/installation/otp_en.md b/docs/installation/otp_en.md -index 8c02201e67699c54b694ddef13d4e54520751c98..f2812346b1348cdf5c383e1812d841a4ffaaf10c 100644 ---- a/docs/installation/otp_en.md -+++ b/docs/installation/otp_en.md -@@ -2,15 +2,16 @@ - - {! backend/installation/otp_vs_from_source.include !} - --This guide covers a installation using an OTP release. To install Pleroma from source, please check out the corresponding guide for your distro. -+This guide covers a installation using OTP releases as built by the Pleroma project, it is meant as a fallback to distribution packages/recipes which are the preferred installation method. -+To install Pleroma from source, please check out the corresponding guide for your distro. - - ## Pre-requisites --* A machine running Linux with GNU (e.g. Debian, Ubuntu) or musl (e.g. Alpine) libc and `x86_64`, `aarch64` or `armv7l` CPU, you have root access to. If you are not sure if it's compatible see [Detecting flavour section](#detecting-flavour) below -+* A machine you have root access to running Debian GNU/Linux or compatible (eg. Ubuntu), or Alpine on `x86_64`, `aarch64` or `armv7l` CPU. If you are not sure what you are running see [Detecting flavour section](#detecting-flavour) below - * A (sub)domain pointed to the machine - --You will be running commands as root. If you aren't root already, please elevate your privileges by executing `sudo su`/`su`. -+You will be running commands as root. If you aren't root already, please elevate your privileges by executing `sudo -i`/`su`. - --While in theory OTP releases are possbile to install on any compatible machine, for the sake of simplicity this guide focuses only on Debian/Ubuntu and Alpine. -+Similarly to other binaries, OTP releases tend to be only compatible with the distro they are built on, as such this guide focuses only on Debian/Ubuntu and Alpine. - - ### Detecting flavour - -@@ -19,7 +20,7 @@ Paste the following into the shell: - arch="$(uname -m)";if [ "$arch" = "x86_64" ];then arch="amd64";elif [ "$arch" = "armv7l" ];then arch="arm";elif [ "$arch" = "aarch64" ];then arch="arm64";else echo "Unsupported arch: $arch">&2;fi;if getconf GNU_LIBC_VERSION>/dev/null;then libc_postfix="";elif [ "$(ldd 2>&1|head -c 9)" = "musl libc" ];then libc_postfix="-musl";elif [ "$(find /lib/libc.musl*|wc -l)" ];then libc_postfix="-musl";else echo "Unsupported libc">&2;fi;echo "$arch$libc_postfix" - ``` - --If your platform is supported the output will contain the flavour string, you will need it later. If not, this just means that we don't build releases for your platform, you can still try installing from source. -+This should give your flavour string. If not this just means that we don't build releases for your platform, you can still try installing from source. - - ### Installing the required packages - -diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex -index a9a9eeeed17adaacc51a5cd6927e5f0daa65e79d..cc3772563b8380af0da1a64ceba238ea144a05ac 100644 ---- a/lib/pleroma/object/fetcher.ex -+++ b/lib/pleroma/object/fetcher.ex -@@ -8,77 +8,30 @@ defmodule Pleroma.Object.Fetcher do - alias Pleroma.Maps - alias Pleroma.Object - alias Pleroma.Object.Containment -- alias Pleroma.Repo - alias Pleroma.Signature - alias Pleroma.Web.ActivityPub.InternalFetchActor -+ alias Pleroma.Web.ActivityPub.MRF - alias Pleroma.Web.ActivityPub.ObjectValidator -+ alias Pleroma.Web.ActivityPub.Pipeline - alias Pleroma.Web.ActivityPub.Transmogrifier - alias Pleroma.Web.Federator - - require Logger - require Pleroma.Constants - -- defp touch_changeset(changeset) do -- updated_at = -- NaiveDateTime.utc_now() -- |> NaiveDateTime.truncate(:second) -- -- Ecto.Changeset.put_change(changeset, :updated_at, updated_at) -- end -- -- defp maybe_reinject_internal_fields(%{data: %{} = old_data}, new_data) do -- has_history? = fn -- %{"formerRepresentations" => %{"orderedItems" => list}} when is_list(list) -> true -- _ -> false -- end -- -- internal_fields = Map.take(old_data, Pleroma.Constants.object_internal_fields()) -- -- remote_history_exists? = has_history?.(new_data) -- -- # If the remote history exists, we treat that as the only source of truth. -- new_data = -- if has_history?.(old_data) and not remote_history_exists? do -- Map.put(new_data, "formerRepresentations", old_data["formerRepresentations"]) -- else -- new_data -- end -- -- # If the remote does not have history information, we need to manage it ourselves -- new_data = -- if not remote_history_exists? do -- changed? = -- Pleroma.Constants.status_updatable_fields() -- |> Enum.any?(fn field -> Map.get(old_data, field) != Map.get(new_data, field) end) -- -- %{updated_object: updated_object} = -- new_data -- |> Object.Updater.maybe_update_history(old_data, -- updated: changed?, -- use_history_in_new_object?: false -- ) -- -- updated_object -- else -- new_data -- end -- -- Map.merge(new_data, internal_fields) -- end -- -- defp maybe_reinject_internal_fields(_, new_data), do: new_data -- - @spec reinject_object(struct(), map()) :: {:ok, Object.t()} | {:error, any()} -- defp reinject_object(%Object{data: %{"type" => "Question"}} = object, new_data) do -+ defp reinject_object(%Object{data: %{}} = object, new_data) do - Logger.debug("Reinjecting object #{new_data["id"]}") - -- with data <- maybe_reinject_internal_fields(object, new_data), -- {:ok, data, _} <- ObjectValidator.validate(data, %{}), -- changeset <- Object.change(object, %{data: data}), -- changeset <- touch_changeset(changeset), -- {:ok, object} <- Repo.insert_or_update(changeset), -- {:ok, object} <- Object.set_cache(object) do -- {:ok, object} -+ with {:ok, new_data, _} <- ObjectValidator.validate(new_data, %{}), -+ {:ok, new_data} <- MRF.filter(new_data), -+ {:ok, new_object, _} <- -+ Object.Updater.do_update_and_invalidate_cache( -+ object, -+ new_data, -+ _touch_changeset? = true -+ ) do -+ {:ok, new_object} - else - e -> - Logger.error("Error while processing object: #{inspect(e)}") -@@ -86,20 +39,11 @@ defp reinject_object(%Object{data: %{"type" => "Question"}} = object, new_data) - end - end - -- defp reinject_object(%Object{} = object, new_data) do -- Logger.debug("Reinjecting object #{new_data["id"]}") -- -- with new_data <- Transmogrifier.fix_object(new_data), -- data <- maybe_reinject_internal_fields(object, new_data), -- changeset <- Object.change(object, %{data: data}), -- changeset <- touch_changeset(changeset), -- {:ok, object} <- Repo.insert_or_update(changeset), -- {:ok, object} <- Object.set_cache(object) do -+ defp reinject_object(_, new_data) do -+ with {:ok, object, _} <- Pipeline.common_pipeline(new_data, local: false) do - {:ok, object} - else -- e -> -- Logger.error("Error while processing object: #{inspect(e)}") -- {:error, e} -+ e -> e - end - end - -diff --git a/lib/pleroma/object/updater.ex b/lib/pleroma/object/updater.ex -index ab38d3ed2b65c843b9268e6b01cb214dbc26b3bb..b1e4870bac4c7900966a57d7dd6774606c0f6109 100644 ---- a/lib/pleroma/object/updater.ex -+++ b/lib/pleroma/object/updater.ex -@@ -5,6 +5,9 @@ - defmodule Pleroma.Object.Updater do - require Pleroma.Constants - -+ alias Pleroma.Object -+ alias Pleroma.Repo -+ - def update_content_fields(orig_object_data, updated_object) do - Pleroma.Constants.status_updatable_fields() - |> Enum.reduce( -@@ -97,12 +100,14 @@ def maybe_update_history( - end - - defp maybe_update_poll(to_be_updated, updated_object) do -- choice_key = fn data -> -- if Map.has_key?(data, "anyOf"), do: "anyOf", else: "oneOf" -+ choice_key = fn -+ %{"anyOf" => [_ | _]} -> "anyOf" -+ %{"oneOf" => [_ | _]} -> "oneOf" -+ _ -> nil - end - - with true <- to_be_updated["type"] == "Question", -- key <- choice_key.(updated_object), -+ key when not is_nil(key) <- choice_key.(updated_object), - true <- key == choice_key.(to_be_updated), - orig_choices <- to_be_updated[key] |> Enum.map(&Map.drop(&1, ["replies"])), - new_choices <- updated_object[key] |> Enum.map(&Map.drop(&1, ["replies"])), -@@ -237,4 +242,49 @@ def do_with_history(object, fun) do - {:history_items, e} -> e - end - end -+ -+ defp maybe_touch_changeset(changeset, true) do -+ updated_at = -+ NaiveDateTime.utc_now() -+ |> NaiveDateTime.truncate(:second) -+ -+ Ecto.Changeset.put_change(changeset, :updated_at, updated_at) -+ end -+ -+ defp maybe_touch_changeset(changeset, _), do: changeset -+ -+ def do_update_and_invalidate_cache(orig_object, updated_object, touch_changeset? \\ false) do -+ orig_object_ap_id = updated_object["id"] -+ orig_object_data = orig_object.data -+ -+ %{ -+ updated_data: updated_object_data, -+ updated: updated, -+ used_history_in_new_object?: used_history_in_new_object? -+ } = make_new_object_data_from_update_object(orig_object_data, updated_object) -+ -+ changeset = -+ orig_object -+ |> Repo.preload(:hashtags) -+ |> Object.change(%{data: updated_object_data}) -+ |> maybe_touch_changeset(touch_changeset?) -+ -+ with {:ok, new_object} <- Repo.update(changeset), -+ {:ok, _} <- Object.invalid_object_cache(new_object), -+ {:ok, _} <- Object.set_cache(new_object), -+ # The metadata/utils.ex uses the object id for the cache. -+ {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(new_object.id) do -+ if used_history_in_new_object? do -+ with create_activity when not is_nil(create_activity) <- -+ Pleroma.Activity.get_create_by_object_ap_id(orig_object_ap_id), -+ {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(create_activity.id) do -+ nil -+ else -+ _ -> nil -+ end -+ end -+ -+ {:ok, new_object, updated} -+ end -+ end - end -diff --git a/lib/pleroma/web/activity_pub/side_effects.ex b/lib/pleroma/web/activity_pub/side_effects.ex -index a2152b945235892d7f87c3fb4b185a740bd4112e..fc5dec3628c7f5e0e19c2c91cdb4baa22f103a39 100644 ---- a/lib/pleroma/web/activity_pub/side_effects.ex -+++ b/lib/pleroma/web/activity_pub/side_effects.ex -@@ -428,37 +428,13 @@ defp handle_update_object( - end - - if orig_object_data["type"] in Pleroma.Constants.updatable_object_types() do -- %{ -- updated_data: updated_object_data, -- updated: updated, -- used_history_in_new_object?: used_history_in_new_object? -- } = Object.Updater.make_new_object_data_from_update_object(orig_object_data, updated_object) -- -- changeset = -- orig_object -- |> Repo.preload(:hashtags) -- |> Object.change(%{data: updated_object_data}) -- -- with {:ok, new_object} <- Repo.update(changeset), -- {:ok, _} <- Object.invalid_object_cache(new_object), -- {:ok, _} <- Object.set_cache(new_object), -- # The metadata/utils.ex uses the object id for the cache. -- {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(new_object.id) do -- if used_history_in_new_object? do -- with create_activity when not is_nil(create_activity) <- -- Pleroma.Activity.get_create_by_object_ap_id(orig_object_ap_id), -- {:ok, _} <- Pleroma.Activity.HTML.invalidate_cache_for(create_activity.id) do -- nil -- else -- _ -> nil -- end -- end -+ {:ok, _, updated} = -+ Object.Updater.do_update_and_invalidate_cache(orig_object, updated_object) - -- if updated do -- object -- |> Activity.normalize() -- |> ActivityPub.notify_and_stream() -- end -+ if updated do -+ object -+ |> Activity.normalize() -+ |> ActivityPub.notify_and_stream() - end - end - -diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex -index 449659f4bbe7b37a3c5f9d11b55fe7036d0d425f..034722eb2e7a7c99fcb1384132d81b6ed7dcd3f1 100644 ---- a/lib/pleroma/web/feed/feed_view.ex -+++ b/lib/pleroma/web/feed/feed_view.ex -@@ -6,7 +6,6 @@ defmodule Pleroma.Web.Feed.FeedView do - use Phoenix.HTML - use Pleroma.Web, :view - -- alias Pleroma.Formatter - alias Pleroma.Object - alias Pleroma.User - alias Pleroma.Web.Gettext -@@ -72,7 +71,9 @@ def logo(user) do - - def last_activity(activities), do: List.last(activities) - -- def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ %{}) do -+ def activity_title(%{"content" => content} = data, opts \\ %{}) do -+ summary = Map.get(data, "summary", "") -+ - title = - cond do - summary != "" -> summary -@@ -81,9 +82,8 @@ def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ - end - - title -- |> Pleroma.Web.Metadata.Utils.scrub_html() -- |> Pleroma.Emoji.Formatter.demojify() -- |> Formatter.truncate(opts[:max_length], opts[:omission]) -+ |> Pleroma.Web.Metadata.Utils.scrub_html_and_truncate(opts[:max_length], opts[:omission]) -+ |> HtmlEntities.encode() - end - - def activity_description(data) do -diff --git a/lib/pleroma/web/media_proxy/media_proxy_controller.ex b/lib/pleroma/web/media_proxy/media_proxy_controller.ex -index d2ad62c13910fbb4a53630ff395089ce204ee8dc..bda5b36edcea2341d29052567b0b4638d3d41660 100644 ---- a/lib/pleroma/web/media_proxy/media_proxy_controller.ex -+++ b/lib/pleroma/web/media_proxy/media_proxy_controller.ex -@@ -12,6 +12,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyController do - alias Pleroma.Web.MediaProxy - alias Plug.Conn - -+ plug(:sandbox) -+ - def remote(conn, %{"sig" => sig64, "url" => url64}) do - with {_, true} <- {:enabled, MediaProxy.enabled?()}, - {:ok, url} <- MediaProxy.decode_url(sig64, url64), -@@ -202,4 +204,9 @@ defp media_preview_proxy_config do - defp media_proxy_opts do - Config.get([:media_proxy, :proxy_opts], []) - end -+ -+ defp sandbox(conn, _params) do -+ conn -+ |> merge_resp_headers([{"content-security-policy", "sandbox;"}]) -+ end - end -diff --git a/lib/pleroma/web/metadata/utils.ex b/lib/pleroma/web/metadata/utils.ex -index 15414a988d72ca36c2ea8e92f6b7528ce4d8df94..80a8be9a2d5e2db48f37d1ff809c1e565517a087 100644 ---- a/lib/pleroma/web/metadata/utils.ex -+++ b/lib/pleroma/web/metadata/utils.ex -@@ -30,12 +30,13 @@ def scrub_html_and_truncate(%{data: %{"content" => content}} = object) do - |> scrub_html_and_truncate_object_field(object) - end - -- def scrub_html_and_truncate(content, max_length \\ 200) when is_binary(content) do -+ def scrub_html_and_truncate(content, max_length \\ 200, omission \\ "...") -+ when is_binary(content) do - content - |> scrub_html - |> Emoji.Formatter.demojify() - |> HtmlEntities.decode() -- |> Formatter.truncate(max_length) -+ |> Formatter.truncate(max_length, omission) - end - - def scrub_html(content) when is_binary(content) do -diff --git a/lib/pleroma/web/plugs/authentication_plug.ex b/lib/pleroma/web/plugs/authentication_plug.ex -index a7fd697b5d106a5101ea484d79ca05b3cbd3fc97..f912a1542f8a761cb4cee485528beddd2f0cc60c 100644 ---- a/lib/pleroma/web/plugs/authentication_plug.ex -+++ b/lib/pleroma/web/plugs/authentication_plug.ex -@@ -38,10 +38,6 @@ def call( - - def call(conn, _), do: conn - -- def checkpw(password, "$6" <> _ = password_hash) do -- :crypt.crypt(password, password_hash) == password_hash -- end -- - def checkpw(password, "$2" <> _ = password_hash) do - # Handle bcrypt passwords for Mastodon migration - Bcrypt.verify_pass(password, password_hash) -@@ -60,10 +56,6 @@ def maybe_update_password(%User{password_hash: "$2" <> _} = user, password) do - do_update_password(user, password) - end - -- def maybe_update_password(%User{password_hash: "$6" <> _} = user, password) do -- do_update_password(user, password) -- end -- - def maybe_update_password(user, _), do: {:ok, user} - - defp do_update_password(user, password) do -diff --git a/lib/pleroma/web/rich_media/parsers/o_embed.ex b/lib/pleroma/web/rich_media/parsers/o_embed.ex -index 75318d9c7207bc0cf2890a5193bb0eeed6600418..0f303176ce849ad36587859edf7d1af73773edbe 100644 ---- a/lib/pleroma/web/rich_media/parsers/o_embed.ex -+++ b/lib/pleroma/web/rich_media/parsers/o_embed.ex -@@ -6,8 +6,8 @@ defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do - def parse(html, _data) do - with elements = [_ | _] <- get_discovery_data(html), - oembed_url when is_binary(oembed_url) <- get_oembed_url(elements), -- {:ok, oembed_data} <- get_oembed_data(oembed_url) do -- oembed_data -+ {:ok, oembed_data = %{"html" => html}} <- get_oembed_data(oembed_url) do -+ %{oembed_data | "html" => Pleroma.HTML.filter_tags(html)} - else - _e -> %{} - end -diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex -index ba1d64ab23dbf9f21342c239d800708724e9498d..c1a690e28a59009292587d76176a80cd73715fb4 100644 ---- a/lib/pleroma/web/router.ex -+++ b/lib/pleroma/web/router.ex -@@ -835,8 +835,7 @@ defmodule Pleroma.Web.Router do - end - - scope "/", Pleroma.Web do -- # Note: html format is supported only if static FE is enabled -- pipe_through([:accepts_html_xml, :static_fe]) -+ pipe_through([:accepts_html_xml]) - - get("/users/:nickname/feed", Feed.UserController, :feed, as: :user_feed) - end -diff --git a/lib/pleroma/web/streamer.ex b/lib/pleroma/web/streamer.ex -index 3c0da5c276d7aa0936511a9726d001405eee0243..b9a04cc7674408bd063cd0cb5c4d3ef8d055afb8 100644 ---- a/lib/pleroma/web/streamer.ex -+++ b/lib/pleroma/web/streamer.ex -@@ -25,6 +25,7 @@ defmodule Pleroma.Web.Streamer do - def registry, do: @registry - - @public_streams ["public", "public:local", "public:media", "public:local:media"] -+ @local_streams ["public:local", "public:local:media"] - @user_streams ["user", "user:notification", "direct", "user:pleroma_chat"] - - @doc "Expands and authorizes a stream, and registers the process for streaming." -@@ -41,14 +42,37 @@ def get_topic_and_add_socket(stream, user, oauth_token, params \\ %{}) do - end - end - -+ defp can_access_stream(user, oauth_token, kind) do -+ with {_, true} <- {:restrict?, Config.restrict_unauthenticated_access?(:timelines, kind)}, -+ {_, %User{id: user_id}, %Token{user_id: user_id}} <- {:user, user, oauth_token}, -+ {_, true} <- -+ {:scopes, -+ OAuthScopesPlug.filter_descendants(["read:statuses"], oauth_token.scopes) != []} do -+ true -+ else -+ {:restrict?, _} -> -+ true -+ -+ _ -> -+ false -+ end -+ end -+ - @doc "Expand and authorizes a stream" - @spec get_topic(stream :: String.t(), User.t() | nil, Token.t() | nil, Map.t()) :: - {:ok, topic :: String.t()} | {:error, :bad_topic} - def get_topic(stream, user, oauth_token, params \\ %{}) - -- # Allow all public steams. -- def get_topic(stream, _user, _oauth_token, _params) when stream in @public_streams do -- {:ok, stream} -+ # Allow all public steams if the instance allows unauthenticated access. -+ # Otherwise, only allow users with valid oauth tokens. -+ def get_topic(stream, user, oauth_token, _params) when stream in @public_streams do -+ kind = if stream in @local_streams, do: :local, else: :federated -+ -+ if can_access_stream(user, oauth_token, kind) do -+ {:ok, stream} -+ else -+ {:error, :unauthorized} -+ end - end - - # Allow all hashtags streams. -@@ -57,12 +81,20 @@ def get_topic("hashtag", _user, _oauth_token, %{"tag" => tag} = _params) do - end - - # Allow remote instance streams. -- def get_topic("public:remote", _user, _oauth_token, %{"instance" => instance} = _params) do -- {:ok, "public:remote:" <> instance} -+ def get_topic("public:remote", user, oauth_token, %{"instance" => instance} = _params) do -+ if can_access_stream(user, oauth_token, :federated) do -+ {:ok, "public:remote:" <> instance} -+ else -+ {:error, :unauthorized} -+ end - end - -- def get_topic("public:remote:media", _user, _oauth_token, %{"instance" => instance} = _params) do -- {:ok, "public:remote:media:" <> instance} -+ def get_topic("public:remote:media", user, oauth_token, %{"instance" => instance} = _params) do -+ if can_access_stream(user, oauth_token, :federated) do -+ {:ok, "public:remote:media:" <> instance} -+ else -+ {:error, :unauthorized} -+ end - end - - # Expand user streams. -diff --git a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex -index 260338772ac9823de69c4c85fe2eb7765bcd9b9d..b774f7984428c554757867b3d1934b7d24bc1547 100644 ---- a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex -+++ b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex -@@ -4,8 +4,8 @@ - <%= @data["id"] %> - <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_description(@data) %> -- <%= to_rfc3339(@activity.data["published"]) %> -- <%= to_rfc3339(@activity.data["published"]) %> -+ <%= to_rfc3339(@data["published"]) %> -+ <%= to_rfc3339(@data["published"]) %> - - <%= activity_context(@activity) %> - -diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex -index 5c8f35fe47f44a93d889580334463d884143e32b..7de98f73682965562b1d013cfe17e804c397ba83 100644 ---- a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex -+++ b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex -@@ -4,7 +4,7 @@ - <%= @data["id"] %> - <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_description(@data) %> -- <%= to_rfc2822(@activity.data["published"]) %> -+ <%= to_rfc2822(@data["published"]) %> - - <%= activity_context(@activity) %> - -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 25980c1e4292b1eb3e197325229e1f2118747cb6..03c222975ec756c28fbdc35578402ddd0976fbab 100644 ---- a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex -+++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex -@@ -7,8 +7,8 @@ - <%= @data["id"] %> - <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_description(@data) %> -- <%= to_rfc3339(@activity.data["published"]) %> -- <%= to_rfc3339(@activity.data["published"]) %> -+ <%= to_rfc3339(@data["published"]) %> -+ <%= to_rfc3339(@data["published"]) %> - - <%= activity_context(@activity) %> - -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 d582c83e8c7f497e299899b611a6e522046779f8..1b8c34b87101e664ecdf6c6f6735a53f794ea3db 100644 ---- a/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex -+++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex -@@ -4,7 +4,7 @@ - - <%= activity_context(@activity) %> - <%= activity_context(@activity) %> -- <%= to_rfc2822(@activity.data["published"]) %> -+ <%= to_rfc2822(@data["published"]) %> - - <%= activity_description(@data) %> - <%= for attachment <- @data["attachment"] || [] do %> -diff --git a/lib/pleroma/workers/background_worker.ex b/lib/pleroma/workers/background_worker.ex -index 3805293bc351f91e80e042bac8c730e6f3a9cbb2..79441761267b8a4aa54a86bb94228440fb73cb15 100644 ---- a/lib/pleroma/workers/background_worker.ex -+++ b/lib/pleroma/workers/background_worker.ex -@@ -45,5 +45,5 @@ def perform(%Job{args: %{"op" => "delete_instance", "host" => host}}) do - end - - @impl Oban.Worker -- def timeout(_job), do: :timer.seconds(5) -+ def timeout(_job), do: :timer.seconds(900) - end -diff --git a/lib/pleroma/workers/receiver_worker.ex b/lib/pleroma/workers/receiver_worker.ex -index 4f513b907481ee86c14ef5fa6552aa32a0eedc31..cf1bb62b44e2d0f26cc66b883d65d3f4bb4c6768 100644 ---- a/lib/pleroma/workers/receiver_worker.ex -+++ b/lib/pleroma/workers/receiver_worker.ex -@@ -13,6 +13,9 @@ def perform(%Job{args: %{"op" => "incoming_ap_doc", "params" => params}}) do - {:ok, res} - else - {:error, :origin_containment_failed} -> {:cancel, :origin_containment_failed} -+ {:error, :already_present} -> {:cancel, :already_present} -+ {:error, {:validate_object, reason}} -> {:cancel, reason} -+ {:error, {:error, {:validate, reason}}} -> {:cancel, reason} - {:error, {:reject, reason}} -> {:cancel, reason} - e -> e - end -diff --git a/mix.exs b/mix.exs -index ab0be4deb0f6ff76df4a084d9672729c536d07a0..79fd9c9efebee61253cb417aed03fc95b52bf7be 100644 ---- a/mix.exs -+++ b/mix.exs -@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do - def project do - [ - app: :pleroma, -- version: version("2.5.1"), -+ version: version("2.5.2"), - elixir: "~> 1.11", - elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix, :gettext] ++ Mix.compilers(), -@@ -150,7 +150,6 @@ defp deps do - {:sweet_xml, "~> 0.7.2"}, - {:earmark, "~> 1.4.22"}, - {:bbcode_pleroma, "~> 0.2.0"}, -- {:crypt, "~> 1.0"}, - {:cors_plug, "~> 2.0"}, - {:web_push_encryption, "~> 0.3.1"}, - {:swoosh, "~> 1.0"}, -diff --git a/mix.lock b/mix.lock -index 3027863262e5fc733b9a11b39d25d918e49515ce..8419dc73972280de7f3f5b5b2b6135ae0f08ace5 100644 ---- a/mix.lock -+++ b/mix.lock -@@ -21,7 +21,6 @@ - "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, - "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, - "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, -- "crypt": {:hex, :crypt, "1.0.1", "a3567e1c651a2ec42c6650d9f3ab789e0f12a508c060653a9bbb5fafe60f043c", [:rebar3], [], "hexpm", "968dffe321c7a5d9f9b4577c4a4ff56a1c26d1a8a2270eb22c7636a0b43d3982"}, - "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, - "db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"}, - "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, -diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs -index c8ad66ddb45eda7658a1d552ab8948cbef004417..53c9277d6778014dbcd8a9f0de26e595375766a9 100644 ---- a/test/pleroma/object/fetcher_test.exs -+++ b/test/pleroma/object/fetcher_test.exs -@@ -9,8 +9,12 @@ defmodule Pleroma.Object.FetcherTest do - alias Pleroma.Instances - alias Pleroma.Object - alias Pleroma.Object.Fetcher -+ alias Pleroma.Web.ActivityPub.ObjectValidator -+ -+ require Pleroma.Constants - - import Mock -+ import Pleroma.Factory - import Tesla.Mock - - setup do -@@ -284,6 +288,8 @@ test "it can refetch pruned objects" do - - describe "refetching" do - setup do -+ insert(:user, ap_id: "https://mastodon.social/users/emelie") -+ - object1 = %{ - "id" => "https://mastodon.social/1", - "actor" => "https://mastodon.social/users/emelie", -@@ -293,10 +299,14 @@ test "it can refetch pruned objects" do - "bcc" => [], - "bto" => [], - "cc" => [], -- "to" => [], -- "summary" => "" -+ "to" => [Pleroma.Constants.as_public()], -+ "summary" => "", -+ "published" => "2023-05-08 23:43:20Z", -+ "updated" => "2023-05-09 23:43:20Z" - } - -+ {:ok, local_object1, _} = ObjectValidator.validate(object1, []) -+ - object2 = %{ - "id" => "https://mastodon.social/2", - "actor" => "https://mastodon.social/users/emelie", -@@ -306,8 +316,10 @@ test "it can refetch pruned objects" do - "bcc" => [], - "bto" => [], - "cc" => [], -- "to" => [], -+ "to" => [Pleroma.Constants.as_public()], - "summary" => "", -+ "published" => "2023-05-08 23:43:20Z", -+ "updated" => "2023-05-09 23:43:25Z", - "formerRepresentations" => %{ - "type" => "OrderedCollection", - "orderedItems" => [ -@@ -319,14 +331,18 @@ test "it can refetch pruned objects" do - "bcc" => [], - "bto" => [], - "cc" => [], -- "to" => [], -- "summary" => "" -+ "to" => [Pleroma.Constants.as_public()], -+ "summary" => "", -+ "published" => "2023-05-08 23:43:20Z", -+ "updated" => "2023-05-09 23:43:21Z" - } - ], - "totalItems" => 1 - } - } - -+ {:ok, local_object2, _} = ObjectValidator.validate(object2, []) -+ - mock(fn - %{ - method: :get, -@@ -335,7 +351,7 @@ test "it can refetch pruned objects" do - %Tesla.Env{ - status: 200, - headers: [{"content-type", "application/activity+json"}], -- body: Jason.encode!(object1) -+ body: Jason.encode!(object1 |> Map.put("updated", "2023-05-09 23:44:20Z")) - } - - %{ -@@ -345,7 +361,7 @@ test "it can refetch pruned objects" do - %Tesla.Env{ - status: 200, - headers: [{"content-type", "application/activity+json"}], -- body: Jason.encode!(object2) -+ body: Jason.encode!(object2 |> Map.put("updated", "2023-05-09 23:44:20Z")) - } - - %{ -@@ -370,7 +386,7 @@ test "it can refetch pruned objects" do - apply(HttpRequestMock, :request, [env]) - end) - -- %{object1: object1, object2: object2} -+ %{object1: local_object1, object2: local_object2} - end - - test "it keeps formerRepresentations if remote does not have this attr", %{object1: object1} do -@@ -388,8 +404,9 @@ test "it keeps formerRepresentations if remote does not have this attr", %{objec - "bcc" => [], - "bto" => [], - "cc" => [], -- "to" => [], -- "summary" => "" -+ "to" => [Pleroma.Constants.as_public()], -+ "summary" => "", -+ "published" => "2023-05-08 23:43:20Z" - } - ], - "totalItems" => 1 -@@ -467,6 +484,53 @@ test "it adds to formerRepresentations if the remote does not have one and the o - } - } = refetched.data - end -+ -+ test "it keeps the history intact if only updated time has changed", -+ %{object1: object1} do -+ full_object1 = -+ object1 -+ |> Map.merge(%{ -+ "updated" => "2023-05-08 23:43:47Z", -+ "formerRepresentations" => %{ -+ "type" => "OrderedCollection", -+ "orderedItems" => [ -+ %{"type" => "Note", "content" => "mew mew 1"} -+ ], -+ "totalItems" => 1 -+ } -+ }) -+ -+ {:ok, o} = Object.create(full_object1) -+ -+ assert {:ok, refetched} = Fetcher.refetch_object(o) -+ -+ assert %{ -+ "content" => "test 1", -+ "formerRepresentations" => %{ -+ "orderedItems" => [ -+ %{"content" => "mew mew 1"} -+ ], -+ "totalItems" => 1 -+ } -+ } = refetched.data -+ end -+ -+ test "it goes through ObjectValidator and MRF", %{object2: object2} do -+ with_mock Pleroma.Web.ActivityPub.MRF, [:passthrough], -+ filter: fn -+ %{"type" => "Note"} = object -> -+ {:ok, Map.put(object, "content", "MRFd content")} -+ -+ arg -> -+ passthrough([arg]) -+ end do -+ {:ok, o} = Object.create(object2) -+ -+ assert {:ok, refetched} = Fetcher.refetch_object(o) -+ -+ assert %{"content" => "MRFd content"} = refetched.data -+ end -+ end - end - - describe "fetch with history" do -diff --git a/test/pleroma/web/federator_test.exs b/test/pleroma/web/federator_test.exs -index 41d1c5d5e842f627668eba496f19b1f50fe9eaa2..1ffe6aae15d129eca24bbdbb1324862ddde0421a 100644 ---- a/test/pleroma/web/federator_test.exs -+++ b/test/pleroma/web/federator_test.exs -@@ -133,7 +133,7 @@ test "successfully processes incoming AP docs with correct origin" do - assert {:ok, _activity} = ObanHelpers.perform(job) - - assert {:ok, job} = Federator.incoming_ap_doc(params) -- assert {:error, :already_present} = ObanHelpers.perform(job) -+ assert {:cancel, :already_present} = ObanHelpers.perform(job) - end - - test "rejects incoming AP docs with incorrect origin" do -diff --git a/test/pleroma/web/feed/user_controller_test.exs b/test/pleroma/web/feed/user_controller_test.exs -index de32d3d4bf0398692fd16e4bc15c94cc8ac0a81b..d3c4108de09bc3a1d8a41bb427999026848b6b6e 100644 ---- a/test/pleroma/web/feed/user_controller_test.exs -+++ b/test/pleroma/web/feed/user_controller_test.exs -@@ -57,9 +57,23 @@ defmodule Pleroma.Web.Feed.UserControllerTest do - ) - - note_activity2 = insert(:note_activity, note: note2) -+ -+ note3 = -+ insert(:note, -+ user: user, -+ data: %{ -+ "content" => "This note tests whether HTML entities are truncated properly", -+ "summary" => "Won't, didn't fail", -+ "inReplyTo" => note_activity2.id -+ } -+ ) -+ -+ _note_activity3 = insert(:note_activity, note: note3) - object = Object.normalize(note_activity, fetch: false) - -- [user: user, object: object, max_id: note_activity2.id] -+ encoded_title = FeedView.activity_title(note3.data) -+ -+ [user: user, object: object, max_id: note_activity2.id, encoded_title: encoded_title] - end - - test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_id} do -@@ -74,7 +88,7 @@ test "gets an atom feed", %{conn: conn, user: user, object: object, max_id: max_ - |> SweetXml.parse() - |> SweetXml.xpath(~x"//entry/title/text()"l) - -- assert activity_titles == ['2hu', '2hu & as'] -+ assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as'] - assert resp =~ FeedView.escape(object.data["content"]) - assert resp =~ FeedView.escape(object.data["summary"]) - assert resp =~ FeedView.escape(object.data["context"]) -@@ -105,7 +119,7 @@ test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id - |> SweetXml.parse() - |> SweetXml.xpath(~x"//item/title/text()"l) - -- assert activity_titles == ['2hu', '2hu & as'] -+ assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as'] - assert resp =~ FeedView.escape(object.data["content"]) - assert resp =~ FeedView.escape(object.data["summary"]) - assert resp =~ FeedView.escape(object.data["context"]) -@@ -176,6 +190,30 @@ test "does not require authentication on non-federating instances", %{conn: conn - |> get("/users/#{user.nickname}/feed.rss") - |> response(200) - end -+ -+ test "does not mangle HTML entities midway", %{ -+ conn: conn, -+ user: user, -+ object: object, -+ encoded_title: encoded_title -+ } do -+ resp = -+ conn -+ |> put_req_header("accept", "application/atom+xml") -+ |> get(user_feed_path(conn, :feed, user.nickname)) -+ |> response(200) -+ -+ activity_titles = -+ resp -+ |> SweetXml.parse() -+ |> SweetXml.xpath(~x"//entry/title/text()"l) -+ -+ assert activity_titles == ['Won\'t, didn\'...', '2hu', '2hu & as'] -+ assert resp =~ FeedView.escape(object.data["content"]) -+ assert resp =~ FeedView.escape(object.data["summary"]) -+ assert resp =~ FeedView.escape(object.data["context"]) -+ assert resp =~ encoded_title -+ end - end - - # Note: see ActivityPubControllerTest for JSON format tests -diff --git a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs -index 5246bf0c4b1990e9c8948f1e0bab4b94c64271f7..9ce092fd8fa01c3cb548deffe21cb726ed6c0d77 100644 ---- a/test/pleroma/web/media_proxy/media_proxy_controller_test.exs -+++ b/test/pleroma/web/media_proxy/media_proxy_controller_test.exs -@@ -6,7 +6,9 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do - use Pleroma.Web.ConnCase - - import Mock -+ import Mox - -+ alias Pleroma.ReverseProxy.ClientMock - alias Pleroma.Web.MediaProxy - alias Plug.Conn - -@@ -74,6 +76,20 @@ test "it returns 404 when url is in banned_urls cache", %{conn: conn, url: url} - assert %Conn{status: 404, resp_body: "Not Found"} = get(conn, url) - end - end -+ -+ test "it applies sandbox CSP to MediaProxy requests", %{conn: conn} do -+ media_url = "https://lain.com/image.png" -+ media_proxy_url = MediaProxy.encode_url(media_url) -+ -+ ClientMock -+ |> expect(:request, fn :get, ^media_url, _, _, _ -> -+ {:ok, 200, [{"content-type", "image/png"}]} -+ end) -+ -+ %Conn{resp_headers: headers} = get(conn, media_proxy_url) -+ -+ assert {"content-security-policy", "sandbox;"} in headers -+ end - end - - describe "Media Preview Proxy" do -diff --git a/test/pleroma/web/metadata/utils_test.exs b/test/pleroma/web/metadata/utils_test.exs -index 85ef6033a7c77b47d7e315ab28272d5efd9f0f5e..3daf852fba8d75c3783ac66b3f2212344b4a40ae 100644 ---- a/test/pleroma/web/metadata/utils_test.exs -+++ b/test/pleroma/web/metadata/utils_test.exs -@@ -72,7 +72,7 @@ test "it does not return old content after editing" do - end - end - -- describe "scrub_html_and_truncate/2" do -+ describe "scrub_html_and_truncate/3" do - test "it returns text without encode HTML" do - assert Utils.scrub_html_and_truncate("Pleroma's really cool!") == "Pleroma's really cool!" - end -diff --git a/test/pleroma/web/plugs/authentication_plug_test.exs b/test/pleroma/web/plugs/authentication_plug_test.exs -index 41fdb93bc96338125067d525b48c4b9e98ba069e..b8acd01c59232fc1d97f98f4850867da946c1fa4 100644 ---- a/test/pleroma/web/plugs/authentication_plug_test.exs -+++ b/test/pleroma/web/plugs/authentication_plug_test.exs -@@ -70,28 +70,6 @@ test "with a bcrypt hash, it updates to a pkbdf2 hash", %{conn: conn} do - assert "$pbkdf2" <> _ = user.password_hash - end - -- @tag :skip_on_mac -- test "with a crypt hash, it updates to a pkbdf2 hash", %{conn: conn} do -- user = -- insert(:user, -- password_hash: -- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" -- ) -- -- conn = -- conn -- |> assign(:auth_user, user) -- |> assign(:auth_credentials, %{password: "password"}) -- |> AuthenticationPlug.call(%{}) -- -- assert conn.assigns.user.id == conn.assigns.auth_user.id -- assert conn.assigns.token == nil -- assert PlugHelper.plug_skipped?(conn, OAuthScopesPlug) -- -- user = User.get_by_id(user.id) -- assert "$pbkdf2" <> _ = user.password_hash -- end -- - describe "checkpw/2" do - test "check pbkdf2 hash" do - hash = -@@ -101,14 +79,6 @@ test "check pbkdf2 hash" do - refute AuthenticationPlug.checkpw("test-password1", hash) - end - -- @tag :skip_on_mac -- test "check sha512-crypt hash" do -- hash = -- "$6$9psBWV8gxkGOZWBz$PmfCycChoxeJ3GgGzwvhlgacb9mUoZ.KUXNCssekER4SJ7bOK53uXrHNb2e4i8yPFgSKyzaW9CcmrDXWIEMtD1" -- -- assert AuthenticationPlug.checkpw("password", hash) -- end -- - test "check bcrypt hash" do - hash = "$2a$10$uyhC/R/zoE1ndwwCtMusK.TLVzkQ/Ugsbqp3uXI.CTTz0gBw.24jS" - -diff --git a/test/pleroma/web/rich_media/parser_test.exs b/test/pleroma/web/rich_media/parser_test.exs -index ffdc4e5d78cf1b00ffbef87b19cde55e2fde5469..9064138a64352f8374eeced43659eabd847b0ab2 100644 ---- a/test/pleroma/web/rich_media/parser_test.exs -+++ b/test/pleroma/web/rich_media/parser_test.exs -@@ -129,7 +129,7 @@ test "parses twitter card" do - }} - end - -- test "parses OEmbed" do -+ test "parses OEmbed and filters HTML tags" do - assert Parser.parse("http://example.com/oembed") == - {:ok, - %{ -@@ -139,7 +139,7 @@ test "parses OEmbed" do - "flickr_type" => "photo", - "height" => "768", - "html" => -- "\"Bacon", -+ "\"Bacon", - "license" => "All Rights Reserved", - "license_id" => 0, - "provider_name" => "Flickr", -diff --git a/test/pleroma/web/streamer_test.exs b/test/pleroma/web/streamer_test.exs -index 8b0c84164dfa20067f9fd96a35225a1dbe93e142..7ab0e379b403b04954c965057a53be8a0f465121 100644 ---- a/test/pleroma/web/streamer_test.exs -+++ b/test/pleroma/web/streamer_test.exs -@@ -29,6 +29,26 @@ test "allows public" do - assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil, nil) - end - -+ test "rejects local public streams if restricted_unauthenticated is on" do -+ clear_config([:restrict_unauthenticated, :timelines, :local], true) -+ -+ assert {:error, :unauthorized} = Streamer.get_topic("public:local", nil, nil) -+ assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", nil, nil) -+ end -+ -+ test "rejects remote public streams if restricted_unauthenticated is on" do -+ clear_config([:restrict_unauthenticated, :timelines, :federated], true) -+ -+ assert {:error, :unauthorized} = Streamer.get_topic("public", nil, nil) -+ assert {:error, :unauthorized} = Streamer.get_topic("public:media", nil, nil) -+ -+ assert {:error, :unauthorized} = -+ Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"}) -+ -+ assert {:error, :unauthorized} = -+ Streamer.get_topic("public:remote:media", nil, nil, %{"instance" => "lain.com"}) -+ end -+ - test "allows instance streams" do - assert {:ok, "public:remote:lain.com"} = - Streamer.get_topic("public:remote", nil, nil, %{"instance" => "lain.com"}) -@@ -69,6 +89,63 @@ test "allows public streams (regardless of OAuth token scopes)", %{ - end - end - -+ test "allows local public streams if restricted_unauthenticated is on", %{ -+ user: user, -+ token: oauth_token -+ } do -+ clear_config([:restrict_unauthenticated, :timelines, :local], true) -+ -+ %{token: read_notifications_token} = oauth_access(["read:notifications"], user: user) -+ %{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user) -+ -+ assert {:ok, "public:local"} = Streamer.get_topic("public:local", user, oauth_token) -+ -+ assert {:ok, "public:local:media"} = -+ Streamer.get_topic("public:local:media", user, oauth_token) -+ -+ for token <- [read_notifications_token, badly_scoped_token] do -+ assert {:error, :unauthorized} = Streamer.get_topic("public:local", user, token) -+ -+ assert {:error, :unauthorized} = Streamer.get_topic("public:local:media", user, token) -+ end -+ end -+ -+ test "allows remote public streams if restricted_unauthenticated is on", %{ -+ user: user, -+ token: oauth_token -+ } do -+ clear_config([:restrict_unauthenticated, :timelines, :federated], true) -+ -+ %{token: read_notifications_token} = oauth_access(["read:notifications"], user: user) -+ %{token: badly_scoped_token} = oauth_access(["irrelevant:scope"], user: user) -+ -+ assert {:ok, "public"} = Streamer.get_topic("public", user, oauth_token) -+ assert {:ok, "public:media"} = Streamer.get_topic("public:media", user, oauth_token) -+ -+ assert {:ok, "public:remote:lain.com"} = -+ Streamer.get_topic("public:remote", user, oauth_token, %{"instance" => "lain.com"}) -+ -+ assert {:ok, "public:remote:media:lain.com"} = -+ Streamer.get_topic("public:remote:media", user, oauth_token, %{ -+ "instance" => "lain.com" -+ }) -+ -+ for token <- [read_notifications_token, badly_scoped_token] do -+ assert {:error, :unauthorized} = Streamer.get_topic("public", user, token) -+ assert {:error, :unauthorized} = Streamer.get_topic("public:media", user, token) -+ -+ assert {:error, :unauthorized} = -+ Streamer.get_topic("public:remote", user, token, %{ -+ "instance" => "lain.com" -+ }) -+ -+ assert {:error, :unauthorized} = -+ Streamer.get_topic("public:remote:media", user, token, %{ -+ "instance" => "lain.com" -+ }) -+ end -+ end -+ - test "allows user streams (with proper OAuth token scopes)", %{ - user: user, - token: read_oauth_token -diff --git a/test/pleroma/workers/receiver_worker_test.exs b/test/pleroma/workers/receiver_worker_test.exs -index 283beee4d552293f22a01a2bf184e0ad065a43f3..acea0ae0003812e18e5d5b42df72744c58b6f26a 100644 ---- a/test/pleroma/workers/receiver_worker_test.exs -+++ b/test/pleroma/workers/receiver_worker_test.exs -@@ -11,7 +11,7 @@ defmodule Pleroma.Workers.ReceiverWorkerTest do - - alias Pleroma.Workers.ReceiverWorker - -- test "it ignores MRF reject" do -+ test "it does not retry MRF reject" do - params = insert(:note).data - - with_mock Pleroma.Web.ActivityPub.Transmogrifier, -@@ -22,4 +22,31 @@ test "it ignores MRF reject" do - }) - end - end -+ -+ test "it does not retry ObjectValidator reject" do -+ params = -+ insert(:note_activity).data -+ |> Map.put("id", Pleroma.Web.ActivityPub.Utils.generate_activity_id()) -+ |> Map.put("object", %{ -+ "type" => "Note", -+ "id" => Pleroma.Web.ActivityPub.Utils.generate_object_id() -+ }) -+ -+ with_mock Pleroma.Web.ActivityPub.ObjectValidator, [:passthrough], -+ validate: fn _, _ -> {:error, %Ecto.Changeset{}} end do -+ assert {:cancel, {:error, %Ecto.Changeset{}}} = -+ ReceiverWorker.perform(%Oban.Job{ -+ args: %{"op" => "incoming_ap_doc", "params" => params} -+ }) -+ end -+ end -+ -+ test "it does not retry duplicates" do -+ params = insert(:note_activity).data -+ -+ assert {:cancel, :already_present} = -+ ReceiverWorker.perform(%Oban.Job{ -+ args: %{"op" => "incoming_ap_doc", "params" => params} -+ }) -+ end - end diff --git a/patches/1(fix_searches_p1).patch b/patches/1(fix_searches_p1).patch new file mode 100755 index 0000000..b40025c --- /dev/null +++ b/patches/1(fix_searches_p1).patch @@ -0,0 +1,27 @@ +From 08c8abc053d2b1b36f4cc21402a8df254a6c7795 Mon Sep 17 00:00:00 2001 +From: Mint <> +Date: Wed, 31 May 2023 18:04:58 +0300 +Subject: [PATCH] Enable redirect middleware for Hackney + +--- + lib/pleroma/http.ex | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex +index d41061538d..a0e7d80f83 100644 +--- a/lib/pleroma/http.ex ++++ b/lib/pleroma/http.ex +@@ -106,6 +106,10 @@ defp adapter_middlewares(Tesla.Adapter.Gun) do + [Tesla.Middleware.FollowRedirects, Pleroma.Tesla.Middleware.ConnectionPool] + end + ++ defp adapter_middlewares(Tesla.Adapter.Hackney) do ++ [Tesla.Middleware.FollowRedirects] ++ end ++ + defp adapter_middlewares(_) do + if Pleroma.Config.get(:env) == :test do + # Emulate redirects in test env, which are handled by adapters in other environments +-- +GitLab + diff --git a/patches/2(fix_searches_p1).patch b/patches/2(fix_searches_p1).patch deleted file mode 100755 index b40025c..0000000 --- a/patches/2(fix_searches_p1).patch +++ /dev/null @@ -1,27 +0,0 @@ -From 08c8abc053d2b1b36f4cc21402a8df254a6c7795 Mon Sep 17 00:00:00 2001 -From: Mint <> -Date: Wed, 31 May 2023 18:04:58 +0300 -Subject: [PATCH] Enable redirect middleware for Hackney - ---- - lib/pleroma/http.ex | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex -index d41061538d..a0e7d80f83 100644 ---- a/lib/pleroma/http.ex -+++ b/lib/pleroma/http.ex -@@ -106,6 +106,10 @@ defp adapter_middlewares(Tesla.Adapter.Gun) do - [Tesla.Middleware.FollowRedirects, Pleroma.Tesla.Middleware.ConnectionPool] - end - -+ defp adapter_middlewares(Tesla.Adapter.Hackney) do -+ [Tesla.Middleware.FollowRedirects] -+ end -+ - defp adapter_middlewares(_) do - if Pleroma.Config.get(:env) == :test do - # Emulate redirects in test env, which are handled by adapters in other environments --- -GitLab - diff --git a/patches/2(fix_searches_p2).patch b/patches/2(fix_searches_p2).patch new file mode 100755 index 0000000..dcc6490 --- /dev/null +++ b/patches/2(fix_searches_p2).patch @@ -0,0 +1,57 @@ +From ed31bad2c481633520cc593912586b403c1ac6d4 Mon Sep 17 00:00:00 2001 +From: Mint <> +Date: Wed, 31 May 2023 19:50:20 +0300 +Subject: [PATCH] In-house redirect handler for mediaproxy with Hackney adapter + +--- + lib/pleroma/reverse_proxy/client/hackney.ex | 32 ++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/lib/pleroma/reverse_proxy/client/hackney.ex b/lib/pleroma/reverse_proxy/client/hackney.ex +index d3e9869121..ca4a0c29f0 100644 +--- a/lib/pleroma/reverse_proxy/client/hackney.ex ++++ b/lib/pleroma/reverse_proxy/client/hackney.ex +@@ -5,9 +5,39 @@ + defmodule Pleroma.ReverseProxy.Client.Hackney do + @behaviour Pleroma.ReverseProxy.Client + ++ # redirect handler from Pleb, slightly modified to work with Hackney ++ # https://declin.eu/objects/d4f38e62-5429-4614-86d1-e8fc16e6bf33 ++ # seven years without upstream fix! ++ # https://github.com/benoitc/hackney/issues/273 ++ @redirect_statuses [301, 302, 303, 307, 308] ++ defp get_location(headers) do ++ location = ++ Enum.find(headers, fn {header, _location} -> ++ String.downcase(header) == "location" ++ end) ++ ++ elem(location, 1) ++ end ++ + @impl true + def request(method, url, headers, body, opts \\ []) do +- :hackney.request(method, url, headers, body, opts) ++ if opts[:follow_redirect] != false do ++ {_state, req_opts} = Access.get_and_update(opts, :follow_redirect, fn a -> {a, false} end) ++ res = :hackney.request(method, url, headers, body, req_opts) ++ ++ case res do ++ {:ok, code, reply_headers, _client} when code in @redirect_statuses -> ++ :hackney.request(method, get_location(reply_headers), headers, body, req_opts) ++ ++ {:ok, code, reply_headers} when code in @redirect_statuses -> ++ :hackney.request(method, get_location(reply_headers), headers, body, req_opts) ++ ++ _ -> ++ res ++ end ++ else ++ :hackney.request(method, url, headers, body, opts) ++ end + end + + @impl true +-- +GitLab + diff --git a/patches/3(fix_searches_p2).patch b/patches/3(fix_searches_p2).patch deleted file mode 100755 index dcc6490..0000000 --- a/patches/3(fix_searches_p2).patch +++ /dev/null @@ -1,57 +0,0 @@ -From ed31bad2c481633520cc593912586b403c1ac6d4 Mon Sep 17 00:00:00 2001 -From: Mint <> -Date: Wed, 31 May 2023 19:50:20 +0300 -Subject: [PATCH] In-house redirect handler for mediaproxy with Hackney adapter - ---- - lib/pleroma/reverse_proxy/client/hackney.ex | 32 ++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/lib/pleroma/reverse_proxy/client/hackney.ex b/lib/pleroma/reverse_proxy/client/hackney.ex -index d3e9869121..ca4a0c29f0 100644 ---- a/lib/pleroma/reverse_proxy/client/hackney.ex -+++ b/lib/pleroma/reverse_proxy/client/hackney.ex -@@ -5,9 +5,39 @@ - defmodule Pleroma.ReverseProxy.Client.Hackney do - @behaviour Pleroma.ReverseProxy.Client - -+ # redirect handler from Pleb, slightly modified to work with Hackney -+ # https://declin.eu/objects/d4f38e62-5429-4614-86d1-e8fc16e6bf33 -+ # seven years without upstream fix! -+ # https://github.com/benoitc/hackney/issues/273 -+ @redirect_statuses [301, 302, 303, 307, 308] -+ defp get_location(headers) do -+ location = -+ Enum.find(headers, fn {header, _location} -> -+ String.downcase(header) == "location" -+ end) -+ -+ elem(location, 1) -+ end -+ - @impl true - def request(method, url, headers, body, opts \\ []) do -- :hackney.request(method, url, headers, body, opts) -+ if opts[:follow_redirect] != false do -+ {_state, req_opts} = Access.get_and_update(opts, :follow_redirect, fn a -> {a, false} end) -+ res = :hackney.request(method, url, headers, body, req_opts) -+ -+ case res do -+ {:ok, code, reply_headers, _client} when code in @redirect_statuses -> -+ :hackney.request(method, get_location(reply_headers), headers, body, req_opts) -+ -+ {:ok, code, reply_headers} when code in @redirect_statuses -> -+ :hackney.request(method, get_location(reply_headers), headers, body, req_opts) -+ -+ _ -> -+ res -+ end -+ else -+ :hackney.request(method, url, headers, body, opts) -+ end - end - - @impl true --- -GitLab - diff --git a/patches/3(fix_searches_p3).patch b/patches/3(fix_searches_p3).patch new file mode 100755 index 0000000..0a2af01 --- /dev/null +++ b/patches/3(fix_searches_p3).patch @@ -0,0 +1,43 @@ +From 8e8b3be31345ce18150b38ebbe84a3fc23f13e0e Mon Sep 17 00:00:00 2001 +From: Mint <> +Date: Wed, 31 May 2023 20:17:33 +0300 +Subject: [PATCH] Use Tesla's middleware for redirect handling on Hackney + +--- + lib/pleroma/http.ex | 6 +++++- + lib/pleroma/http/adapter_helper/hackney.ex | 2 -- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex +index a0e7d80f83..6c430fc2d0 100644 +--- a/lib/pleroma/http.ex ++++ b/lib/pleroma/http.ex +@@ -107,7 +107,11 @@ defp adapter_middlewares(Tesla.Adapter.Gun) do + end + + defp adapter_middlewares(Tesla.Adapter.Hackney) do +- [Tesla.Middleware.FollowRedirects] ++ if Pleroma.Config.get([:http, :adapter, :follow_redirect]) != false do ++ [Tesla.Middleware.FollowRedirects] ++ else ++ [] ++ end + end + + defp adapter_middlewares(_) do +diff --git a/lib/pleroma/http/adapter_helper/hackney.ex b/lib/pleroma/http/adapter_helper/hackney.ex +index f3be1f3d0f..15a84cf736 100644 +--- a/lib/pleroma/http/adapter_helper/hackney.ex ++++ b/lib/pleroma/http/adapter_helper/hackney.ex +@@ -6,8 +6,6 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do + @behaviour Pleroma.HTTP.AdapterHelper + + @defaults [ +- follow_redirect: true, +- force_redirect: true + ] + + @spec options(keyword(), URI.t()) :: keyword() +-- +GitLab + diff --git a/patches/4(fix_searches_p3).patch b/patches/4(fix_searches_p3).patch deleted file mode 100755 index 0a2af01..0000000 --- a/patches/4(fix_searches_p3).patch +++ /dev/null @@ -1,43 +0,0 @@ -From 8e8b3be31345ce18150b38ebbe84a3fc23f13e0e Mon Sep 17 00:00:00 2001 -From: Mint <> -Date: Wed, 31 May 2023 20:17:33 +0300 -Subject: [PATCH] Use Tesla's middleware for redirect handling on Hackney - ---- - lib/pleroma/http.ex | 6 +++++- - lib/pleroma/http/adapter_helper/hackney.ex | 2 -- - 2 files changed, 5 insertions(+), 3 deletions(-) - -diff --git a/lib/pleroma/http.ex b/lib/pleroma/http.ex -index a0e7d80f83..6c430fc2d0 100644 ---- a/lib/pleroma/http.ex -+++ b/lib/pleroma/http.ex -@@ -107,7 +107,11 @@ defp adapter_middlewares(Tesla.Adapter.Gun) do - end - - defp adapter_middlewares(Tesla.Adapter.Hackney) do -- [Tesla.Middleware.FollowRedirects] -+ if Pleroma.Config.get([:http, :adapter, :follow_redirect]) != false do -+ [Tesla.Middleware.FollowRedirects] -+ else -+ [] -+ end - end - - defp adapter_middlewares(_) do -diff --git a/lib/pleroma/http/adapter_helper/hackney.ex b/lib/pleroma/http/adapter_helper/hackney.ex -index f3be1f3d0f..15a84cf736 100644 ---- a/lib/pleroma/http/adapter_helper/hackney.ex -+++ b/lib/pleroma/http/adapter_helper/hackney.ex -@@ -6,8 +6,6 @@ defmodule Pleroma.HTTP.AdapterHelper.Hackney do - @behaviour Pleroma.HTTP.AdapterHelper - - @defaults [ -- follow_redirect: true, -- force_redirect: true - ] - - @spec options(keyword(), URI.t()) :: keyword() --- -GitLab - diff --git a/patches/4i2psearch.diff b/patches/4i2psearch.diff new file mode 100644 index 0000000..dd0086c --- /dev/null +++ b/patches/4i2psearch.diff @@ -0,0 +1,28 @@ +diff --git a/mix.exs b/mix.exs +index 00c8f7b0da6cd992036dd5cf35daf4f9619d8f14..8dd7a8cc5a43ef6d4869353e890cad39bac0f5c4 100644 +--- a/mix.exs ++++ b/mix.exs +@@ -161,7 +161,9 @@ defp deps do + {:floki, "~> 0.27"}, + {:timex, "~> 3.6"}, + {:ueberauth, "~> 0.4"}, +- {:linkify, "~> 0.5.2"}, ++ {:linkify, ++ git: "https://gitgud.io/mintplg/linkify.git", ++ branch: "domain-mention-parsing-fix"}, + {:http_signatures, "~> 0.1.1"}, + {:telemetry, "~> 0.3"}, + {:poolboy, "~> 1.5"}, +diff --git a/mix.lock b/mix.lock +index 4cb6fc7da9702b595845d1e5f619d53fb98a378e..a965208c3226d0e91c15d911d0774e5629878041 100644 +--- a/mix.lock ++++ b/mix.lock +@@ -69,7 +69,7 @@ + "jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"}, + "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, + "libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"}, +- "linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"}, ++ "linkify": {:git, "https://gitgud.io/mintplg/linkify.git", "a3954f1db2983f2b7e79d04b84d5f6fecbf6fe71", [branch: "domain-mention-parsing-fix"]}, + "majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"}, + "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, diff --git a/patches/5(search_i2p).diff b/patches/5(search_i2p).diff deleted file mode 100755 index 4e7d77b..0000000 --- a/patches/5(search_i2p).diff +++ /dev/null @@ -1 +0,0 @@ -Linkify in mix.exs and mix.lock is changed diff --git a/patches/5spoof.diff b/patches/5spoof.diff new file mode 100644 index 0000000..718bfc4 --- /dev/null +++ b/patches/5spoof.diff @@ -0,0 +1,67 @@ +diff --git a/config/config.exs b/config/config.exs +index 5d2e3b5ea1a3821629bc3025c1992c3cc21ff2f5..643e77c176e8dec2c304403a4240df8d77c19999 100644 +--- a/config/config.exs ++++ b/config/config.exs +@@ -362,7 +362,13 @@ + follow_handshake_timeout: 500, + note_replies_output_limit: 5, + sign_object_fetches: true, +- authorized_fetch_mode: false ++ authorized_fetch_mode: false, ++ spoof_object_fetch_signatures: false, ++ spoofed_key: "-----BEGIN RSA PRIVATE KEY----- ++overwrite this with your internal.fetch key rippen from donor instance DB ++yes, just like that, newlines are important ++-----END RSA PRIVATE KEY-----", ++ spoofed_instance: "https://funnydomain.example" + + config :pleroma, :streamer, + workers: 3, +diff --git a/lib/pleroma/object/fetcher.ex b/lib/pleroma/object/fetcher.ex +index deb3dc711598fb94dcee37a04bd1e55317fa5b88..6bc8d8ed71dd3e8a373eaf1420227c9c072bba5c 100644 +--- a/lib/pleroma/object/fetcher.ex ++++ b/lib/pleroma/object/fetcher.ex +@@ -3,7 +3,10 @@ + # SPDX-License-Identifier: AGPL-3.0-only + + defmodule Pleroma.Object.Fetcher do ++ @behaviour HTTPSignatures.Adapter ++ + alias Pleroma.HTTP ++ alias Pleroma.Keys + alias Pleroma.Maps + alias Pleroma.Object + alias Pleroma.Object.Containment +@@ -161,13 +164,31 @@ def fetch_object_from_id!(id, options \\ []) do + defp make_signature(id, date) do + uri = URI.parse(id) + +- signature = ++ spoofed_pem = Pleroma.Config.get([:activitypub, :spoofed_key]) ++ # workaround for syntax shite disallowing me from defining signature in "if" block ++ spoofed_key = if Pleroma.Config.get([:activitypub, :spoof_object_fetch_signatures]) do ++ with {:ok, private_key, _} <- Keys.keys_from_pem(spoofed_pem) do ++ private_key ++ end ++ else ++ "" ++ end ++ spoofed_instance = Pleroma.Config.get([:activitypub, :spoofed_instance]) ++ ++ signature = if Pleroma.Config.get([:activitypub, :spoof_object_fetch_signatures]) do ++ HTTPSignatures.sign(spoofed_key, spoofed_instance <> "/internal/fetch#main-key", %{ ++ "(request-target)": "get #{uri.path}", ++ host: uri.host, ++ date: date ++ }) ++ else + InternalFetchActor.get_actor() + |> Signature.sign(%{ + "(request-target)": "get #{uri.path}", + host: uri.host, + date: date + }) ++ end + + {"signature", signature} + end diff --git a/patches/6(2.5.3).diff b/patches/6(2.5.3).diff deleted file mode 100755 index f89cb31..0000000 --- a/patches/6(2.5.3).diff +++ /dev/null @@ -1,261 +0,0 @@ -diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml -index 8b0381d1101a269a5921ee3d78920fa66420018b..91e568a3201d71921b93a9d4d6da9c01224bedea 100644 ---- a/.gitlab-ci.yml -+++ b/.gitlab-ci.yml -@@ -32,7 +32,13 @@ before_script: - after_script: - - rm -rf _build/*/lib/pleroma - -+.using-ci-base: -+ tags: -+ - amd64 -+ - build: -+ extends: -+ - .using-ci-base - stage: build - only: - changes: &build_changes_policy -@@ -44,6 +50,8 @@ build: - - mix compile --force - - spec-build: -+ extends: -+ - .using-ci-base - stage: test - only: - changes: -@@ -57,6 +65,8 @@ spec-build: - - mix pleroma.openapi_spec spec.json - - benchmark: -+ extends: -+ - .using-ci-base - stage: benchmark - when: manual - variables: -@@ -71,6 +81,8 @@ benchmark: - - mix pleroma.load_testing - - unit-testing: -+ extends: -+ - .using-ci-base - stage: test - only: - changes: *build_changes_policy -@@ -94,6 +106,8 @@ unit-testing: - path: coverage.xml - - unit-testing-erratic: -+ extends: -+ - .using-ci-base - stage: test - retry: 2 - allow_failure: true -@@ -129,6 +143,8 @@ unit-testing-erratic: - # - mix test --trace --only federated - - unit-testing-rum: -+ extends: -+ - .using-ci-base - stage: test - only: - changes: *build_changes_policy -@@ -162,6 +178,8 @@ lint: - - mix format --check-formatted - - analysis: -+ extends: -+ - .using-ci-base - stage: test - only: - changes: *build_changes_policy -diff --git a/CHANGELOG.md b/CHANGELOG.md -index f6fc6aaee23c312a43f67b5210688b28e1060554..468ec101293b462c8eddaddf375d0de9e8d68fcd 100644 ---- a/CHANGELOG.md -+++ b/CHANGELOG.md -@@ -14,6 +14,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - ### Removed - -+## 2.5.3 -+ -+### Security -+- Emoji pack loader sanitizes pack names -+- Reduced permissions of config files and directories, distros requiring greater permissions like group-read need to pre-create the directories -+ - ## 2.5.2 - - ### Security -diff --git a/changelog.d/emoji-pack-sanitization.security b/changelog.d/emoji-pack-sanitization.security -new file mode 100644 -index 0000000000000000000000000000000000000000..f3218abd4d78e57813b9259a62a73f73b32499a2 ---- /dev/null -+++ b/changelog.d/emoji-pack-sanitization.security -@@ -0,0 +1 @@ -+Emoji pack loader sanitizes pack names -diff --git a/changelog.d/otp_perms.security b/changelog.d/otp_perms.security -new file mode 100644 -index 0000000000000000000000000000000000000000..a3da1c677b6c58beb60613a90615a6fa04c42955 ---- /dev/null -+++ b/changelog.d/otp_perms.security -@@ -0,0 +1 @@ -+- Reduced permissions of config files and directories, distros requiring greater permissions like group-read need to pre-create the directories -\ No newline at end of file -diff --git a/lib/mix/tasks/pleroma/instance.ex b/lib/mix/tasks/pleroma/instance.ex -index 5c93f19ff5aa45c4908c33bb34963f53b5dfa79f..5d8b254a223e8d7b3fd8b07691dd8f9cbcc072e2 100644 ---- a/lib/mix/tasks/pleroma/instance.ex -+++ b/lib/mix/tasks/pleroma/instance.ex -@@ -266,12 +266,20 @@ def run(["gen" | rest]) do - config_dir = Path.dirname(config_path) - psql_dir = Path.dirname(psql_path) - -+ # Note: Distros requiring group read (0o750) on those directories should -+ # pre-create the directories. - [config_dir, psql_dir, static_dir, uploads_dir] - |> Enum.reject(&File.exists?/1) -- |> Enum.map(&File.mkdir_p!/1) -+ |> Enum.each(fn dir -> -+ File.mkdir_p!(dir) -+ File.chmod!(dir, 0o700) -+ end) - - shell_info("Writing config to #{config_path}.") - -+ # Sadly no fchmod(2) equivalent in Elixir… -+ File.touch!(config_path) -+ File.chmod!(config_path, 0o640) - File.write(config_path, result_config) - shell_info("Writing the postgres script to #{psql_path}.") - File.write(psql_path, result_psql) -@@ -290,8 +298,7 @@ def run(["gen" | rest]) do - else - shell_error( - "The task would have overwritten the following files:\n" <> -- (Enum.map(will_overwrite, &"- #{&1}\n") |> Enum.join("")) <> -- "Rerun with `--force` to overwrite them." -+ Enum.map_join(will_overwrite, &"- #{&1}\n") <> "Rerun with `--force` to overwrite them." - ) - end - end -diff --git a/lib/pleroma/config/release_runtime_provider.ex b/lib/pleroma/config/release_runtime_provider.ex -index 91e5f1a540e2d034357262c3e68b67c681f95ef0..9ec0f975e8c9b9b6f1e827700f7e13d40bca8e72 100644 ---- a/lib/pleroma/config/release_runtime_provider.ex -+++ b/lib/pleroma/config/release_runtime_provider.ex -@@ -20,6 +20,20 @@ def load(config, opts) do - - with_runtime_config = - if File.exists?(config_path) do -+ # -+ %File.Stat{mode: mode} = File.lstat!(config_path) -+ -+ if Bitwise.band(mode, 0o007) > 0 do -+ raise "Configuration at #{config_path} has world-permissions, execute the following: chmod o= #{config_path}" -+ end -+ -+ if Bitwise.band(mode, 0o020) > 0 do -+ raise "Configuration at #{config_path} has group-wise write permissions, execute the following: chmod g-w #{config_path}" -+ end -+ -+ # Note: Elixir doesn't provides a getuid(2) -+ # so cannot forbid group-read only when config is owned by us -+ - runtime_config = Config.Reader.read!(config_path) - - with_defaults -diff --git a/lib/pleroma/emoji/pack.ex b/lib/pleroma/emoji/pack.ex -index a361ea2009ae187df70c39889b145e7ed7f36dab..6e58f88981299916b913274173d3d5da11a97be5 100644 ---- a/lib/pleroma/emoji/pack.ex -+++ b/lib/pleroma/emoji/pack.ex -@@ -285,6 +285,7 @@ def update_metadata(name, data) do - - @spec load_pack(String.t()) :: {:ok, t()} | {:error, :file.posix()} - def load_pack(name) do -+ name = Path.basename(name) - pack_file = Path.join([emoji_path(), name, "pack.json"]) - - with {:ok, _} <- File.stat(pack_file), -diff --git a/mix.exs b/mix.exs -index 79fd9c9efebee61253cb417aed03fc95b52bf7be..d1cdb151dd25545b31f777e8c3b57e42db673357 100644 ---- a/mix.exs -+++ b/mix.exs -@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do - def project do - [ - app: :pleroma, -- version: version("2.5.2"), -+ version: version("2.5.3"), - elixir: "~> 1.11", - elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix, :gettext] ++ Mix.compilers(), -diff --git a/test/pleroma/config/release_runtime_provider_test.exs b/test/pleroma/config/release_runtime_provider_test.exs -index 4e0d4c838a661c307be24034d43cd65627c81de3..8ff578e6352684fc99dccf073f808f5a006ae636 100644 ---- a/test/pleroma/config/release_runtime_provider_test.exs -+++ b/test/pleroma/config/release_runtime_provider_test.exs -@@ -17,6 +17,8 @@ test "loads release defaults config and warns about non-existent runtime config" - end - - test "merged runtime config" do -+ assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640) -+ - merged = - ReleaseRuntimeProvider.load([], config_path: "test/fixtures/config/temp.secret.exs") - -@@ -25,6 +27,8 @@ test "merged runtime config" do - end - - test "merged exported config" do -+ assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640) -+ - ExUnit.CaptureIO.capture_io(fn -> - merged = - ReleaseRuntimeProvider.load([], -@@ -37,6 +41,9 @@ test "merged exported config" do - end - - test "runtime config is merged with exported config" do -+ assert :ok == File.chmod!("test/fixtures/config/temp.secret.exs", 0o640) -+ assert :ok == File.chmod!("test/fixtures/config/temp.exported_from_db.secret.exs", 0o640) -+ - merged = - ReleaseRuntimeProvider.load([], - config_path: "test/fixtures/config/temp.secret.exs", -diff --git a/test/pleroma/emoji/pack_test.exs b/test/pleroma/emoji/pack_test.exs -index 18b99da75b3f68352f9c8915711cff7a9b4407f8..00001abfcdb32793ad9f637ebe83689b22e76f2c 100644 ---- a/test/pleroma/emoji/pack_test.exs -+++ b/test/pleroma/emoji/pack_test.exs -@@ -90,4 +90,8 @@ test "add emoji file", %{pack: pack} do - - assert updated_pack.files_count == 1 - end -+ -+ test "load_pack/1 ignores path traversal in a forged pack name", %{pack: pack} do -+ assert {:ok, ^pack} = Pack.load_pack("../../../../../dump_pack") -+ end - end -diff --git a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs -index 9d99df27c8e891d9ca8d1bd48fd938cb2c7e64fe..83bf59c6f3425944d3eb070ac1086b44fc59416d 100644 ---- a/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs -+++ b/test/pleroma/web/activity_pub/transmogrifier/emoji_react_handling_test.exs -@@ -65,7 +65,7 @@ test "it works for incoming unqualified emoji reactions" do - object = Object.get_by_ap_id(data["object"]) - - assert object.data["reaction_count"] == 1 -- assert match?([[emoji, _]], object.data["reactions"]) -+ assert match?([[^emoji, _]], object.data["reactions"]) - end - - test "it reject invalid emoji reactions" do -diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs -index 57fa0f0476d70f4e5069ab6526a0546085dc6fc8..40f79d10302a2912c7284d14fb55500dc0f32654 100644 ---- a/test/pleroma/web/mastodon_api/update_credentials_test.exs -+++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs -@@ -375,7 +375,7 @@ test "updates the user's background, upload_limit, returns a HTTP 413", %{ - "pleroma_background_image" => new_background_oversized - }) - -- assert user_response = json_response_and_validate_schema(res, 413) -+ assert _user_response = json_response_and_validate_schema(res, 413) - assert user.background == %{} - - clear_config([:instance, :upload_limit], upload_limit) diff --git a/patches/7(2.5.4).diff b/patches/7(2.5.4).diff deleted file mode 100755 index d630ee3..0000000 --- a/patches/7(2.5.4).diff +++ /dev/null @@ -1,110 +0,0 @@ -diff --git a/CHANGELOG.md b/CHANGELOG.md -index 468ec101293b462c8eddaddf375d0de9e8d68fcd..9d9aadc6e8a0162d8944622f783a6301fefd6cfa 100644 ---- a/CHANGELOG.md -+++ b/CHANGELOG.md -@@ -14,6 +14,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - ### Removed - -+## 2.5.54 -+ -+## Security -+- Fix XML External Entity (XXE) loading vulnerability allowing to fetch arbitary files from the server's filesystem -+ - ## 2.5.3 - - ### Security -diff --git a/changelog.d/akkoma-xml-remote-entities.security b/changelog.d/akkoma-xml-remote-entities.security -new file mode 100644 -index 0000000000000000000000000000000000000000..5e6725e5bb5ad6a7140beb8245676a1fa0408086 ---- /dev/null -+++ b/changelog.d/akkoma-xml-remote-entities.security -@@ -0,0 +1 @@ -+Fix XML External Entity (XXE) loading vulnerability allowing to fetch arbitary files from the server's filesystem -diff --git a/lib/pleroma/web/xml.ex b/lib/pleroma/web/xml.ex -index b699446b007b07ec9e7e5f057ba6532d405a77cd..380a80ab83afe367b08a9770cac110440c6f4ccf 100644 ---- a/lib/pleroma/web/xml.ex -+++ b/lib/pleroma/web/xml.ex -@@ -29,7 +29,10 @@ def parse_document(text) do - {doc, _rest} = - text - |> :binary.bin_to_list() -- |> :xmerl_scan.string(quiet: true) -+ |> :xmerl_scan.string( -+ quiet: true, -+ fetch_fun: fn _, _ -> raise "Resolving external entities not supported" end -+ ) - - {:ok, doc} - rescue -diff --git a/mix.exs b/mix.exs -index d1cdb151dd25545b31f777e8c3b57e42db673357..12f721364dd75744651e5044936d195684d8cf08 100644 ---- a/mix.exs -+++ b/mix.exs -@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do - def project do - [ - app: :pleroma, -- version: version("2.5.3"), -+ version: version("2.5.4"), - elixir: "~> 1.11", - elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix, :gettext] ++ Mix.compilers(), -diff --git a/test/fixtures/xml_external_entities.xml b/test/fixtures/xml_external_entities.xml -new file mode 100644 -index 0000000000000000000000000000000000000000..d5ff87134734bd072f57e41ff7662638c0cc22c8 ---- /dev/null -+++ b/test/fixtures/xml_external_entities.xml -@@ -0,0 +1,3 @@ -+ -+ ]> -+&xxe; -diff --git a/test/pleroma/web/web_finger_test.exs b/test/pleroma/web/web_finger_test.exs -index fafef54fe7040df234ee0931787a024481f6f053..be5e08776becca8ade9710f76f41a7678a2fb7c8 100644 ---- a/test/pleroma/web/web_finger_test.exs -+++ b/test/pleroma/web/web_finger_test.exs -@@ -180,5 +180,28 @@ test "respects xml content-type" do - - {:ok, _data} = WebFinger.finger("pekorino@pawoo.net") - end -+ -+ test "refuses to process XML remote entities" do -+ Tesla.Mock.mock(fn -+ %{ -+ url: "https://pawoo.net/.well-known/webfinger?resource=acct:pekorino@pawoo.net" -+ } -> -+ {:ok, -+ %Tesla.Env{ -+ status: 200, -+ body: File.read!("test/fixtures/xml_external_entities.xml"), -+ headers: [{"content-type", "application/xrd+xml"}] -+ }} -+ -+ %{url: "https://pawoo.net/.well-known/host-meta"} -> -+ {:ok, -+ %Tesla.Env{ -+ status: 200, -+ body: File.read!("test/fixtures/tesla_mock/pawoo.net_host_meta") -+ }} -+ end) -+ -+ assert :error = WebFinger.finger("pekorino@pawoo.net") -+ end - end - end -diff --git a/test/pleroma/web/xml_test.exs b/test/pleroma/web/xml_test.exs -new file mode 100644 -index 0000000000000000000000000000000000000000..89d4709b6e7938cbc5c7d604ac2c479707d6ab5c ---- /dev/null -+++ b/test/pleroma/web/xml_test.exs -@@ -0,0 +1,10 @@ -+defmodule Pleroma.Web.XMLTest do -+ use Pleroma.DataCase, async: true -+ -+ alias Pleroma.Web.XML -+ -+ test "refuses to load external entities from XML" do -+ data = File.read!("test/fixtures/xml_external_entities.xml") -+ assert(:error == XML.parse_document(data)) -+ end -+end diff --git a/patches/8(2.5.5).diff b/patches/8(2.5.5).diff deleted file mode 100644 index fef991f..0000000 --- a/patches/8(2.5.5).diff +++ /dev/null @@ -1,293 +0,0 @@ -diff --git a/CHANGELOG.md b/CHANGELOG.md -index 9d9aadc6e8a0162d8944622f783a6301fefd6cfa..32ec440de55b707d01be37e21f1517542c9cf7d9 100644 ---- a/CHANGELOG.md -+++ b/CHANGELOG.md -@@ -14,7 +14,12 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - - ### Removed - --## 2.5.54 -+## 2.5.5 -+ -+## Security -+- Prevent users from accessing media of other users by creating a status with reused attachment ID -+ -+## 2.5.4 - - ## Security - - Fix XML External Entity (XXE) loading vulnerability allowing to fetch arbitary files from the server's filesystem -diff --git a/changelog.d/check-attachment-attribution.security b/changelog.d/check-attachment-attribution.security -new file mode 100644 -index 0000000000000000000000000000000000000000..e0e46525b38d15e58423debbf9d799e85276d0ca ---- /dev/null -+++ b/changelog.d/check-attachment-attribution.security -@@ -0,0 +1 @@ -+CommonAPI: Prevent users from accessing media of other users by creating a status with reused attachment ID -diff --git a/lib/pleroma/scheduled_activity.ex b/lib/pleroma/scheduled_activity.ex -index a7be585123d4be67e7513626b07c2e33c8b18388..0ed51ad07d43c0cc434e532852ce6a7ec1089d10 100644 ---- a/lib/pleroma/scheduled_activity.ex -+++ b/lib/pleroma/scheduled_activity.ex -@@ -40,7 +40,11 @@ defp with_media_attachments( - %{changes: %{params: %{"media_ids" => media_ids} = params}} = changeset - ) - when is_list(media_ids) do -- media_attachments = Utils.attachments_from_ids(%{media_ids: media_ids}) -+ media_attachments = -+ Utils.attachments_from_ids( -+ %{media_ids: media_ids}, -+ User.get_cached_by_id(changeset.data.user_id) -+ ) - - params = - params -diff --git a/lib/pleroma/web/common_api.ex b/lib/pleroma/web/common_api.ex -index 89cc0d6fe82acfd418e8e5928bc4b44d72b17f79..44eb00075ee694005241c1eabfbb846e4668d665 100644 ---- a/lib/pleroma/web/common_api.ex -+++ b/lib/pleroma/web/common_api.ex -@@ -33,6 +33,7 @@ def block(blocker, blocked) do - - def post_chat_message(%User{} = user, %User{} = recipient, content, opts \\ []) do - with maybe_attachment <- opts[:media_id] && Object.get_by_id(opts[:media_id]), -+ :ok <- validate_chat_attachment_attribution(maybe_attachment, user), - :ok <- validate_chat_content_length(content, !!maybe_attachment), - {_, {:ok, chat_message_data, _meta}} <- - {:build_object, -@@ -71,6 +72,17 @@ defp format_chat_content(content) do - text - end - -+ defp validate_chat_attachment_attribution(nil, _), do: :ok -+ -+ defp validate_chat_attachment_attribution(attachment, user) do -+ with :ok <- Object.authorize_access(attachment, user) do -+ :ok -+ else -+ e -> -+ e -+ end -+ end -+ - defp validate_chat_content_length(_, true), do: :ok - defp validate_chat_content_length(nil, false), do: {:error, :no_content} - -diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex -index 9af635da8abafb9d9a4c1b59c00cc63261955d48..63ed48a27bbd4a4f2fdfd97776acadcf0fa72c74 100644 ---- a/lib/pleroma/web/common_api/activity_draft.ex -+++ b/lib/pleroma/web/common_api/activity_draft.ex -@@ -111,7 +111,7 @@ defp full_payload(%{status: status, summary: summary} = draft) do - end - - defp attachments(%{params: params} = draft) do -- attachments = Utils.attachments_from_ids(params) -+ attachments = Utils.attachments_from_ids(params, draft.user) - draft = %__MODULE__{draft | attachments: attachments} - - case Utils.validate_attachments_count(attachments) do -diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex -index ff0814329583726d43ad52e6082662aee1212b45..6410815ea89153a65f20bacc24a5a5aed82a1aa0 100644 ---- a/lib/pleroma/web/common_api/utils.ex -+++ b/lib/pleroma/web/common_api/utils.ex -@@ -23,21 +23,21 @@ defmodule Pleroma.Web.CommonAPI.Utils do - require Logger - require Pleroma.Constants - -- def attachments_from_ids(%{media_ids: ids, descriptions: desc}) do -- attachments_from_ids_descs(ids, desc) -+ def attachments_from_ids(%{media_ids: ids, descriptions: desc}, user) do -+ attachments_from_ids_descs(ids, desc, user) - end - -- def attachments_from_ids(%{media_ids: ids}) do -- attachments_from_ids_no_descs(ids) -+ def attachments_from_ids(%{media_ids: ids}, user) do -+ attachments_from_ids_no_descs(ids, user) - end - -- def attachments_from_ids(_), do: [] -+ def attachments_from_ids(_, _), do: [] - -- def attachments_from_ids_no_descs([]), do: [] -+ def attachments_from_ids_no_descs([], _), do: [] - -- def attachments_from_ids_no_descs(ids) do -+ def attachments_from_ids_no_descs(ids, user) do - Enum.map(ids, fn media_id -> -- case get_attachment(media_id) do -+ case get_attachment(media_id, user) do - %Object{data: data} -> data - _ -> nil - end -@@ -45,21 +45,26 @@ def attachments_from_ids_no_descs(ids) do - |> Enum.reject(&is_nil/1) - end - -- def attachments_from_ids_descs([], _), do: [] -+ def attachments_from_ids_descs([], _, _), do: [] - -- def attachments_from_ids_descs(ids, descs_str) do -+ def attachments_from_ids_descs(ids, descs_str, user) do - {_, descs} = Jason.decode(descs_str) - - Enum.map(ids, fn media_id -> -- with %Object{data: data} <- get_attachment(media_id) do -+ with %Object{data: data} <- get_attachment(media_id, user) do - Map.put(data, "name", descs[media_id]) - end - end) - |> Enum.reject(&is_nil/1) - end - -- defp get_attachment(media_id) do -- Repo.get(Object, media_id) -+ defp get_attachment(media_id, user) do -+ with %Object{data: _data} = object <- Repo.get(Object, media_id), -+ :ok <- Object.authorize_access(object, user) do -+ object -+ else -+ _ -> nil -+ end - end - - @spec get_to_and_cc(ActivityDraft.t()) :: {list(String.t()), list(String.t())} -diff --git a/mix.exs b/mix.exs -index 12f721364dd75744651e5044936d195684d8cf08..e2aac0fc541f2820841a16feff06b058b18ed2ec 100644 ---- a/mix.exs -+++ b/mix.exs -@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do - def project do - [ - app: :pleroma, -- version: version("2.5.4"), -+ version: version("2.5.5"), - elixir: "~> 1.11", - elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix, :gettext] ++ Mix.compilers(), -diff --git a/test/pleroma/web/common_api/utils_test.exs b/test/pleroma/web/common_api/utils_test.exs -index d309c6deda789fd7818b29e95425b77413b06f7c..c52d3e9c557b6040bb457f40d9ebd02c31975a64 100644 ---- a/test/pleroma/web/common_api/utils_test.exs -+++ b/test/pleroma/web/common_api/utils_test.exs -@@ -586,41 +586,56 @@ test "returns recipients when object not found" do - end - end - -- describe "attachments_from_ids_descs/2" do -+ describe "attachments_from_ids_descs/3" do - test "returns [] when attachment ids is empty" do -- assert Utils.attachments_from_ids_descs([], "{}") == [] -+ assert Utils.attachments_from_ids_descs([], "{}", nil) == [] - end - - test "returns list attachments with desc" do -- object = insert(:note) -+ user = insert(:user) -+ object = insert(:note, %{user: user}) - desc = Jason.encode!(%{object.id => "test-desc"}) - -- assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc) == [ -+ assert Utils.attachments_from_ids_descs(["#{object.id}", "34"], desc, user) == [ - Map.merge(object.data, %{"name" => "test-desc"}) - ] - end - end - -- describe "attachments_from_ids/1" do -+ describe "attachments_from_ids/2" do - test "returns attachments with descs" do -- object = insert(:note) -+ user = insert(:user) -+ object = insert(:note, %{user: user}) - desc = Jason.encode!(%{object.id => "test-desc"}) - -- assert Utils.attachments_from_ids(%{ -- media_ids: ["#{object.id}"], -- descriptions: desc -- }) == [ -+ assert Utils.attachments_from_ids( -+ %{ -+ media_ids: ["#{object.id}"], -+ descriptions: desc -+ }, -+ user -+ ) == [ - Map.merge(object.data, %{"name" => "test-desc"}) - ] - end - - test "returns attachments without descs" do -- object = insert(:note) -- assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}) == [object.data] -+ user = insert(:user) -+ object = insert(:note, %{user: user}) -+ assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user) == [object.data] - end - - test "returns [] when not pass media_ids" do -- assert Utils.attachments_from_ids(%{}) == [] -+ assert Utils.attachments_from_ids(%{}, nil) == [] -+ end -+ -+ test "returns [] when media_ids not belong to current user" do -+ user = insert(:user) -+ user2 = insert(:user) -+ -+ object = insert(:attachment, %{user: user}) -+ -+ assert Utils.attachments_from_ids(%{media_ids: ["#{object.id}"]}, user2) == [] - end - end - -diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs -index 5c9103e9fc742b8082a432d8ac9ca2ce1929ec32..e60691995c51bdd829f0f67a3abbddc9fe919db9 100644 ---- a/test/pleroma/web/common_api_test.exs -+++ b/test/pleroma/web/common_api_test.exs -@@ -279,6 +279,24 @@ test "it reject messages via MRF" do - assert {:reject, "[KeywordPolicy] Matches with rejected keyword"} == - CommonAPI.post_chat_message(author, recipient, "GNO/Linux") - end -+ -+ test "it reject messages with attachments not belonging to user" do -+ author = insert(:user) -+ not_author = insert(:user) -+ recipient = author -+ -+ attachment = insert(:attachment, %{user: not_author}) -+ -+ {:error, message} = -+ CommonAPI.post_chat_message( -+ author, -+ recipient, -+ "123", -+ media_id: attachment.id -+ ) -+ -+ assert message == :forbidden -+ end - end - - describe "unblocking" do -diff --git a/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs b/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs -index e5e510d33b88244b9b088ed93b98bfb2c411dd8b..07a65a3bc1bd09ece6afa2557a719b7550dfae2a 100644 ---- a/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs -+++ b/test/pleroma/web/mastodon_api/views/scheduled_activity_view_test.exs -@@ -48,7 +48,7 @@ test "A scheduled activity with a media attachment" do - id: to_string(scheduled_activity.id), - media_attachments: - %{media_ids: [upload.id]} -- |> Utils.attachments_from_ids() -+ |> Utils.attachments_from_ids(user) - |> Enum.map(&StatusView.render("attachment.json", %{attachment: &1})), - params: %{ - in_reply_to_id: to_string(activity.id), -diff --git a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs -index 017c9c5c0d2fdf4686d920ea7f05084a6ddf44d7..7ab3f5acdc7971f9ac324db07be30dbff60d680a 100644 ---- a/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs -+++ b/test/pleroma/web/pleroma_api/views/chat_message_reference_view_test.exs -@@ -24,7 +24,7 @@ test "it displays a chat message" do - filename: "an_image.jpg" - } - -- {:ok, upload} = ActivityPub.upload(file, actor: user.ap_id) -+ {:ok, upload} = ActivityPub.upload(file, actor: recipient.ap_id) - - {:ok, activity} = - CommonAPI.post_chat_message(user, recipient, "kippis :firefox:", idempotency_key: "123") diff --git a/patches/9(2.6.0).diff b/patches/9(2.6.0).diff deleted file mode 100644 index 1df8895..0000000 --- a/patches/9(2.6.0).diff +++ /dev/null @@ -1,392 +0,0 @@ -diff --git a/mix.exs b/mix.exs -index b071e7c7b4778d16c2b503b3ed5ddfee777111f3..3c1ce1f7ede8eda14733e99ff7a97bbd39d3f988 100644 ---- a/mix.exs -+++ b/mix.exs -@@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do - def project do - [ - app: :pleroma, -- version: version("2.5.5"), -+ version: version("2.6.0"), - elixir: "~> 1.11", - elixirc_paths: elixirc_paths(Mix.env()), - compilers: [:phoenix] ++ Mix.compilers(), -diff --git a/priv/static/index.html b/priv/static/index.html -index 7dd5d0b783b78bd33399aa4c139451098bbf3d29..52ff685c002c5b4aae07a8f53e74e703a6f65589 100644 ---- a/priv/static/index.html -+++ b/priv/static/index.html -@@ -1 +1 @@ --
-\ No newline at end of file -+
-\ No newline at end of file -diff --git a/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css b/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css -deleted file mode 100644 -index b14e141435c66818830a5f2eb95c152e18c260ab..0000000000000000000000000000000000000000 -Binary files a/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css and /dev/null differ -diff --git a/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css.map b/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css.map -deleted file mode 100644 -index 72f22de670d5a08ffa301e696a6befdc4897d8c6..0000000000000000000000000000000000000000 ---- a/priv/static/static/css/5948.06d2a0d84620cba6a4fb.css.map -+++ /dev/null -@@ -1 +0,0 @@ --{"version":3,"file":"static/css/5948.06d2a0d84620cba6a4fb.css","mappings":"AACA,uBAGE,mBAFA,aACA,YAEA,uBAEA,4BACE,YACA,iBCPJ,gBACE,gBAEA,2DAEE,qBACA,iBAEA,iEACE,mBAGF,mFACE,gBAIJ,sCAOE,YADA,eALA,gBACA,qBAEA,wBADA,uCAEA,YAEA,CAEA,yBATF,sCAWI,YADA,eACA,EAGF,kDACE,YACA,kBAEA,uDACE,eACA,eACA,cAKN,iCACE,aAEA,mCACE,kBAGF,gDACE,aACA,YAKF,2CASE,8CAEA,yBAXF,2CAgBI","sources":["webpack://pleroma_fe/./src/components/async_component_error/async_component_error.vue","webpack://pleroma_fe/./src/components/settings_modal/settings_modal.scss"],"sourcesContent":["\n.async-component-error {\n display: flex;\n height: 100%;\n align-items: center;\n justify-content: center;\n\n .btn {\n margin: 0.5em;\n padding: 0.5em 2em;\n }\n}\n","@import \"src/variables\";\n\n.settings-modal {\n overflow: hidden;\n\n .setting-list,\n .option-list {\n list-style-type: none;\n padding-left: 2em;\n\n li {\n margin-bottom: 0.5em;\n }\n\n .suboptions {\n margin-top: 0.3em;\n }\n }\n\n .settings-modal-panel {\n overflow: hidden;\n transition: transform;\n transition-timing-function: ease-in-out;\n transition-duration: 300ms;\n width: 1000px;\n max-width: 90vw;\n height: 90vh;\n\n @media all and (max-width: 800px) {\n max-width: 100vw;\n height: 100%;\n }\n\n >.panel-body {\n height: 100%;\n overflow-y: hidden;\n\n .btn {\n min-height: 2em;\n min-width: 10em;\n padding: 0 2em;\n }\n }\n }\n\n .settings-footer {\n display: flex;\n\n >* {\n margin-right: 0.5em;\n }\n\n .extra-content {\n display: flex;\n flex-grow: 1;\n }\n }\n\n &.peek {\n .settings-modal-panel {\n /* Explanation:\n * Modal is positioned vertically centered.\n * 100vh - 100% = Distance between modal's top+bottom boundaries and screen\n * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen\n * + 100% - we move modal completely off-screen, it's top boundary touches\n * bottom of the screen\n * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible\n */\n transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));\n\n @media all and (max-width: 800px) {\n /* For mobile, the modal takes 100% of the available screen.\n This ensures the minimized modal is always 50px above the browser bottom\n bar regardless of whether or not it is visible.\n */\n transform: translateY(calc(100% - 50px));\n }\n }\n }\n}\n"],"names":[],"sourceRoot":""} -\ No newline at end of file -diff --git a/priv/static/static/css/7586.0d43f70bc6240422f179.css b/priv/static/static/css/7586.0d43f70bc6240422f179.css -new file mode 100644 -index 0000000000000000000000000000000000000000..7da2aa2ea553e16d597de1814c074b2788cdcfb5 -Binary files /dev/null and b/priv/static/static/css/7586.0d43f70bc6240422f179.css differ -diff --git a/priv/static/static/css/7586.0d43f70bc6240422f179.css.map b/priv/static/static/css/7586.0d43f70bc6240422f179.css.map -new file mode 100644 -index 0000000000000000000000000000000000000000..f8f61fe6ef49becd2c76a53f4d8f95cdd16346a2 ---- /dev/null -+++ b/priv/static/static/css/7586.0d43f70bc6240422f179.css.map -@@ -0,0 +1 @@ -+{"version":3,"file":"static/css/7586.0d43f70bc6240422f179.css","mappings":"AACA,uBAGE,mBAFA,aACA,YAEA,uBAEA,4BACE,YACA,iBCPJ,gBACE,gBAEA,2DAEE,qBACA,iBAEA,iEACE,mBAGF,mFACE,gBAIJ,qCAGE,cADA,kBADA,eAEA,CAGF,sCAOE,YADA,eALA,gBACA,qBAEA,wBADA,uCAEA,YAEA,CAEA,yBATF,sCAWI,YADA,eACA,EAGF,kDACE,YACA,kBAEA,uDACE,eAGF,6EACE,cAKN,iCACE,aACA,eACA,cAEA,mCACE,kBAGF,gDACE,aACA,YAKF,2CASE,8CAEA,yBAXF,2CAgBI","sources":["webpack://pleroma_fe/./src/components/async_component_error/async_component_error.vue","webpack://pleroma_fe/./src/components/settings_modal/settings_modal.scss"],"sourcesContent":["\n.async-component-error {\n display: flex;\n height: 100%;\n align-items: center;\n justify-content: center;\n\n .btn {\n margin: 0.5em;\n padding: 0.5em 2em;\n }\n}\n","@import \"src/variables\";\n\n.settings-modal {\n overflow: hidden;\n\n .setting-list,\n .option-list {\n list-style-type: none;\n padding-left: 2em;\n\n li {\n margin-bottom: 0.5em;\n }\n\n .suboptions {\n margin-top: 0.3em;\n }\n }\n\n .setting-description {\n margin-top: 0.2em;\n margin-bottom: 2em;\n font-size: 70%;\n }\n\n .settings-modal-panel {\n overflow: hidden;\n transition: transform;\n transition-timing-function: ease-in-out;\n transition-duration: 300ms;\n width: 1000px;\n max-width: 90vw;\n height: 90vh;\n\n @media all and (max-width: 800px) {\n max-width: 100vw;\n height: 100%;\n }\n\n >.panel-body {\n height: 100%;\n overflow-y: hidden;\n\n .btn {\n min-height: 2em;\n }\n\n .btn:not(.dropdown-button) {\n padding: 0 2em;\n }\n }\n }\n\n .settings-footer {\n display: flex;\n flex-wrap: wrap;\n line-height: 2;\n\n >* {\n margin-right: 0.5em;\n }\n\n .extra-content {\n display: flex;\n flex-grow: 1;\n }\n }\n\n &.peek {\n .settings-modal-panel {\n /* Explanation:\n * Modal is positioned vertically centered.\n * 100vh - 100% = Distance between modal's top+bottom boundaries and screen\n * (100vh - 100%) / 2 = Distance between bottom (or top) boundary and screen\n * + 100% - we move modal completely off-screen, it's top boundary touches\n * bottom of the screen\n * - 50px - leaving tiny amount of space so that titlebar + tiny amount of modal is visible\n */\n transform: translateY(calc(((100vh - 100%) / 2 + 100%) - 50px));\n\n @media all and (max-width: 800px) {\n /* For mobile, the modal takes 100% of the available screen.\n This ensures the minimized modal is always 50px above the browser bottom\n bar regardless of whether or not it is visible.\n */\n transform: translateY(calc(100% - 50px));\n }\n }\n }\n}\n"],"names":[],"sourceRoot":""} -\ No newline at end of file -diff --git a/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css b/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css -new file mode 100644 -index 0000000000000000000000000000000000000000..2326ed9323c38b12859426c3d656dc350acc46fd -Binary files /dev/null and b/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css differ -diff --git a/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css.map b/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css.map -new file mode 100644 -index 0000000000000000000000000000000000000000..9d501f27a04328a54af9e2faa7b3eba481da0151 ---- /dev/null -+++ b/priv/static/static/css/7962.76663e78ad5ea0bb0b90.css.map -@@ -0,0 +1 @@ -+{"version":3,"file":"static/css/7962.76663e78ad5ea0bb0b90.css","mappings":"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","sources":["webpack://pleroma_fe/./src/components/importer/importer.vue","webpack://pleroma_fe/./src/components/exporter/exporter.vue","webpack://pleroma_fe/./src/components/autosuggest/autosuggest.vue","webpack://pleroma_fe/./src/_variables.scss","webpack://pleroma_fe/./src/components/block_card/block_card.vue","webpack://pleroma_fe/./src/components/mute_card/mute_card.vue","webpack://pleroma_fe/./src/components/domain_mute_card/domain_mute_card.vue","webpack://pleroma_fe/./src/components/selectable_list/selectable_list.vue","webpack://pleroma_fe/./src/hocs/with_subscription/with_subscription.scss","webpack://pleroma_fe/./src/components/settings_modal/tabs/mutes_and_blocks_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/helpers/modified_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/profile_setting_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/draft_buttons.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/security_tab/mfa.vue","webpack://pleroma_fe/./node_modules/cropperjs/dist/cropper.css","webpack://pleroma_fe/./src/components/image_cropper/image_cropper.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/profile_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/helpers/size_setting.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/general_tab.vue","webpack://pleroma_fe/./src/components/color_input/color_input.scss","webpack://pleroma_fe/./src/components/color_input/color_input.vue","webpack://pleroma_fe/./src/components/shadow_control/shadow_control.vue","webpack://pleroma_fe/./src/components/font_control/font_control.vue","webpack://pleroma_fe/./src/components/contrast_ratio/contrast_ratio.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/theme_tab/preview.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/theme_tab/theme_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/settings_modal_user_content.scss"],"sourcesContent":["\n.importer {\n &-uploading {\n font-size: 1.5em;\n margin: 0.25em;\n }\n}\n","\n.exporter {\n &-processing {\n margin: 0.25em;\n }\n}\n","\n@import \"../../variables\";\n\n.autosuggest {\n position: relative;\n\n &-input {\n display: block;\n width: 100%;\n }\n\n &-results {\n position: absolute;\n left: 0;\n top: 100%;\n right: 0;\n max-height: 400px;\n background-color: $fallback--bg;\n background-color: var(--bg, $fallback--bg);\n border-style: solid;\n border-width: 1px;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n border-radius: $fallback--inputRadius;\n border-radius: var(--inputRadius, $fallback--inputRadius);\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n box-shadow: 1px 1px 4px rgb(0 0 0 / 60%);\n box-shadow: var(--panelShadow);\n overflow-y: auto;\n z-index: 1;\n }\n}\n","$main-color: #f58d2c;\n$main-background: white;\n$darkened-background: whitesmoke;\n\n$fallback--bg: #121a24;\n$fallback--fg: #182230;\n$fallback--faint: rgb(185 185 186 / 50%);\n$fallback--text: #b9b9ba;\n$fallback--link: #d8a070;\n$fallback--icon: #666;\n$fallback--lightBg: rgb(21 30 42);\n$fallback--lightText: #b9b9ba;\n$fallback--border: #222;\n$fallback--cRed: #f00;\n$fallback--cBlue: #0095ff;\n$fallback--cGreen: #0fa00f;\n$fallback--cOrange: orange;\n\n$fallback--alertError: rgb(211 16 20 / 50%);\n$fallback--alertWarning: rgb(111 111 20 / 50%);\n\n$fallback--panelRadius: 10px;\n$fallback--checkboxRadius: 2px;\n$fallback--btnRadius: 4px;\n$fallback--inputRadius: 4px;\n$fallback--tooltipRadius: 5px;\n$fallback--avatarRadius: 4px;\n$fallback--avatarAltRadius: 10px;\n$fallback--attachmentRadius: 10px;\n$fallback--chatMessageRadius: 10px;\n\n$fallback--buttonShadow: 0 0 2px 0 rgb(0 0 0 / 100%),\n 0 1px 0 0 rgb(255 255 255 / 20%) inset,\n 0 -1px 0 0 rgb(0 0 0 / 20%) inset;\n\n$status-margin: 0.75em;\n","\n.block-card-content-container {\n margin-top: 0.5em;\n text-align: right;\n\n button {\n width: 10em;\n }\n}\n","\n.mute-card-content-container {\n margin-top: 0.5em;\n text-align: right;\n\n button {\n width: 10em;\n }\n}\n","\n.domain-mute-card {\n flex: 1 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.6em 1em 0.6em 0;\n\n &-domain {\n margin-right: 1em;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n button {\n width: 10em;\n }\n\n .autosuggest-results & {\n padding-left: 1em;\n }\n}\n","\n@import \"../../variables\";\n\n.selectable-list {\n &-item-inner {\n display: flex;\n align-items: center;\n\n > * {\n min-width: 0;\n }\n }\n\n &-item-selected-inner {\n background-color: $fallback--lightBg;\n background-color: var(--selectedMenu, $fallback--lightBg);\n color: var(--selectedMenuText, $fallback--text);\n\n --faint: var(--selectedMenuFaintText, $fallback--faint);\n --faintLink: var(--selectedMenuFaintLink, $fallback--faint);\n --lightText: var(--selectedMenuLightText, $fallback--lightText);\n --icon: var(--selectedMenuIcon, $fallback--icon);\n }\n\n &-header {\n display: flex;\n align-items: center;\n padding: 0.6em 0;\n border-bottom: 2px solid;\n border-bottom-color: $fallback--border;\n border-bottom-color: var(--border, $fallback--border);\n\n &-actions {\n flex: 1;\n }\n }\n\n &-checkbox-wrapper {\n padding: 0 10px;\n flex: none;\n }\n}\n",".with-subscription {\n &-loading {\n padding: 10px;\n text-align: center;\n\n .error {\n font-size: 1rem;\n }\n }\n}\n",".mutes-and-blocks-tab {\n height: 100%;\n\n .usersearch-wrapper {\n padding: 1em;\n }\n\n .bulk-actions {\n text-align: right;\n padding: 0 1em;\n min-height: 2em;\n }\n\n .bulk-action-button {\n width: 10em;\n }\n\n .domain-mute-form {\n padding: 1em;\n display: flex;\n flex-direction: column;\n }\n\n .domain-mute-button {\n align-self: flex-end;\n margin-top: 1em;\n width: 10em;\n }\n}\n","\n.ModifiedIndicator {\n display: inline-block;\n position: relative;\n}\n\n.modified-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.ProfileSettingIndicator {\n display: inline-block;\n position: relative;\n}\n\n.profilesetting-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.DraftButtons {\n display: inline-block;\n position: relative;\n\n .button-default {\n margin-left: 0.5em;\n }\n}\n\n.draft-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n@import \"../../../../variables\";\n\n.mfa-backup-codes {\n .warning {\n color: $fallback--cOrange;\n color: var(--cOrange, $fallback--cOrange);\n }\n\n .backup-codes {\n font-family: var(--postCodeFont, monospace);\n }\n}\n","\n@import \"../../../../variables\";\n\n.mfa-settings {\n .mfa-heading,\n .method-item {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: baseline;\n }\n\n .warning {\n color: $fallback--cOrange;\n color: var(--cOrange, $fallback--cOrange);\n }\n\n .setup-otp {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n\n .qr-code {\n flex: 1;\n padding-right: 10px;\n }\n .verify { flex: 1; }\n .error { margin: 4px 0 0; }\n\n .confirm-otp-actions {\n button {\n width: 15em;\n margin-top: 5px;\n }\n }\n }\n}\n","/*!\n * Cropper.js v1.5.13\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2022-11-20T05:30:43.444Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n -webkit-backface-visibility: hidden;\n backface-visibility: hidden;\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n }\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: 0.5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline: 1px solid #39f;\n outline-color: rgba(51, 153, 255, 75%);\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: 0.5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n }\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n }\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: 0.75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center::before,\n .cropper-center::after {\n background-color: #eee;\n content: \" \";\n display: block;\n position: absolute;\n }\n\n.cropper-center::before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n }\n\n.cropper-center::after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n }\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: 0.1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n }\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n }\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n }\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: 0.75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n }\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n }\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n }\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n }\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n }\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n }\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n }\n\n@media (min-width: 768px) {\n\n.cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n }\n\n@media (min-width: 992px) {\n\n.cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n }\n\n@media (min-width: 1200px) {\n\n.cropper-point.point-se {\n height: 5px;\n opacity: 0.75;\n width: 5px;\n }\n }\n\n.cropper-point.point-se::before {\n background-color: #39f;\n bottom: -50%;\n content: \" \";\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n }\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC\");\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n","\n.image-cropper {\n &-img-input {\n display: none;\n }\n\n &-image-container {\n position: relative;\n\n img {\n display: block;\n max-width: 100%;\n }\n }\n\n &-buttons-wrapper {\n margin-top: 10px;\n\n button {\n margin-top: 5px;\n }\n }\n}\n","@import \"../../../variables\";\n\n.profile-tab {\n .bio {\n margin: 0;\n }\n\n .visibility-tray {\n padding-top: 5px;\n }\n\n input[type=\"file\"] {\n padding: 5px;\n height: auto;\n }\n\n .banner-background-preview {\n max-width: 100%;\n width: 300px;\n position: relative;\n\n img {\n width: 100%;\n }\n }\n\n .uploading {\n font-size: 1.5em;\n margin: 0.25em;\n }\n\n .name-changer {\n width: 100%;\n }\n\n .current-avatar-container {\n position: relative;\n width: 150px;\n height: 150px;\n }\n\n .current-avatar {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: $fallback--avatarRadius;\n border-radius: var(--avatarRadius, $fallback--avatarRadius);\n }\n\n .reset-button {\n position: absolute;\n top: 0.2em;\n right: 0.2em;\n border-radius: $fallback--tooltipRadius;\n border-radius: var(--tooltipRadius, $fallback--tooltipRadius);\n background-color: rgb(0 0 0 / 60%);\n opacity: 0.7;\n width: 1.5em;\n height: 1.5em;\n text-align: center;\n line-height: 1.5em;\n font-size: 1.5em;\n cursor: pointer;\n\n &:hover {\n opacity: 1;\n }\n\n svg {\n color: white;\n }\n }\n\n .oauth-tokens {\n width: 100%;\n\n th {\n text-align: left;\n }\n\n .actions {\n text-align: right;\n }\n }\n\n &-usersearch-wrapper {\n padding: 1em;\n }\n\n &-bulk-actions {\n text-align: right;\n padding: 0 1em;\n min-height: 2em;\n\n button {\n width: 10em;\n }\n }\n\n &-domain-mute-form {\n padding: 1em;\n display: flex;\n flex-direction: column;\n\n button {\n align-self: flex-end;\n margin-top: 1em;\n width: 10em;\n }\n }\n\n .setting-subitem {\n margin-left: 1.75em;\n }\n\n .profile-fields {\n display: flex;\n\n & > .emoji-input {\n flex: 1 1 auto;\n margin: 0 0.2em 0.5em;\n min-width: 0;\n }\n\n .delete-field {\n width: 20px;\n align-self: center;\n margin: 0 0.2em 0.5em;\n padding: 0 0.5em;\n }\n }\n\n .birthday-input {\n display: block;\n margin-bottom: 1em;\n }\n}\n","\n.SizeSetting {\n .number-input {\n max-width: 6.5em;\n }\n\n .css-unit-input,\n .css-unit-input select {\n margin-left: 0.5em;\n width: 4em;\n max-width: 4em;\n min-width: 4em;\n }\n}\n\n","\n.column-settings {\n display: flex;\n justify-content: space-evenly;\n flex-wrap: wrap;\n}\n\n.column-settings .size-label {\n display: block;\n margin-bottom: 0.5em;\n margin-top: 0.5em;\n}\n","@import \"../../variables\";\n\n.color-input {\n display: inline-flex;\n\n &-field.input {\n display: inline-flex;\n flex: 0 0 0;\n max-width: 9em;\n align-items: stretch;\n padding: 0.2em 8px;\n\n input {\n background: none;\n color: $fallback--lightText;\n color: var(--inputText, $fallback--lightText);\n border: none;\n padding: 0;\n margin: 0;\n\n &.textColor {\n flex: 1 0 3em;\n min-width: 3em;\n padding: 0;\n }\n\n &.nativeColor {\n flex: 0 0 2em;\n min-width: 2em;\n align-self: stretch;\n min-height: 100%;\n }\n }\n\n .computedIndicator,\n .transparentIndicator {\n flex: 0 0 2em;\n min-width: 2em;\n align-self: stretch;\n min-height: 100%;\n }\n\n .transparentIndicator {\n // forgot to install counter-strike source, ooops\n background-color: #f0f;\n position: relative;\n\n &::before,\n &::after {\n display: block;\n content: \"\";\n background-color: #000;\n position: absolute;\n height: 50%;\n width: 50%;\n }\n\n &::after {\n top: 0;\n left: 0;\n }\n\n &::before {\n bottom: 0;\n right: 0;\n }\n }\n }\n\n .label {\n flex: 1 1 auto;\n }\n}\n","\n.color-control {\n input.text-input {\n max-width: 7em;\n flex: 1;\n }\n}\n","\n@import \"../../variables\";\n\n.shadow-control {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n margin-bottom: 1em;\n\n .shadow-preview-container,\n .shadow-tweak {\n margin: 5px 6px 0 0;\n }\n\n .shadow-preview-container {\n flex: 0;\n display: flex;\n flex-wrap: wrap;\n\n $side: 15em;\n\n input[type=\"number\"] {\n width: 5em;\n min-width: 2em;\n }\n\n .x-shift-control,\n .y-shift-control {\n display: flex;\n flex: 0;\n\n &[disabled=\"disabled\"] * {\n opacity: 0.5;\n }\n }\n\n .x-shift-control {\n align-items: flex-start;\n }\n\n .x-shift-control .wrap,\n input[type=\"range\"] {\n margin: 0;\n width: $side;\n height: 2em;\n }\n\n .y-shift-control {\n flex-direction: column;\n align-items: flex-end;\n\n .wrap {\n width: 2em;\n height: $side;\n }\n\n input[type=\"range\"] {\n transform-origin: 1em 1em;\n transform: rotate(90deg);\n }\n }\n\n .preview-window {\n flex: 1;\n background-color: #999;\n display: flex;\n align-items: center;\n justify-content: center;\n background-image:\n linear-gradient(45deg, #666 25%, transparent 25%),\n linear-gradient(-45deg, #666 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #666 75%),\n linear-gradient(-45deg, transparent 75%, #666 75%);\n background-size: 20px 20px;\n background-position: 0 0, 0 10px, 10px -10px, -10px 0;\n border-radius: $fallback--inputRadius;\n border-radius: var(--inputRadius, $fallback--inputRadius);\n\n .preview-block {\n width: 33%;\n height: 33%;\n background-color: $fallback--bg;\n background-color: var(--bg, $fallback--bg);\n border-radius: $fallback--panelRadius;\n border-radius: var(--panelRadius, $fallback--panelRadius);\n }\n }\n }\n\n .shadow-tweak {\n flex: 1;\n min-width: 280px;\n\n .id-control {\n align-items: stretch;\n\n .shadow-switcher {\n flex: 1;\n }\n\n .shadow-switcher,\n .btn {\n min-width: 1px;\n margin-right: 5px;\n }\n\n .btn {\n padding: 0 0.4em;\n margin: 0 0.1em;\n }\n }\n }\n}\n","\n@import \"../../variables\";\n\n.font-control {\n input.custom-font {\n min-width: 10em;\n }\n\n &.custom {\n /* TODO Should make proper joiners... */\n .font-switcher {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n .custom-font {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n }\n}\n","\n.contrast-ratio {\n display: flex;\n justify-content: flex-end;\n margin-top: -4px;\n margin-bottom: 5px;\n\n .label {\n margin-right: 1em;\n }\n\n .rating {\n display: inline-block;\n text-align: center;\n margin-left: 0.5em;\n }\n}\n","\n.preview-container {\n position: relative;\n}\n\n.underlay-preview {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 10px;\n right: 10px;\n}\n","@import \"src/variables\";\n\n.theme-tab {\n padding-bottom: 2em;\n\n .preset-switcher {\n margin-right: 1em;\n }\n\n .btn {\n margin-left: 0.25em;\n margin-right: 0.25em;\n }\n\n .style-control {\n display: flex;\n align-items: baseline;\n margin-bottom: 5px;\n\n .label {\n flex: 1;\n }\n\n .opt {\n margin: 0.5em;\n }\n\n .color-input {\n flex: 0 0 0;\n }\n\n input,\n select {\n min-width: 3em;\n margin: 0;\n flex: 0;\n\n &[type=\"number\"] {\n min-width: 5em;\n }\n\n &[type=\"range\"] {\n flex: 1;\n min-width: 3em;\n align-self: flex-start;\n }\n }\n\n &.disabled {\n input,\n select {\n opacity: 0.5;\n }\n }\n }\n\n .reset-container {\n flex-wrap: wrap;\n }\n\n .fonts-container,\n .reset-container,\n .apply-container,\n .radius-container,\n .color-container, {\n display: flex;\n }\n\n .fonts-container,\n .radius-container {\n flex-direction: column;\n }\n\n .color-container {\n > h4 {\n width: 99%;\n }\n\n flex-wrap: wrap;\n justify-content: space-between;\n }\n\n .fonts-container,\n .color-container,\n .shadow-container,\n .radius-container,\n .presets-container {\n margin: 1em 1em 0;\n }\n\n .tab-header {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n width: 100%;\n min-height: 30px;\n margin-bottom: 1em;\n\n p {\n flex: 1;\n margin: 0;\n margin-right: 0.5em;\n }\n }\n\n .tab-header-buttons {\n display: flex;\n flex-direction: column;\n\n .btn {\n min-width: 1px;\n flex: 0 auto;\n padding: 0 1em;\n margin-bottom: 0.5em;\n }\n }\n\n .shadow-selector {\n .override {\n flex: 1;\n margin-left: 0.5em;\n }\n\n .select-container {\n margin-top: -4px;\n margin-bottom: -3px;\n }\n }\n\n .save-load,\n .save-load-options {\n display: flex;\n justify-content: center;\n align-items: baseline;\n flex-wrap: wrap;\n\n .presets,\n .import-export {\n margin-bottom: 0.5em;\n }\n\n .import-export {\n display: flex;\n }\n\n .override {\n margin-left: 0.5em;\n }\n }\n\n .save-load-options {\n flex-wrap: wrap;\n margin-top: 0.5em;\n justify-content: center;\n\n .keep-option {\n margin: 0 0.5em 0.5em;\n min-width: 25%;\n }\n }\n\n .preview-container {\n border-top: 1px dashed;\n border-bottom: 1px dashed;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n margin: 1em 0;\n padding: 1em;\n background-color: var(--wallpaper);\n background-image: var(--body-background-image);\n background-size: cover;\n background-position: 50% 50%;\n\n .dummy {\n .post {\n font-family: var(--postFont);\n display: flex;\n\n .content {\n flex: 1;\n\n h4 {\n margin-bottom: 0.25em;\n }\n\n .icons {\n margin-top: 0.5em;\n display: flex;\n\n i {\n margin-right: 1em;\n }\n }\n }\n }\n\n .after-post {\n margin-top: 1em;\n display: flex;\n align-items: center;\n }\n\n .avatar,\n .avatar-alt {\n background:\n linear-gradient(\n 135deg,\n #b8e1fc 0%,\n #a9d2f3 10%,\n #90bae4 25%,\n #90bcea 37%,\n #90bff0 50%,\n #6ba8e5 51%,\n #a2daf5 83%,\n #bdf3fd 100%\n );\n color: black;\n font-family: sans-serif;\n text-align: center;\n margin-right: 1em;\n }\n\n .avatar-alt {\n flex: 0 auto;\n margin-left: 28px;\n font-size: 12px;\n min-width: 20px;\n min-height: 20px;\n line-height: 20px;\n border-radius: $fallback--avatarAltRadius;\n border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);\n }\n\n .avatar {\n flex: 0 auto;\n width: 48px;\n height: 48px;\n font-size: 14px;\n line-height: 48px;\n }\n\n .actions {\n display: flex;\n align-items: baseline;\n\n .checkbox {\n display: inline-flex;\n align-items: baseline;\n margin-right: 1em;\n flex: 1;\n }\n }\n\n .separator {\n margin: 1em;\n border-bottom: 1px solid;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n }\n\n .btn {\n min-width: 3em;\n }\n }\n }\n\n .radius-item {\n flex-basis: auto;\n }\n\n .radius-item,\n .color-item {\n min-width: 20em;\n margin: 5px 6px 0 0;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n\n &.wide {\n min-width: 60%;\n }\n\n &:not(.wide):nth-child(2n+1) {\n margin-right: 7px;\n }\n\n .color,\n .opacity {\n display: flex;\n align-items: baseline;\n }\n }\n\n .theme-radius-rn,\n .theme-color-cl {\n border: 0;\n box-shadow: none;\n background: transparent;\n color: var(--faint, $fallback--faint);\n align-self: stretch;\n }\n\n .theme-color-cl,\n .theme-radius-in,\n .theme-color-in {\n margin-left: 4px;\n }\n\n .theme-radius-in {\n min-width: 1em;\n max-width: 7em;\n flex: 1;\n }\n\n .theme-radius-lb {\n max-width: 50em;\n }\n\n .theme-preview-content {\n padding: 20px;\n }\n\n .theme-warning {\n display: flex;\n align-items: baseline;\n margin-bottom: 0.5em;\n\n .buttons {\n .btn {\n margin-bottom: 0.5em;\n }\n }\n }\n}\n\n.extra-content {\n .apply-container {\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n flex-grow: 1;\n\n /* stylelint-disable-next-line no-descending-specificity */\n .btn {\n flex-grow: 1;\n min-height: 2em;\n min-width: 0;\n max-width: 10em;\n padding: 0;\n }\n }\n}\n","@import \"src/variables\";\n\n.settings_tab-switcher {\n height: 100%;\n\n .setting-item {\n border-bottom: 2px solid var(--fg, $fallback--fg);\n margin: 1em 1em 1.4em;\n padding-bottom: 1.4em;\n\n > div,\n > label {\n display: block;\n margin-bottom: 0.5em;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .select-multiple {\n display: flex;\n\n .option-list {\n margin: 0;\n padding-left: 0.5em;\n }\n }\n\n &:last-child {\n border-bottom: none;\n padding-bottom: 0;\n margin-bottom: 1em;\n }\n\n select {\n min-width: 10em;\n }\n\n textarea {\n width: 100%;\n max-width: 100%;\n height: 100px;\n }\n\n .unavailable,\n .unavailable svg {\n color: var(--cRed, $fallback--cRed);\n color: $fallback--cRed;\n }\n }\n}\n"],"names":[],"sourceRoot":""} -\ No newline at end of file -diff --git a/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css b/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css -deleted file mode 100644 -index 6c25e903087e00fc72c45b4dd1111867c9c00c2f..0000000000000000000000000000000000000000 -Binary files a/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css and /dev/null differ -diff --git a/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css.map b/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css.map -deleted file mode 100644 -index e8f8688aee7feb20eaa667e9496fa33d7f095cc6..0000000000000000000000000000000000000000 ---- a/priv/static/static/css/9114.8def3b2b7fe70b3b3712.css.map -+++ /dev/null -@@ -1 +0,0 @@ --{"version":3,"file":"static/css/9114.8def3b2b7fe70b3b3712.css","mappings":"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","sources":["webpack://pleroma_fe/./src/components/importer/importer.vue","webpack://pleroma_fe/./src/components/exporter/exporter.vue","webpack://pleroma_fe/./src/components/autosuggest/autosuggest.vue","webpack://pleroma_fe/./src/_variables.scss","webpack://pleroma_fe/./src/components/block_card/block_card.vue","webpack://pleroma_fe/./src/components/mute_card/mute_card.vue","webpack://pleroma_fe/./src/components/domain_mute_card/domain_mute_card.vue","webpack://pleroma_fe/./src/components/selectable_list/selectable_list.vue","webpack://pleroma_fe/./src/hocs/with_subscription/with_subscription.scss","webpack://pleroma_fe/./src/components/settings_modal/tabs/mutes_and_blocks_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/helpers/modified_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/server_side_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/security_tab/mfa_backup_codes.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/security_tab/mfa.vue","webpack://pleroma_fe/./node_modules/cropperjs/dist/cropper.css","webpack://pleroma_fe/./src/components/image_cropper/image_cropper.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/profile_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/helpers/size_setting.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/general_tab.vue","webpack://pleroma_fe/./src/components/color_input/color_input.scss","webpack://pleroma_fe/./src/components/color_input/color_input.vue","webpack://pleroma_fe/./src/components/shadow_control/shadow_control.vue","webpack://pleroma_fe/./src/components/font_control/font_control.vue","webpack://pleroma_fe/./src/components/contrast_ratio/contrast_ratio.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/theme_tab/preview.vue","webpack://pleroma_fe/./src/components/settings_modal/tabs/theme_tab/theme_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/settings_modal_content.scss"],"sourcesContent":["\n.importer {\n &-uploading {\n font-size: 1.5em;\n margin: 0.25em;\n }\n}\n","\n.exporter {\n &-processing {\n margin: 0.25em;\n }\n}\n","\n@import \"../../variables\";\n\n.autosuggest {\n position: relative;\n\n &-input {\n display: block;\n width: 100%;\n }\n\n &-results {\n position: absolute;\n left: 0;\n top: 100%;\n right: 0;\n max-height: 400px;\n background-color: $fallback--bg;\n background-color: var(--bg, $fallback--bg);\n border-style: solid;\n border-width: 1px;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n border-radius: $fallback--inputRadius;\n border-radius: var(--inputRadius, $fallback--inputRadius);\n border-top-left-radius: 0;\n border-top-right-radius: 0;\n box-shadow: 1px 1px 4px rgb(0 0 0 / 60%);\n box-shadow: var(--panelShadow);\n overflow-y: auto;\n z-index: 1;\n }\n}\n","$main-color: #f58d2c;\n$main-background: white;\n$darkened-background: whitesmoke;\n\n$fallback--bg: #121a24;\n$fallback--fg: #182230;\n$fallback--faint: rgb(185 185 186 / 50%);\n$fallback--text: #b9b9ba;\n$fallback--link: #d8a070;\n$fallback--icon: #666;\n$fallback--lightBg: rgb(21 30 42);\n$fallback--lightText: #b9b9ba;\n$fallback--border: #222;\n$fallback--cRed: #f00;\n$fallback--cBlue: #0095ff;\n$fallback--cGreen: #0fa00f;\n$fallback--cOrange: orange;\n\n$fallback--alertError: rgb(211 16 20 / 50%);\n$fallback--alertWarning: rgb(111 111 20 / 50%);\n\n$fallback--panelRadius: 10px;\n$fallback--checkboxRadius: 2px;\n$fallback--btnRadius: 4px;\n$fallback--inputRadius: 4px;\n$fallback--tooltipRadius: 5px;\n$fallback--avatarRadius: 4px;\n$fallback--avatarAltRadius: 10px;\n$fallback--attachmentRadius: 10px;\n$fallback--chatMessageRadius: 10px;\n\n$fallback--buttonShadow: 0 0 2px 0 rgb(0 0 0 / 100%),\n 0 1px 0 0 rgb(255 255 255 / 20%) inset,\n 0 -1px 0 0 rgb(0 0 0 / 20%) inset;\n\n$status-margin: 0.75em;\n","\n.block-card-content-container {\n margin-top: 0.5em;\n text-align: right;\n\n button {\n width: 10em;\n }\n}\n","\n.mute-card-content-container {\n margin-top: 0.5em;\n text-align: right;\n\n button {\n width: 10em;\n }\n}\n","\n.domain-mute-card {\n flex: 1 0;\n display: flex;\n justify-content: space-between;\n align-items: center;\n padding: 0.6em 1em 0.6em 0;\n\n &-domain {\n margin-right: 1em;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n button {\n width: 10em;\n }\n\n .autosuggest-results & {\n padding-left: 1em;\n }\n}\n","\n@import \"../../variables\";\n\n.selectable-list {\n &-item-inner {\n display: flex;\n align-items: center;\n\n > * {\n min-width: 0;\n }\n }\n\n &-item-selected-inner {\n background-color: $fallback--lightBg;\n background-color: var(--selectedMenu, $fallback--lightBg);\n color: var(--selectedMenuText, $fallback--text);\n\n --faint: var(--selectedMenuFaintText, $fallback--faint);\n --faintLink: var(--selectedMenuFaintLink, $fallback--faint);\n --lightText: var(--selectedMenuLightText, $fallback--lightText);\n --icon: var(--selectedMenuIcon, $fallback--icon);\n }\n\n &-header {\n display: flex;\n align-items: center;\n padding: 0.6em 0;\n border-bottom: 2px solid;\n border-bottom-color: $fallback--border;\n border-bottom-color: var(--border, $fallback--border);\n\n &-actions {\n flex: 1;\n }\n }\n\n &-checkbox-wrapper {\n padding: 0 10px;\n flex: none;\n }\n}\n",".with-subscription {\n &-loading {\n padding: 10px;\n text-align: center;\n\n .error {\n font-size: 1rem;\n }\n }\n}\n",".mutes-and-blocks-tab {\n height: 100%;\n\n .usersearch-wrapper {\n padding: 1em;\n }\n\n .bulk-actions {\n text-align: right;\n padding: 0 1em;\n min-height: 2em;\n }\n\n .bulk-action-button {\n width: 10em;\n }\n\n .domain-mute-form {\n padding: 1em;\n display: flex;\n flex-direction: column;\n }\n\n .domain-mute-button {\n align-self: flex-end;\n margin-top: 1em;\n width: 10em;\n }\n}\n","\n.ModifiedIndicator {\n display: inline-block;\n position: relative;\n}\n\n.modified-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.ServerSideIndicator {\n display: inline-block;\n position: relative;\n}\n\n.serverside-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n@import \"../../../../variables\";\n\n.mfa-backup-codes {\n .warning {\n color: $fallback--cOrange;\n color: var(--cOrange, $fallback--cOrange);\n }\n\n .backup-codes {\n font-family: var(--postCodeFont, monospace);\n }\n}\n","\n@import \"../../../../variables\";\n\n.mfa-settings {\n .mfa-heading,\n .method-item {\n display: flex;\n flex-wrap: wrap;\n justify-content: space-between;\n align-items: baseline;\n }\n\n .warning {\n color: $fallback--cOrange;\n color: var(--cOrange, $fallback--cOrange);\n }\n\n .setup-otp {\n display: flex;\n justify-content: center;\n flex-wrap: wrap;\n\n .qr-code {\n flex: 1;\n padding-right: 10px;\n }\n .verify { flex: 1; }\n .error { margin: 4px 0 0; }\n\n .confirm-otp-actions {\n button {\n width: 15em;\n margin-top: 5px;\n }\n }\n }\n}\n","/*!\n * Cropper.js v1.5.12\n * https://fengyuanchen.github.io/cropperjs\n *\n * Copyright 2015-present Chen Fengyuan\n * Released under the MIT license\n *\n * Date: 2021-06-12T08:00:11.623Z\n */\n\n.cropper-container {\n direction: ltr;\n font-size: 0;\n line-height: 0;\n position: relative;\n -ms-touch-action: none;\n touch-action: none;\n -webkit-user-select: none;\n -moz-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.cropper-container img {\n display: block;\n height: 100%;\n image-orientation: 0deg;\n max-height: none !important;\n max-width: none !important;\n min-height: 0 !important;\n min-width: 0 !important;\n width: 100%;\n}\n\n.cropper-wrap-box,\n.cropper-canvas,\n.cropper-drag-box,\n.cropper-crop-box,\n.cropper-modal {\n bottom: 0;\n left: 0;\n position: absolute;\n right: 0;\n top: 0;\n}\n\n.cropper-wrap-box,\n.cropper-canvas {\n overflow: hidden;\n}\n\n.cropper-drag-box {\n background-color: #fff;\n opacity: 0;\n}\n\n.cropper-modal {\n background-color: #000;\n opacity: 0.5;\n}\n\n.cropper-view-box {\n display: block;\n height: 100%;\n outline: 1px solid #39f;\n outline-color: rgba(51, 153, 255, 0.75);\n overflow: hidden;\n width: 100%;\n}\n\n.cropper-dashed {\n border: 0 dashed #eee;\n display: block;\n opacity: 0.5;\n position: absolute;\n}\n\n.cropper-dashed.dashed-h {\n border-bottom-width: 1px;\n border-top-width: 1px;\n height: calc(100% / 3);\n left: 0;\n top: calc(100% / 3);\n width: 100%;\n}\n\n.cropper-dashed.dashed-v {\n border-left-width: 1px;\n border-right-width: 1px;\n height: 100%;\n left: calc(100% / 3);\n top: 0;\n width: calc(100% / 3);\n}\n\n.cropper-center {\n display: block;\n height: 0;\n left: 50%;\n opacity: 0.75;\n position: absolute;\n top: 50%;\n width: 0;\n}\n\n.cropper-center::before,\n.cropper-center::after {\n background-color: #eee;\n content: ' ';\n display: block;\n position: absolute;\n}\n\n.cropper-center::before {\n height: 1px;\n left: -3px;\n top: 0;\n width: 7px;\n}\n\n.cropper-center::after {\n height: 7px;\n left: 0;\n top: -3px;\n width: 1px;\n}\n\n.cropper-face,\n.cropper-line,\n.cropper-point {\n display: block;\n height: 100%;\n opacity: 0.1;\n position: absolute;\n width: 100%;\n}\n\n.cropper-face {\n background-color: #fff;\n left: 0;\n top: 0;\n}\n\n.cropper-line {\n background-color: #39f;\n}\n\n.cropper-line.line-e {\n cursor: ew-resize;\n right: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-n {\n cursor: ns-resize;\n height: 5px;\n left: 0;\n top: -3px;\n}\n\n.cropper-line.line-w {\n cursor: ew-resize;\n left: -3px;\n top: 0;\n width: 5px;\n}\n\n.cropper-line.line-s {\n bottom: -3px;\n cursor: ns-resize;\n height: 5px;\n left: 0;\n}\n\n.cropper-point {\n background-color: #39f;\n height: 5px;\n opacity: 0.75;\n width: 5px;\n}\n\n.cropper-point.point-e {\n cursor: ew-resize;\n margin-top: -3px;\n right: -3px;\n top: 50%;\n}\n\n.cropper-point.point-n {\n cursor: ns-resize;\n left: 50%;\n margin-left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-w {\n cursor: ew-resize;\n left: -3px;\n margin-top: -3px;\n top: 50%;\n}\n\n.cropper-point.point-s {\n bottom: -3px;\n cursor: s-resize;\n left: 50%;\n margin-left: -3px;\n}\n\n.cropper-point.point-ne {\n cursor: nesw-resize;\n right: -3px;\n top: -3px;\n}\n\n.cropper-point.point-nw {\n cursor: nwse-resize;\n left: -3px;\n top: -3px;\n}\n\n.cropper-point.point-sw {\n bottom: -3px;\n cursor: nesw-resize;\n left: -3px;\n}\n\n.cropper-point.point-se {\n bottom: -3px;\n cursor: nwse-resize;\n height: 20px;\n opacity: 1;\n right: -3px;\n width: 20px;\n}\n\n@media (min-width: 768px) {\n .cropper-point.point-se {\n height: 15px;\n width: 15px;\n }\n}\n\n@media (min-width: 992px) {\n .cropper-point.point-se {\n height: 10px;\n width: 10px;\n }\n}\n\n@media (min-width: 1200px) {\n .cropper-point.point-se {\n height: 5px;\n opacity: 0.75;\n width: 5px;\n }\n}\n\n.cropper-point.point-se::before {\n background-color: #39f;\n bottom: -50%;\n content: ' ';\n display: block;\n height: 200%;\n opacity: 0;\n position: absolute;\n right: -50%;\n width: 200%;\n}\n\n.cropper-invisible {\n opacity: 0;\n}\n\n.cropper-bg {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAQMAAAAlPW0iAAAAA3NCSVQICAjb4U/gAAAABlBMVEXMzMz////TjRV2AAAACXBIWXMAAArrAAAK6wGCiw1aAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAABFJREFUCJlj+M/AgBVhF/0PAH6/D/HkDxOGAAAAAElFTkSuQmCC');\n}\n\n.cropper-hide {\n display: block;\n height: 0;\n position: absolute;\n width: 0;\n}\n\n.cropper-hidden {\n display: none !important;\n}\n\n.cropper-move {\n cursor: move;\n}\n\n.cropper-crop {\n cursor: crosshair;\n}\n\n.cropper-disabled .cropper-drag-box,\n.cropper-disabled .cropper-face,\n.cropper-disabled .cropper-line,\n.cropper-disabled .cropper-point {\n cursor: not-allowed;\n}\n","\n.image-cropper {\n &-img-input {\n display: none;\n }\n\n &-image-container {\n position: relative;\n\n img {\n display: block;\n max-width: 100%;\n }\n }\n\n &-buttons-wrapper {\n margin-top: 10px;\n\n button {\n margin-top: 5px;\n }\n }\n}\n","@import \"../../../variables\";\n\n.profile-tab {\n .bio {\n margin: 0;\n }\n\n .visibility-tray {\n padding-top: 5px;\n }\n\n input[type=\"file\"] {\n padding: 5px;\n height: auto;\n }\n\n .banner-background-preview {\n max-width: 100%;\n width: 300px;\n position: relative;\n\n img {\n width: 100%;\n }\n }\n\n .uploading {\n font-size: 1.5em;\n margin: 0.25em;\n }\n\n .name-changer {\n width: 100%;\n }\n\n .current-avatar-container {\n position: relative;\n width: 150px;\n height: 150px;\n }\n\n .current-avatar {\n display: block;\n width: 100%;\n height: 100%;\n border-radius: $fallback--avatarRadius;\n border-radius: var(--avatarRadius, $fallback--avatarRadius);\n }\n\n .reset-button {\n position: absolute;\n top: 0.2em;\n right: 0.2em;\n border-radius: $fallback--tooltipRadius;\n border-radius: var(--tooltipRadius, $fallback--tooltipRadius);\n background-color: rgb(0 0 0 / 60%);\n opacity: 0.7;\n width: 1.5em;\n height: 1.5em;\n text-align: center;\n line-height: 1.5em;\n font-size: 1.5em;\n cursor: pointer;\n\n &:hover {\n opacity: 1;\n }\n\n svg {\n color: white;\n }\n }\n\n .oauth-tokens {\n width: 100%;\n\n th {\n text-align: left;\n }\n\n .actions {\n text-align: right;\n }\n }\n\n &-usersearch-wrapper {\n padding: 1em;\n }\n\n &-bulk-actions {\n text-align: right;\n padding: 0 1em;\n min-height: 2em;\n\n button {\n width: 10em;\n }\n }\n\n &-domain-mute-form {\n padding: 1em;\n display: flex;\n flex-direction: column;\n\n button {\n align-self: flex-end;\n margin-top: 1em;\n width: 10em;\n }\n }\n\n .setting-subitem {\n margin-left: 1.75em;\n }\n\n .profile-fields {\n display: flex;\n\n & > .emoji-input {\n flex: 1 1 auto;\n margin: 0 0.2em 0.5em;\n min-width: 0;\n }\n\n .delete-field {\n width: 20px;\n align-self: center;\n margin: 0 0.2em 0.5em;\n padding: 0 0.5em;\n }\n }\n\n .birthday-input {\n display: block;\n margin-bottom: 1em;\n }\n}\n","\n.css-unit-input,\n.css-unit-input select {\n margin-left: 0.5em;\n width: 4em;\n max-width: 4em;\n min-width: 4em;\n}\n","\n.column-settings {\n display: flex;\n justify-content: space-evenly;\n flex-wrap: wrap;\n}\n\n.column-settings .size-label {\n display: block;\n margin-bottom: 0.5em;\n margin-top: 0.5em;\n}\n","@import \"../../variables\";\n\n.color-input {\n display: inline-flex;\n\n &-field.input {\n display: inline-flex;\n flex: 0 0 0;\n max-width: 9em;\n align-items: stretch;\n padding: 0.2em 8px;\n\n input {\n background: none;\n color: $fallback--lightText;\n color: var(--inputText, $fallback--lightText);\n border: none;\n padding: 0;\n margin: 0;\n\n &.textColor {\n flex: 1 0 3em;\n min-width: 3em;\n padding: 0;\n }\n\n &.nativeColor {\n flex: 0 0 2em;\n min-width: 2em;\n align-self: stretch;\n min-height: 100%;\n }\n }\n\n .computedIndicator,\n .transparentIndicator {\n flex: 0 0 2em;\n min-width: 2em;\n align-self: stretch;\n min-height: 100%;\n }\n\n .transparentIndicator {\n // forgot to install counter-strike source, ooops\n background-color: #f0f;\n position: relative;\n\n &::before,\n &::after {\n display: block;\n content: \"\";\n background-color: #000;\n position: absolute;\n height: 50%;\n width: 50%;\n }\n\n &::after {\n top: 0;\n left: 0;\n }\n\n &::before {\n bottom: 0;\n right: 0;\n }\n }\n }\n\n .label {\n flex: 1 1 auto;\n }\n}\n","\n.color-control {\n input.text-input {\n max-width: 7em;\n flex: 1;\n }\n}\n","\n@import \"../../variables\";\n\n.shadow-control {\n display: flex;\n flex-wrap: wrap;\n justify-content: center;\n margin-bottom: 1em;\n\n .shadow-preview-container,\n .shadow-tweak {\n margin: 5px 6px 0 0;\n }\n\n .shadow-preview-container {\n flex: 0;\n display: flex;\n flex-wrap: wrap;\n\n $side: 15em;\n\n input[type=\"number\"] {\n width: 5em;\n min-width: 2em;\n }\n\n .x-shift-control,\n .y-shift-control {\n display: flex;\n flex: 0;\n\n &[disabled=\"disabled\"] * {\n opacity: 0.5;\n }\n }\n\n .x-shift-control {\n align-items: flex-start;\n }\n\n .x-shift-control .wrap,\n input[type=\"range\"] {\n margin: 0;\n width: $side;\n height: 2em;\n }\n\n .y-shift-control {\n flex-direction: column;\n align-items: flex-end;\n\n .wrap {\n width: 2em;\n height: $side;\n }\n\n input[type=\"range\"] {\n transform-origin: 1em 1em;\n transform: rotate(90deg);\n }\n }\n\n .preview-window {\n flex: 1;\n background-color: #999;\n display: flex;\n align-items: center;\n justify-content: center;\n background-image:\n linear-gradient(45deg, #666 25%, transparent 25%),\n linear-gradient(-45deg, #666 25%, transparent 25%),\n linear-gradient(45deg, transparent 75%, #666 75%),\n linear-gradient(-45deg, transparent 75%, #666 75%);\n background-size: 20px 20px;\n background-position: 0 0, 0 10px, 10px -10px, -10px 0;\n border-radius: $fallback--inputRadius;\n border-radius: var(--inputRadius, $fallback--inputRadius);\n\n .preview-block {\n width: 33%;\n height: 33%;\n background-color: $fallback--bg;\n background-color: var(--bg, $fallback--bg);\n border-radius: $fallback--panelRadius;\n border-radius: var(--panelRadius, $fallback--panelRadius);\n }\n }\n }\n\n .shadow-tweak {\n flex: 1;\n min-width: 280px;\n\n .id-control {\n align-items: stretch;\n\n .shadow-switcher {\n flex: 1;\n }\n\n .shadow-switcher,\n .btn {\n min-width: 1px;\n margin-right: 5px;\n }\n\n .btn {\n padding: 0 0.4em;\n margin: 0 0.1em;\n }\n }\n }\n}\n","\n@import \"../../variables\";\n\n.font-control {\n input.custom-font {\n min-width: 10em;\n }\n\n &.custom {\n /* TODO Should make proper joiners... */\n .font-switcher {\n border-top-right-radius: 0;\n border-bottom-right-radius: 0;\n }\n\n .custom-font {\n border-top-left-radius: 0;\n border-bottom-left-radius: 0;\n }\n }\n}\n","\n.contrast-ratio {\n display: flex;\n justify-content: flex-end;\n margin-top: -4px;\n margin-bottom: 5px;\n\n .label {\n margin-right: 1em;\n }\n\n .rating {\n display: inline-block;\n text-align: center;\n margin-left: 0.5em;\n }\n}\n","\n.preview-container {\n position: relative;\n}\n\n.underlay-preview {\n position: absolute;\n top: 0;\n bottom: 0;\n left: 10px;\n right: 10px;\n}\n","@import \"src/variables\";\n\n.theme-tab {\n padding-bottom: 2em;\n\n .preset-switcher {\n margin-right: 1em;\n }\n\n .btn {\n margin-left: 0.25em;\n margin-right: 0.25em;\n }\n\n .style-control {\n display: flex;\n align-items: baseline;\n margin-bottom: 5px;\n\n .label {\n flex: 1;\n }\n\n .opt {\n margin: 0.5em;\n }\n\n .color-input {\n flex: 0 0 0;\n }\n\n input,\n select {\n min-width: 3em;\n margin: 0;\n flex: 0;\n\n &[type=\"number\"] {\n min-width: 5em;\n }\n\n &[type=\"range\"] {\n flex: 1;\n min-width: 3em;\n align-self: flex-start;\n }\n }\n\n &.disabled {\n input,\n select {\n opacity: 0.5;\n }\n }\n }\n\n .reset-container {\n flex-wrap: wrap;\n }\n\n .fonts-container,\n .reset-container,\n .apply-container,\n .radius-container,\n .color-container, {\n display: flex;\n }\n\n .fonts-container,\n .radius-container {\n flex-direction: column;\n }\n\n .color-container {\n > h4 {\n width: 99%;\n }\n\n flex-wrap: wrap;\n justify-content: space-between;\n }\n\n .fonts-container,\n .color-container,\n .shadow-container,\n .radius-container,\n .presets-container {\n margin: 1em 1em 0;\n }\n\n .tab-header {\n display: flex;\n justify-content: space-between;\n align-items: baseline;\n width: 100%;\n min-height: 30px;\n margin-bottom: 1em;\n\n p {\n flex: 1;\n margin: 0;\n margin-right: 0.5em;\n }\n }\n\n .tab-header-buttons {\n display: flex;\n flex-direction: column;\n\n .btn {\n min-width: 1px;\n flex: 0 auto;\n padding: 0 1em;\n margin-bottom: 0.5em;\n }\n }\n\n .shadow-selector {\n .override {\n flex: 1;\n margin-left: 0.5em;\n }\n\n .select-container {\n margin-top: -4px;\n margin-bottom: -3px;\n }\n }\n\n .save-load,\n .save-load-options {\n display: flex;\n justify-content: center;\n align-items: baseline;\n flex-wrap: wrap;\n\n .presets,\n .import-export {\n margin-bottom: 0.5em;\n }\n\n .import-export {\n display: flex;\n }\n\n .override {\n margin-left: 0.5em;\n }\n }\n\n .save-load-options {\n flex-wrap: wrap;\n margin-top: 0.5em;\n justify-content: center;\n\n .keep-option {\n margin: 0 0.5em 0.5em;\n min-width: 25%;\n }\n }\n\n .preview-container {\n border-top: 1px dashed;\n border-bottom: 1px dashed;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n margin: 1em 0;\n padding: 1em;\n background-color: var(--wallpaper);\n background-image: var(--body-background-image);\n background-size: cover;\n background-position: 50% 50%;\n\n .dummy {\n .post {\n font-family: var(--postFont);\n display: flex;\n\n .content {\n flex: 1;\n\n h4 {\n margin-bottom: 0.25em;\n }\n\n .icons {\n margin-top: 0.5em;\n display: flex;\n\n i {\n margin-right: 1em;\n }\n }\n }\n }\n\n .after-post {\n margin-top: 1em;\n display: flex;\n align-items: center;\n }\n\n .avatar,\n .avatar-alt {\n background:\n linear-gradient(\n 135deg,\n #b8e1fc 0%,\n #a9d2f3 10%,\n #90bae4 25%,\n #90bcea 37%,\n #90bff0 50%,\n #6ba8e5 51%,\n #a2daf5 83%,\n #bdf3fd 100%\n );\n color: black;\n font-family: sans-serif;\n text-align: center;\n margin-right: 1em;\n }\n\n .avatar-alt {\n flex: 0 auto;\n margin-left: 28px;\n font-size: 12px;\n min-width: 20px;\n min-height: 20px;\n line-height: 20px;\n border-radius: $fallback--avatarAltRadius;\n border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);\n }\n\n .avatar {\n flex: 0 auto;\n width: 48px;\n height: 48px;\n font-size: 14px;\n line-height: 48px;\n }\n\n .actions {\n display: flex;\n align-items: baseline;\n\n .checkbox {\n display: inline-flex;\n align-items: baseline;\n margin-right: 1em;\n flex: 1;\n }\n }\n\n .separator {\n margin: 1em;\n border-bottom: 1px solid;\n border-color: $fallback--border;\n border-color: var(--border, $fallback--border);\n }\n\n .btn {\n min-width: 3em;\n }\n }\n }\n\n .radius-item {\n flex-basis: auto;\n }\n\n .radius-item,\n .color-item {\n min-width: 20em;\n margin: 5px 6px 0 0;\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n\n &.wide {\n min-width: 60%;\n }\n\n &:not(.wide):nth-child(2n+1) {\n margin-right: 7px;\n }\n\n .color,\n .opacity {\n display: flex;\n align-items: baseline;\n }\n }\n\n .theme-radius-rn,\n .theme-color-cl {\n border: 0;\n box-shadow: none;\n background: transparent;\n color: var(--faint, $fallback--faint);\n align-self: stretch;\n }\n\n .theme-color-cl,\n .theme-radius-in,\n .theme-color-in {\n margin-left: 4px;\n }\n\n .theme-radius-in {\n min-width: 1em;\n max-width: 7em;\n flex: 1;\n }\n\n .theme-radius-lb {\n max-width: 50em;\n }\n\n .theme-preview-content {\n padding: 20px;\n }\n\n .theme-warning {\n display: flex;\n align-items: baseline;\n margin-bottom: 0.5em;\n\n .buttons {\n .btn {\n margin-bottom: 0.5em;\n }\n }\n }\n}\n\n.extra-content {\n .apply-container {\n display: flex;\n flex-direction: row;\n justify-content: space-around;\n flex-grow: 1;\n\n /* stylelint-disable-next-line no-descending-specificity */\n .btn {\n flex-grow: 1;\n min-height: 2em;\n min-width: 0;\n max-width: 10em;\n padding: 0;\n }\n }\n}\n","@import \"src/variables\";\n\n.settings_tab-switcher {\n height: 100%;\n\n .setting-item {\n border-bottom: 2px solid var(--fg, $fallback--fg);\n margin: 1em 1em 1.4em;\n padding-bottom: 1.4em;\n\n > div,\n > label {\n display: block;\n margin-bottom: 0.5em;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .select-multiple {\n display: flex;\n\n .option-list {\n margin: 0;\n padding-left: 0.5em;\n }\n }\n\n &:last-child {\n border-bottom: none;\n padding-bottom: 0;\n margin-bottom: 1em;\n }\n\n select {\n min-width: 10em;\n }\n\n textarea {\n width: 100%;\n max-width: 100%;\n height: 100px;\n }\n\n .unavailable,\n .unavailable svg {\n color: var(--cRed, $fallback--cRed);\n color: $fallback--cRed;\n }\n\n .number-input {\n max-width: 6em;\n }\n }\n}\n"],"names":[],"sourceRoot":""} -\ No newline at end of file -diff --git a/priv/static/static/css/9801.cfe503d4c949ae0c3813.css b/priv/static/static/css/9801.cfe503d4c949ae0c3813.css -new file mode 100644 -index 0000000000000000000000000000000000000000..b27df4a19f6e80a806e1267d2e6ce2fa158028fd -Binary files /dev/null and b/priv/static/static/css/9801.cfe503d4c949ae0c3813.css differ -diff --git a/priv/static/static/css/9801.cfe503d4c949ae0c3813.css.map b/priv/static/static/css/9801.cfe503d4c949ae0c3813.css.map -new file mode 100644 -index 0000000000000000000000000000000000000000..7ab561567deb66ff11d8f4c3b8d7021c148922e3 ---- /dev/null -+++ b/priv/static/static/css/9801.cfe503d4c949ae0c3813.css.map -@@ -0,0 +1 @@ -+{"version":3,"file":"static/css/9801.cfe503d4c949ae0c3813.css","mappings":"AACA,mBACE,qBACA,kBAGF,kBACE,gBACA,eACA,kBCRF,yBACE,qBACA,kBAGF,wBACE,gBACA,eACA,kBCRF,cACE,qBACA,kBAEA,8BACE,iBAIJ,eACE,gBACA,eACA,kBCXA,+BACE,cAEA,YACA,mBAFA,UAEA,CAGF,qCAEE,aACA,sBAFA,gBAGA,WAGF,6BACE,mBAEA,uEAEE,WCpBJ,2BACE,UAGF,kBAEE,iBAGA,eADA,kBAHA,uBAEA,kBAEA,CCRJ,uBACE,YAEA,qCACE,0CACA,qBACA,qBAEA,oFAEE,cACA,mBAEA,0GACE,gBAIJ,sDACE,aAEA,mEACE,SACA,kBAIJ,gDACE,mBAEA,kBADA,gBACA,CAGF,4CACE,eAGF,8CAGE,aADA,eADA,UAEA,CAGF,wGAEE,sBACA,SCnCW","sources":["webpack://pleroma_fe/./src/components/settings_modal/helpers/modified_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/profile_setting_indicator.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/draft_buttons.vue","webpack://pleroma_fe/./src/components/settings_modal/helpers/attachment_setting.vue","webpack://pleroma_fe/./src/components/settings_modal/admin_tabs/frontends_tab.scss","webpack://pleroma_fe/./src/components/settings_modal/settings_modal_admin_content.scss","webpack://pleroma_fe/./src/_variables.scss"],"sourcesContent":["\n.ModifiedIndicator {\n display: inline-block;\n position: relative;\n}\n\n.modified-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.ProfileSettingIndicator {\n display: inline-block;\n position: relative;\n}\n\n.profilesetting-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.DraftButtons {\n display: inline-block;\n position: relative;\n\n .button-default {\n margin-left: 0.5em;\n }\n}\n\n.draft-tooltip {\n margin: 0.5em 1em;\n min-width: 10em;\n text-align: center;\n}\n","\n.AttachmentSetting {\n .attachment {\n display: block;\n width: 100%;\n height: 15em;\n margin-bottom: 0.5em;\n }\n\n .attachment-input {\n margin-left: 1em;\n display: flex;\n flex-direction: column;\n width: 20em;\n }\n\n .controls {\n margin-bottom: 0.5em;\n\n input,\n button {\n width: 100%;\n }\n }\n}\n",".frontends-tab {\n .cards-list {\n padding: 0;\n }\n\n dd {\n text-overflow: ellipsis;\n word-wrap: nowrap;\n white-space: nowrap;\n overflow-x: hidden;\n max-width: 10em;\n }\n}\n","@import \"src/variables\";\n\n.settings_tab-switcher {\n height: 100%;\n\n .setting-item {\n border-bottom: 2px solid var(--fg, $fallback--fg);\n margin: 1em 1em 1.4em;\n padding-bottom: 1.4em;\n\n > div,\n > label {\n display: block;\n margin-bottom: 0.5em;\n\n &:last-child {\n margin-bottom: 0;\n }\n }\n\n .select-multiple {\n display: flex;\n\n .option-list {\n margin: 0;\n padding-left: 0.5em;\n }\n }\n\n &:last-child {\n border-bottom: none;\n padding-bottom: 0;\n margin-bottom: 1em;\n }\n\n select {\n min-width: 10em;\n }\n\n textarea {\n width: 100%;\n max-width: 100%;\n height: 100px;\n }\n\n .unavailable,\n .unavailable svg {\n color: var(--cRed, $fallback--cRed);\n color: $fallback--cRed;\n }\n }\n}\n","$main-color: #f58d2c;\n$main-background: white;\n$darkened-background: whitesmoke;\n\n$fallback--bg: #121a24;\n$fallback--fg: #182230;\n$fallback--faint: rgb(185 185 186 / 50%);\n$fallback--text: #b9b9ba;\n$fallback--link: #d8a070;\n$fallback--icon: #666;\n$fallback--lightBg: rgb(21 30 42);\n$fallback--lightText: #b9b9ba;\n$fallback--border: #222;\n$fallback--cRed: #f00;\n$fallback--cBlue: #0095ff;\n$fallback--cGreen: #0fa00f;\n$fallback--cOrange: orange;\n\n$fallback--alertError: rgb(211 16 20 / 50%);\n$fallback--alertWarning: rgb(111 111 20 / 50%);\n\n$fallback--panelRadius: 10px;\n$fallback--checkboxRadius: 2px;\n$fallback--btnRadius: 4px;\n$fallback--inputRadius: 4px;\n$fallback--tooltipRadius: 5px;\n$fallback--avatarRadius: 4px;\n$fallback--avatarAltRadius: 10px;\n$fallback--attachmentRadius: 10px;\n$fallback--chatMessageRadius: 10px;\n\n$fallback--buttonShadow: 0 0 2px 0 rgb(0 0 0 / 100%),\n 0 1px 0 0 rgb(255 255 255 / 20%) inset,\n 0 -1px 0 0 rgb(0 0 0 / 20%) inset;\n\n$status-margin: 0.75em;\n"],"names":[],"sourceRoot":""} -\ No newline at end of file -diff --git a/priv/static/static/css/app.48e52505beba5b9ab69b.css b/priv/static/static/css/app.48e52505beba5b9ab69b.css -deleted file mode 100644 -index ee1ea9cb439dd39f1b70fd7eb159d7381866a9b7..0000000000000000000000000000000000000000 -Binary files a/priv/static/static/css/app.48e52505beba5b9ab69b.css and /dev/null differ -diff --git a/priv/static/static/css/app.48e52505beba5b9ab69b.css.map b/priv/static/static/css/app.48e52505beba5b9ab69b.css.map -deleted file mode 100644 -index a87315d2bd098121524077f5f6ffed16625151b3..0000000000000000000000000000000000000000 ---- a/priv/static/static/css/app.48e52505beba5b9ab69b.css.map -+++ /dev/null -@@ -1 +0,0 @@ --{"version":3,"file":"static/css/app.48e52505beba5b9ab69b.css","mappings":"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","sources":["webpack://pleroma_fe/./src/components/modal/modal.vue","webpack://pleroma_fe/./node_modules/vue-virtual-scroller/dist/vue-virtual-scroller.css","webpack://pleroma_fe/./src/components/login_form/login_form.vue","webpack://pleroma_fe/./src/components/media_upload/media_upload.vue","webpack://pleroma_fe/./src/components/scope_selector/scope_selector.vue","webpack://pleroma_fe/./src/_variables.scss","webpack://pleroma_fe/./src/components/checkbox/checkbox.vue","webpack://pleroma_fe/./src/components/popover/popover.vue","webpack://pleroma_fe/./src/components/still-image/still-image.vue","webpack://pleroma_fe/./src/components/emoji_picker/emoji_picker.scss","webpack://pleroma_fe/./src/components/emoji_input/emoji_input.vue","webpack://pleroma_fe/./src/components/select/select.vue","webpack://pleroma_fe/./src/components/poll/poll_form.vue","webpack://pleroma_fe/./src/components/flash/flash.vue","webpack://pleroma_fe/./src/components/attachment/attachment.scss","webpack://pleroma_fe/./src/components/gallery/gallery.vue","webpack://pleroma_fe/./src/components/user_avatar/user_avatar.vue","webpack://pleroma_fe/./src/components/mention_link/mention_link.scss","webpack://pleroma_fe/./src/components/mentions_line/mentions_line.scss","webpack://pleroma_fe/./src/components/hashtag_link/hashtag_link.scss","webpack://pleroma_fe/./src/components/rich_content/rich_content.scss","webpack://pleroma_fe/./src/components/poll/poll.vue","webpack://pleroma_fe/./src/components/status_body/status_body.scss","webpack://pleroma_fe/./src/components/link-preview/link-preview.vue","webpack://pleroma_fe/./src/components/status_content/status_content.vue","webpack://pleroma_fe/./src/components/post_status_form/post_status_form.vue","webpack://pleroma_fe/./src/components/remote_follow/remote_follow.vue","webpack://pleroma_fe/./src/components/dialog_modal/dialog_modal.vue","webpack://pleroma_fe/./src/components/moderation_tools/moderation_tools.vue","webpack://pleroma_fe/./src/components/account_actions/account_actions.vue","webpack://pleroma_fe/./src/components/user_note/user_note.vue","webpack://pleroma_fe/./src/components/user_card/user_card.scss","webpack://pleroma_fe/./src/components/user_panel/user_panel.vue","webpack://pleroma_fe/./src/components/navigation/navigation_entry.vue","webpack://pleroma_fe/./src/components/navigation/navigation_pins.vue","webpack://pleroma_fe/./src/components/nav_panel/nav_panel.vue","webpack://pleroma_fe/./src/components/features_panel/features_panel.vue","webpack://pleroma_fe/./src/components/who_to_follow_panel/who_to_follow_panel.vue","webpack://pleroma_fe/./src/components/shout_panel/shout_panel.vue","webpack://pleroma_fe/./src/components/media_modal/media_modal.vue","webpack://pleroma_fe/./src/components/side_drawer/side_drawer.vue","webpack://pleroma_fe/./src/components/mobile_post_status_button/mobile_post_status_button.vue","webpack://pleroma_fe/./src/components/reply_button/reply_button.vue","webpack://pleroma_fe/./src/components/favorite_button/favorite_button.vue","webpack://pleroma_fe/./src/components/react_button/react_button.vue","webpack://pleroma_fe/./src/components/retweet_button/retweet_button.vue","webpack://pleroma_fe/./src/components/extra_buttons/extra_buttons.vue","webpack://pleroma_fe/./src/components/avatar_list/avatar_list.vue","webpack://pleroma_fe/./src/components/status_popover/status_popover.vue","webpack://pleroma_fe/./src/components/user_list_popover/user_list_popover.vue","webpack://pleroma_fe/./src/components/emoji_reactions/emoji_reactions.vue","webpack://pleroma_fe/./src/components/status/status.scss","webpack://pleroma_fe/./src/components/report/report.scss","webpack://pleroma_fe/./src/components/notification/notification.scss","webpack://pleroma_fe/./src/components/notifications/notifications.scss","webpack://pleroma_fe/./src/components/mobile_nav/mobile_nav.vue","webpack://pleroma_fe/./src/components/search_bar/search_bar.vue","webpack://pleroma_fe/./src/components/desktop_nav/desktop_nav.scss","webpack://pleroma_fe/./src/components/list/list.vue","webpack://pleroma_fe/./src/components/user_reporting_modal/user_reporting_modal.vue","webpack://pleroma_fe/./src/components/edit_status_modal/edit_status_modal.vue","webpack://pleroma_fe/./src/components/post_status_modal/post_status_modal.vue","webpack://pleroma_fe/./src/components/status_history_modal/status_history_modal.vue","webpack://pleroma_fe/./src/components/global_notice_list/global_notice_list.vue","webpack://pleroma_fe/./src/App.scss","webpack://pleroma_fe/./src/panel.scss","webpack://pleroma_fe/./src/components/thread_tree/thread_tree.vue","webpack://pleroma_fe/./src/components/conversation/conversation.vue","webpack://pleroma_fe/./src/components/timeline_menu/timeline_menu.vue","webpack://pleroma_fe/./src/components/timeline/timeline.scss","webpack://pleroma_fe/./src/components/tab_switcher/tab_switcher.scss","webpack://pleroma_fe/./src/components/chat_title/chat_title.vue","webpack://pleroma_fe/./src/components/chat_list_item/chat_list_item.scss","webpack://pleroma_fe/./src/components/basic_user_card/basic_user_card.vue","webpack://pleroma_fe/./src/components/chat_new/chat_new.scss","webpack://pleroma_fe/./src/components/chat_list/chat_list.vue","webpack://pleroma_fe/./src/components/chat_message/chat_message.scss","webpack://pleroma_fe/./src/components/chat/chat.scss","webpack://pleroma_fe/./src/components/follow_card/follow_card.vue","webpack://pleroma_fe/./src/hocs/with_load_more/with_load_more.scss","webpack://pleroma_fe/./src/components/user_profile/user_profile.vue","webpack://pleroma_fe/./src/components/search/search.vue","webpack://pleroma_fe/./src/components/interface_language_switcher/interface_language_switcher.vue","webpack://pleroma_fe/./src/components/registration/registration.vue","webpack://pleroma_fe/./src/components/password_reset/password_reset.vue","webpack://pleroma_fe/./src/components/follow_request_card/follow_request_card.vue","webpack://pleroma_fe/./src/components/terms_of_service_panel/terms_of_service_panel.vue","webpack://pleroma_fe/./src/components/staff_panel/staff_panel.vue","webpack://pleroma_fe/./src/components/mrf_transparency_panel/mrf_transparency_panel.scss","webpack://pleroma_fe/./src/components/lists_card/lists_card.vue","webpack://pleroma_fe/./src/components/lists/lists.vue","webpack://pleroma_fe/./src/components/lists_user_search/lists_user_search.vue","webpack://pleroma_fe/./src/components/panel_loading/panel_loading.vue","webpack://pleroma_fe/./src/components/lists_edit/lists_edit.vue","webpack://pleroma_fe/./src/components/announcement_editor/announcement_editor.vue","webpack://pleroma_fe/./src/components/announcement/announcement.vue","webpack://pleroma_fe/./src/components/announcements_page/announcements_page.vue"],"sourcesContent":["\n.modal-view {\n z-index: var(--ZI_modals);\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: center;\n align-items: center;\n overflow: auto;\n pointer-events: none;\n animation-duration: 0.2s;\n animation-name: modal-background-fadein;\n opacity: 0;\n\n > * {\n pointer-events: initial;\n }\n\n &.modal-background {\n pointer-events: initial;\n background-color: rgb(0 0 0 / 50%);\n }\n\n &.open {\n opacity: 1;\n }\n}\n\n@keyframes modal-background-fadein {\n from {\n background-color: rgb(0 0 0 / 0%);\n }\n\n to {\n background-color: rgb(0 0 0 / 50%);\n }\n}\n",".vue-recycle-scroller{position:relative}.vue-recycle-scroller.direction-vertical:not(.page-mode){overflow-y:auto}.vue-recycle-scroller.direction-horizontal:not(.page-mode){overflow-x:auto}.vue-recycle-scroller.direction-horizontal{display:flex}.vue-recycle-scroller__slot{flex:auto 0 0}.vue-recycle-scroller__item-wrapper{flex:1;box-sizing:border-box;overflow:hidden;position:relative}.vue-recycle-scroller.ready .vue-recycle-scroller__item-view{position:absolute;top:0;left:0;will-change:transform}.vue-recycle-scroller.direction-vertical .vue-recycle-scroller__item-wrapper{width:100%}.vue-recycle-scroller.direction-horizontal .vue-recycle-scroller__item-wrapper{height:100%}.vue-recycle-scroller.ready.direction-vertical .vue-recycle-scroller__item-view{width:100%}.vue-recycle-scroller.ready.direction-horizontal .vue-recycle-scroller__item-view{height:100%}.resize-observer[data-v-b329ee4c]{position:absolute;top:0;left:0;z-index:-1;width:100%;height:100%;border:none;background-color:transparent;pointer-events:none;display:block;overflow:hidden;opacity:0}.resize-observer[data-v-b329ee4c] object{display:block;position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:-1}","\n@import \"../../variables\";\n\n.login-form {\n display: flex;\n flex-direction: column;\n padding: 0.6em;\n\n .btn {\n min-height: 2em;\n width: 10em;\n }\n\n .register {\n flex: 1 1;\n }\n\n .login-bottom {\n margin-top: 1em;\n display: flex;\n flex-direction: row;\n align-items: center;\n justify-content: space-between;\n }\n\n .form-group {\n display: flex;\n flex-direction: column;\n padding: 0.3em 0.5em 0.6em;\n line-height: 24px;\n }\n\n .form-bottom {\n display: flex;\n padding: 0.5em;\n height: 32px;\n\n button {\n width: 10em;\n }\n\n p {\n margin: 0.35em;\n padding: 0.35em;\n display: flex;\n }\n }\n\n .error {\n text-align: center;\n animation-name: shakeError;\n animation-duration: 0.4s;\n animation-timing-function: ease-in-out;\n }\n}\n","\n@import \"../../variables\";\n\n.media-upload {\n cursor: pointer; // We use