diff --git a/CHANGELOG.md b/CHANGELOG.md index a979ff3256..4bbbd0ea6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,8 +11,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - MastoFE ### Changed +- **Breaking:** Elixir >=1.10 is now required (was >= 1.9) - Allow users to remove their emails if instance does not need email to register - Uploadfilter `Pleroma.Upload.Filter.Exiftool` has been renamed to `Pleroma.Upload.Filter.Exiftool.StripLocation` +- **Breaking**: `/api/v1/pleroma/backups` endpoints now requires `read:backups` scope instead of `read:accounts` - Updated the recommended pleroma.vcl configuration for Varnish to target Varnish 7.0+ ### Added diff --git a/ci/Dockerfile b/ci/Dockerfile index 5dfe574421..dcb2d0ab23 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,7 +1,8 @@ FROM elixir:1.12 +# Single RUN statement, otherwise intermediate images are created +# https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run RUN apt-get update &&\ - apt-get install -y libmagic-dev cmake libimage-exiftool-perl ffmpeg &&\ + apt-get install -y libmagic-dev cmake libimage-exiftool-perl ffmpeg &&\ mix local.hex --force &&\ mix local.rebar --force - diff --git a/ci/README b/ci/README new file mode 100644 index 0000000000..3785adef1e --- /dev/null +++ b/ci/README @@ -0,0 +1,12 @@ +## Dependencies + +Assuming an AMD64 Alpine system, you're going to need the following packages +- `qemu qemu-openrc qemu-arm qemu-aarch64` for binfmt +- `docker-cli-buildx` for building the images + +## Setting up + +``` +docker login git.pleroma.social:5050 +doas rc-service qemu-binfmt start +``` diff --git a/config/config.exs b/config/config.exs index b5f9d86e88..39a3f40ef2 100644 --- a/config/config.exs +++ b/config/config.exs @@ -37,7 +37,7 @@ # FIGURATION! EDIT YOUR SECRET FILE (either prod.secret.exs, dev.secret.exs). # # This file is responsible for configuring your application -# and its dependencies with the aid of the Mix.Config module. +# and its dependencies with the aid of the Config module. # # This configuration file is loaded before any dependency and # is restricted to this project. @@ -571,8 +571,8 @@ token_expiration: 5, filter_expiration: 1, backup: 1, - federator_incoming: 50, - federator_outgoing: 50, + federator_incoming: 5, + federator_outgoing: 5, ingestion_queue: 50, web_push: 50, mailer: 10, diff --git a/docs/configuration/howto_database_config.md b/docs/configuration/howto_database_config.md index ae1462f9b0..e5af9097a9 100644 --- a/docs/configuration/howto_database_config.md +++ b/docs/configuration/howto_database_config.md @@ -59,7 +59,7 @@ The configuration of Pleroma has traditionally been managed with a config file, Here is an example of a server config stripped down after migration: ``` - use Mix.Config + import Config config :pleroma, Pleroma.Web.Endpoint, url: [host: "cool.pleroma.site", scheme: "https", port: 443] diff --git a/docs/installation/generic_dependencies.include b/docs/installation/generic_dependencies.include index 2dbd93e427..dcaacfdfda 100644 --- a/docs/installation/generic_dependencies.include +++ b/docs/installation/generic_dependencies.include @@ -1,7 +1,7 @@ ## Required dependencies * PostgreSQL 9.6+ -* Elixir 1.9+ +* Elixir 1.10+ * Erlang OTP 22.2+ * git * file / libmagic diff --git a/elixir_buildpack.config b/elixir_buildpack.config index 946408c12f..1102e71455 100644 --- a/elixir_buildpack.config +++ b/elixir_buildpack.config @@ -1,2 +1,2 @@ -elixir_version=1.9.4 +elixir_version=1.10.4 erlang_version=22.3.4.1 diff --git a/lib/mix/tasks/pleroma/config.ex b/lib/mix/tasks/pleroma/config.ex index 33d147d362..3a2ea44f80 100644 --- a/lib/mix/tasks/pleroma/config.ex +++ b/lib/mix/tasks/pleroma/config.ex @@ -304,13 +304,8 @@ defp write_config(file, path, opts) do System.cmd("mix", ["format", path]) end - if Code.ensure_loaded?(Config.Reader) do - defp config_header, do: "import Config\r\n\r\n" - defp read_file(config_file), do: Config.Reader.read_imports!(config_file) - else - defp config_header, do: "use Mix.Config\r\n\r\n" - defp read_file(config_file), do: Mix.Config.eval!(config_file) - end + defp config_header, do: "import Config\r\n\r\n" + defp read_file(config_file), do: Config.Reader.read_imports!(config_file) defp write_and_delete(config, file, delete?) do config diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex index 50ffb7f27e..929fa17177 100644 --- a/lib/mix/tasks/pleroma/user.ex +++ b/lib/mix/tasks/pleroma/user.ex @@ -112,9 +112,10 @@ def run(["reset_password", nickname]) do {:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do shell_info("Generated password reset token for #{user.nickname}") - IO.puts("URL: #{Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint, - :reset, - token.token)}") + url = + Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint, :reset, token.token) + + IO.puts("URL: #{url}") else _ -> shell_error("No local user #{nickname}") diff --git a/lib/pleroma/config/loader.ex b/lib/pleroma/config/loader.ex index 015be3d8ed..bd85eccab5 100644 --- a/lib/pleroma/config/loader.ex +++ b/lib/pleroma/config/loader.ex @@ -19,21 +19,10 @@ defmodule Pleroma.Config.Loader do :tesla ] - if Code.ensure_loaded?(Config.Reader) do - @reader Config.Reader - - def read(path), do: @reader.read!(path) - else - # support for Elixir less than 1.9 - @reader Mix.Config - def read(path) do - path - |> @reader.eval!() - |> elem(0) - end - end + @reader Config.Reader @spec read(Path.t()) :: keyword() + def read(path), do: @reader.read!(path) @spec merge(keyword(), keyword()) :: keyword() def merge(c1, c2), do: @reader.merge(c1, c2) diff --git a/lib/pleroma/object.ex b/lib/pleroma/object.ex index 489081ec94..d5d57504ea 100644 --- a/lib/pleroma/object.ex +++ b/lib/pleroma/object.ex @@ -144,7 +144,7 @@ defp warn_on_no_object_preloaded(ap_id) do Logger.debug("Backtrace: #{inspect(Process.info(:erlang.self(), :current_stacktrace))}") end - def normalize(_, options \\ [fetch: false]) + def normalize(_, options \\ [fetch: false, id_only: false]) # If we pass an Activity to Object.normalize(), we can try to use the preloaded object. # Use this whenever possible, especially when walking graphs in an O(N) loop! @@ -172,10 +172,15 @@ def normalize(%Activity{data: %{"object" => ap_id}}, options) do def normalize(%{"id" => ap_id}, options), do: normalize(ap_id, options) def normalize(ap_id, options) when is_binary(ap_id) do - if Keyword.get(options, :fetch) do - Fetcher.fetch_object_from_id!(ap_id, options) - else - get_cached_by_ap_id(ap_id) + cond do + Keyword.get(options, :id_only) -> + ap_id + + Keyword.get(options, :fetch) -> + Fetcher.fetch_object_from_id!(ap_id, options) + + true -> + get_cached_by_ap_id(ap_id) end end diff --git a/lib/pleroma/signature.ex b/lib/pleroma/signature.ex index ff0c568564..5cfdae051b 100644 --- a/lib/pleroma/signature.ex +++ b/lib/pleroma/signature.ex @@ -66,9 +66,8 @@ def refetch_public_key(conn) do end end - def sign(%User{} = user, headers) do - with {:ok, %{keys: keys}} <- User.ensure_keys_present(user), - {:ok, private_key, _} <- Keys.keys_from_pem(keys) do + def sign(%User{keys: keys} = user, headers) do + with {:ok, private_key, _} <- Keys.keys_from_pem(keys) do HTTPSignatures.sign(private_key, user.ap_id <> "#main-key", headers) end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 03db604114..d024a092ee 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -723,6 +723,7 @@ def register_changeset_ldap(struct, params = %{password: password}) |> put_ap_id() |> unique_constraint(:ap_id) |> put_following_and_follower_and_featured_address() + |> put_private_key() end def register_changeset(struct, params \\ %{}, opts \\ []) do @@ -781,6 +782,7 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do |> put_ap_id() |> unique_constraint(:ap_id) |> put_following_and_follower_and_featured_address() + |> put_private_key() end def validate_not_restricted_nickname(changeset, field) do @@ -859,6 +861,11 @@ defp put_following_and_follower_and_featured_address(changeset) do |> put_change(:featured_address, featured) end + defp put_private_key(changeset) do + {:ok, pem} = Keys.generate_rsa_pem() + put_change(changeset, :keys, pem) + end + defp autofollow_users(user) do candidates = Config.get([:instance, :autofollowed_nicknames]) @@ -2107,6 +2114,7 @@ defp create_service_actor(uri, nickname) do follower_address: uri <> "/followers" } |> change + |> put_private_key() |> unique_constraint(:nickname) |> Repo.insert() |> set_cache() @@ -2372,17 +2380,6 @@ def get_mascot(%{mascot: mascot}) when is_nil(mascot) do } end - def ensure_keys_present(%{keys: keys} = user) when not is_nil(keys), do: {:ok, user} - - def ensure_keys_present(%User{} = user) do - with {:ok, pem} <- Keys.generate_rsa_pem() do - user - |> cast(%{keys: pem}, [:keys]) - |> validate_required([:keys]) - |> update_and_set_cache() - end - end - def get_ap_ids_by_nicknames(nicknames) do from(u in User, where: u.nickname in ^nicknames, diff --git a/lib/pleroma/user/search.ex b/lib/pleroma/user/search.ex index cd6f69f563..a7fb8fb833 100644 --- a/lib/pleroma/user/search.ex +++ b/lib/pleroma/user/search.ex @@ -94,6 +94,7 @@ defp search_query(query_string, for_user, following, top_user_ids) do |> subquery() |> order_by(desc: :search_rank) |> maybe_restrict_local(for_user) + |> filter_deactivated_users() end defp select_top_users(query, top_user_ids) do @@ -166,6 +167,10 @@ defp filter_internal_users(query) do from(q in query, where: q.actor_type != "Application") end + defp filter_deactivated_users(query) do + from(q in query, where: q.is_active == true) + end + defp filter_blocked_user(query, %User{} = blocker) do query |> join(:left, [u], b in Pleroma.UserRelationship, diff --git a/lib/pleroma/web/activity_pub/activity_pub_controller.ex b/lib/pleroma/web/activity_pub/activity_pub_controller.ex index b8f63d69dc..1357c379c2 100644 --- a/lib/pleroma/web/activity_pub/activity_pub_controller.ex +++ b/lib/pleroma/web/activity_pub/activity_pub_controller.ex @@ -66,8 +66,7 @@ defp relay_active?(conn, _) do end def user(conn, %{"nickname" => nickname}) do - with %User{local: true} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{local: true} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -174,7 +173,6 @@ def relay_following(conn, _params) do def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user), {:show_follows, true} <- {:show_follows, (for_user && for_user == user) || !user.hide_follows} do {page, _} = Integer.parse(page) @@ -192,8 +190,7 @@ def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p end def following(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -213,7 +210,6 @@ def relay_followers(conn, _params) do def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "page" => page}) do with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user), {:show_followers, true} <- {:show_followers, (for_user && for_user == user) || !user.hide_followers} do {page, _} = Integer.parse(page) @@ -231,8 +227,7 @@ def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname, "p end def followers(%{assigns: %{user: for_user}} = conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {user, for_user} <- ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -245,8 +240,7 @@ def outbox( %{"nickname" => nickname, "page" => page?} = params ) when page? in [true, "true"] do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do # "include_poll_votes" is a hack because postgres generates inefficient # queries when filtering by 'Answer', poll votes will be hidden by the # visibility filter in this case anyway @@ -270,8 +264,7 @@ def outbox( end def outbox(conn, %{"nickname" => nickname}) do - with %User{} = user <- User.get_cached_by_nickname(nickname), - {:ok, user} <- User.ensure_keys_present(user) do + with %User{} = user <- User.get_cached_by_nickname(nickname) do conn |> put_resp_content_type("application/activity+json") |> put_view(UserView) @@ -328,14 +321,10 @@ defp post_inbox_relayed_create(conn, params) do end defp represent_service_actor(%User{} = user, conn) do - with {:ok, user} <- User.ensure_keys_present(user) do - conn - |> put_resp_content_type("application/activity+json") - |> put_view(UserView) - |> render("user.json", %{user: user}) - else - nil -> {:error, :not_found} - end + conn + |> put_resp_content_type("application/activity+json") + |> put_view(UserView) + |> render("user.json", %{user: user}) end defp represent_service_actor(nil, _), do: {:error, :not_found} @@ -388,12 +377,10 @@ def read_inbox( def read_inbox(%{assigns: %{user: %User{nickname: nickname} = user}} = conn, %{ "nickname" => nickname }) do - with {:ok, user} <- User.ensure_keys_present(user) do - conn - |> put_resp_content_type("application/activity+json") - |> put_view(UserView) - |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"}) - end + conn + |> put_resp_content_type("application/activity+json") + |> put_view(UserView) + |> render("activity_collection.json", %{iri: "#{user.ap_id}/inbox"}) end def read_inbox(%{assigns: %{user: %User{nickname: as_nickname}}} = conn, %{ @@ -530,19 +517,6 @@ defp set_requester_reachable(%Plug.Conn{} = conn, _) do conn end - defp ensure_user_keys_present_and_maybe_refresh_for_user(user, for_user) do - {:ok, new_user} = User.ensure_keys_present(user) - - for_user = - if new_user != user and match?(%User{}, for_user) do - User.get_cached_by_nickname(for_user.nickname) - else - for_user - end - - {new_user, for_user} - end - def upload_media(%{assigns: %{user: %User{} = user}} = conn, %{"file" => file} = data) do with {:ok, object} <- ActivityPub.upload( diff --git a/lib/pleroma/web/activity_pub/object_validator.ex b/lib/pleroma/web/activity_pub/object_validator.ex index 9f446100db..5bcd6da464 100644 --- a/lib/pleroma/web/activity_pub/object_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validator.ex @@ -247,8 +247,7 @@ def cast_and_apply(%{"type" => type} = object) when type in ~w[Article Note Page def cast_and_apply(o), do: {:error, {:validator_not_set, o}} - # is_struct/1 appears in Elixir 1.11 - def stringify_keys(%{__struct__: _} = object) do + def stringify_keys(object) when is_struct(object) do object |> Map.from_struct() |> stringify_keys diff --git a/lib/pleroma/web/activity_pub/views/object_view.ex b/lib/pleroma/web/activity_pub/views/object_view.ex index f848aba3a5..63caa915c0 100644 --- a/lib/pleroma/web/activity_pub/views/object_view.ex +++ b/lib/pleroma/web/activity_pub/views/object_view.ex @@ -29,11 +29,11 @@ def render("object.json", %{object: %Activity{data: %{"type" => activity_type}} def render("object.json", %{object: %Activity{} = activity}) do base = Pleroma.Web.ActivityPub.Utils.make_json_ld_header() - object = Object.normalize(activity, fetch: false) + object_id = Object.normalize(activity, id_only: true) additional = Transmogrifier.prepare_object(activity.data) - |> Map.put("object", object.data["id"]) + |> Map.put("object", object_id) Map.merge(base, additional) end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 4b5fd736dc..2c7d8cedd2 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -34,7 +34,6 @@ def render("endpoints.json", %{user: %User{local: true} = _user}) do def render("endpoints.json", _), do: %{} def render("service.json", %{user: user}) do - {:ok, user} = User.ensure_keys_present(user) {:ok, _, public_key} = Keys.keys_from_pem(user.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) @@ -71,7 +70,6 @@ def render("user.json", %{user: %User{nickname: "internal." <> _} = user}), do: render("service.json", %{user: user}) |> Map.put("preferredUsername", user.nickname) def render("user.json", %{user: user}) do - {:ok, user} = User.ensure_keys_present(user) {:ok, _, public_key} = Keys.keys_from_pem(user.keys) public_key = :public_key.pem_entry_encode(:SubjectPublicKeyInfo, public_key) public_key = :public_key.pem_encode([public_key]) diff --git a/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex index 82ec1e7bb7..45fa2b0582 100644 --- a/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex +++ b/lib/pleroma/web/api_spec/operations/pleroma_backup_operation.ex @@ -16,7 +16,7 @@ def index_operation do %Operation{ tags: ["Backups"], summary: "List backups", - security: [%{"oAuth" => ["read:account"]}], + security: [%{"oAuth" => ["read:backups"]}], operationId: "PleromaAPI.BackupController.index", responses: %{ 200 => @@ -37,7 +37,7 @@ def create_operation do %Operation{ tags: ["Backups"], summary: "Create a backup", - security: [%{"oAuth" => ["read:account"]}], + security: [%{"oAuth" => ["read:backups"]}], operationId: "PleromaAPI.BackupController.create", responses: %{ 200 => diff --git a/lib/pleroma/web/federator.ex b/lib/pleroma/web/federator.ex index e7feefc073..3be71c1b69 100644 --- a/lib/pleroma/web/federator.ex +++ b/lib/pleroma/web/federator.ex @@ -61,10 +61,8 @@ def perform(:publish_one, module, params) do def perform(:publish, activity) do Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end) - with %User{} = actor <- User.get_cached_by_ap_id(activity.data["actor"]), - {:ok, actor} <- User.ensure_keys_present(actor) do - Publisher.publish(actor, activity) - end + %User{} = actor = User.get_cached_by_ap_id(activity.data["actor"]) + Publisher.publish(actor, activity) end def perform(:incoming_ap_doc, params) do diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 8f3675fd28..d6072e36af 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -488,7 +488,7 @@ def remove_from_followers(%{assigns: %{user: %{id: id}, account: %{id: id}}}, _p def remove_from_followers(%{assigns: %{user: followed, account: follower}} = conn, _params) do with {:ok, follower} <- CommonAPI.reject_follow_request(follower, followed) do - render(conn, "relationship.json", user: follower, target: followed) + render(conn, "relationship.json", user: followed, target: follower) else nil -> render_error(conn, :not_found, "Record not found") diff --git a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex index 1a0548295a..b9daed22bc 100644 --- a/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex +++ b/lib/pleroma/web/pleroma_api/controllers/backup_controller.ex @@ -9,7 +9,7 @@ defmodule Pleroma.Web.PleromaAPI.BackupController do alias Pleroma.Web.Plugs.OAuthScopesPlug action_fallback(Pleroma.Web.MastodonAPI.FallbackController) - plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action in [:index, :create]) + plug(OAuthScopesPlug, %{scopes: ["read:backups"]} when action in [:index, :create]) plug(Pleroma.Web.ApiSpec.CastAndValidate) defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaBackupOperation diff --git a/lib/pleroma/web/web_finger.ex b/lib/pleroma/web/web_finger.ex index f46afa31d3..f95dc24584 100644 --- a/lib/pleroma/web/web_finger.ex +++ b/lib/pleroma/web/web_finger.ex @@ -69,8 +69,6 @@ defp gather_aliases(%User{} = user) do end def represent_user(user, "JSON") do - {:ok, user} = User.ensure_keys_present(user) - %{ "subject" => "acct:#{user.nickname}@#{domain()}", "aliases" => gather_aliases(user), @@ -79,8 +77,6 @@ def represent_user(user, "JSON") do end def represent_user(user, "XML") do - {:ok, user} = User.ensure_keys_present(user) - aliases = user |> gather_aliases() diff --git a/mix.exs b/mix.exs index 1e5da841de..7cd8434b20 100644 --- a/mix.exs +++ b/mix.exs @@ -9,7 +9,7 @@ def project do name: "Rebased", compat_name: "Pleroma", version: version("2.4.52"), - elixir: "~> 1.9", + elixir: "~> 1.10", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix, :gettext] ++ Mix.compilers(), elixirc_options: [warnings_as_errors: warnings_as_errors()], @@ -172,7 +172,7 @@ defp deps do {:prometheus, "~> 4.6"}, {:prometheus_ex, git: "https://gitlab.com/soapbox-pub/elixir-libraries/prometheus.ex.git", - ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5", + branch: "fix/elixir-1.14", override: true}, {:prometheus_plugs, "~> 1.1"}, {:prometheus_phoenix, "~> 1.3"}, @@ -217,7 +217,7 @@ defp deps do {:excoveralls, "0.12.3", only: :test}, {:hackney, "~> 1.18.0", override: true}, {:mox, "~> 1.0", only: :test}, - {:websocket_client, git: "https://github.com/jeremyong/websocket_client.git", only: :test} + {:websockex, "~> 0.4.3", only: :test} ] ++ oauth_deps() end diff --git a/mix.lock b/mix.lock index 9e3e7d8612..cafab5197b 100644 --- a/mix.lock +++ b/mix.lock @@ -116,7 +116,7 @@ "pot": {:hex, :pot, "1.0.1", "81b511b1fa7c3123171c265cb7065a1528cebd7277b0cbc94257c50a8b2e4c17", [:rebar3], [], "hexpm", "ed87f5976531d91528452faa1138a5328db7f9f20d8feaae15f5051f79bcfb6d"}, "prometheus": {:hex, :prometheus, "4.8.0", "1ce1e1002b173c336d61f186b56263346536e76814edd9a142e12aeb2d6c1ad2", [:mix, :rebar3], [], "hexpm", "0fc2e17103073edb3758a46a5d44b006191bf25b73cbaa2b779109de396afcb5"}, "prometheus_ecto": {:hex, :prometheus_ecto, "1.4.3", "3dd4da1812b8e0dbee81ea58bb3b62ed7588f2eae0c9e97e434c46807ff82311", [:mix], [{:ecto, "~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "8d66289f77f913b37eda81fd287340c17e61a447549deb28efc254532b2bed82"}, - "prometheus_ex": {:git, "https://gitlab.com/soapbox-pub/elixir-libraries/prometheus.ex.git", "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5", [ref: "a4e9beb3c1c479d14b352fd9d6dd7b1f6d7deee5"]}, + "prometheus_ex": {:git, "https://gitlab.com/soapbox-pub/elixir-libraries/prometheus.ex.git", "31f7fbe4b71b79ba27efc2a5085746c4011ceb8f", [branch: "fix/elixir-1.14"]}, "prometheus_phoenix": {:hex, :prometheus_phoenix, "1.3.0", "c4b527e0b3a9ef1af26bdcfbfad3998f37795b9185d475ca610fe4388fdd3bb5", [:mix], [{:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.3 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}], "hexpm", "c4d1404ac4e9d3d963da601db2a7d8ea31194f0017057fabf0cfb9bf5a6c8c75"}, "prometheus_phx": {:git, "https://gitlab.com/soapbox-pub/elixir-libraries/prometheus-phx.git", "9cd8f248c9381ffedc799905050abce194a97514", [branch: "no-logging"]}, "prometheus_plugs": {:hex, :prometheus_plugs, "1.1.5", "25933d48f8af3a5941dd7b621c889749894d8a1082a6ff7c67cc99dec26377c5", [:mix], [{:accept, "~> 0.1", [hex: :accept, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:prometheus_ex, "~> 1.1 or ~> 2.0 or ~> 3.0", [hex: :prometheus_ex, repo: "hexpm", optional: false]}, {:prometheus_process_collector, "~> 1.1", [hex: :prometheus_process_collector, repo: "hexpm", optional: true]}], "hexpm", "0273a6483ccb936d79ca19b0ab629aef0dba958697c94782bb728b920dfc6a79"}, @@ -148,4 +148,5 @@ "unsafe": {:hex, :unsafe, "1.0.1", "a27e1874f72ee49312e0a9ec2e0b27924214a05e3ddac90e91727bc76f8613d8", [:mix], [], "hexpm", "6c7729a2d214806450d29766abc2afaa7a2cbecf415be64f36a6691afebb50e5"}, "web_push_encryption": {:hex, :web_push_encryption, "0.3.1", "76d0e7375142dfee67391e7690e89f92578889cbcf2879377900b5620ee4708d", [:mix], [{:httpoison, "~> 1.0", [hex: :httpoison, repo: "hexpm", optional: false]}, {:jose, "~> 1.11.1", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "4f82b2e57622fb9337559058e8797cb0df7e7c9790793bdc4e40bc895f70e2a2"}, "websocket_client": {:git, "https://github.com/jeremyong/websocket_client.git", "9a6f65d05ebf2725d62fb19262b21f1805a59fbf", []}, + "websockex": {:hex, :websockex, "0.4.3", "92b7905769c79c6480c02daacaca2ddd49de936d912976a4d3c923723b647bf0", [:mix], [], "hexpm", "95f2e7072b85a3a4cc385602d42115b73ce0b74a9121d0d6dbbf557645ac53e4"}, } diff --git a/priv/gettext/config_descriptions.pot b/priv/gettext/config_descriptions.pot index 9021fbfab2..a8074ee64e 100644 --- a/priv/gettext/config_descriptions.pot +++ b/priv/gettext/config_descriptions.pot @@ -1720,12 +1720,6 @@ msgctxt "config description at :pleroma-:instance > :banner_upload_limit" msgid "File size limit of user's profile banners" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :pleroma-:instance > :birthday_min_age" -msgid "Minimum required age for users to create account. Only used if birthday is required." -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config description at :pleroma-:instance > :birthday_required" @@ -6021,3 +6015,45 @@ msgstr "" msgctxt "config label at :pleroma-:instance > :short_description" msgid "Short description" msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects" +msgid "`delete_context_objects` background migration settings" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Max accepted rate of objects that failed in the migration. Any value from 0.0 which tolerates no errors to 1.0 which will enable the feature even if context object deletion failed for all records." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval between each chunk of processed records in order to decrease the load on the system (defaults to 0 and should be keep default on most instances)." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :birthday_min_age" +msgid "Minimum required age (in days) for users to create account. Only used if birthday is required." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects" +msgid "Delete context objects" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects > :fault_rate_allowance" +msgid "Fault rate allowance" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:delete_context_objects > :sleep_interval_ms" +msgid "Sleep interval ms" +msgstr "" diff --git a/priv/gettext/errors.pot b/priv/gettext/errors.pot index 85854d23ef..274e5fe7f1 100644 --- a/priv/gettext/errors.pot +++ b/priv/gettext/errors.pot @@ -90,7 +90,7 @@ msgid "must be equal to %{number}" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:523 +#: lib/pleroma/web/common_api.ex:558 msgid "Account not found" msgstr "" @@ -121,12 +121,12 @@ msgid "Can't get favorites" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:482 +#: lib/pleroma/web/common_api/utils.ex:457 msgid "Cannot post an empty status without attachments" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:441 +#: lib/pleroma/web/common_api/utils.ex:445 msgid "Comment must be up to %{max_size} characters" msgstr "" @@ -157,13 +157,13 @@ msgid "Could not unrepeat" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:530 -#: lib/pleroma/web/common_api.ex:539 +#: lib/pleroma/web/common_api.ex:565 +#: lib/pleroma/web/common_api.ex:574 msgid "Could not update state" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:205 +#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:207 msgid "Error." msgstr "" @@ -194,7 +194,7 @@ msgid "Invalid parameters" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:349 +#: lib/pleroma/web/common_api/utils.ex:353 msgid "Invalid password." msgstr "" @@ -213,11 +213,6 @@ msgstr "" msgid "Missing parameters" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:477 -msgid "No such conversation" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:171 #: lib/pleroma/web/admin_api/controllers/admin_api_controller.ex:197 @@ -226,7 +221,7 @@ msgid "No such permission_group" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:515 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:502 #: lib/pleroma/web/admin_api/controllers/fallback_controller.ex:11 #: lib/pleroma/web/feed/tag_controller.ex:16 #: lib/pleroma/web/feed/user_controller.ex:69 @@ -245,7 +240,7 @@ msgstr "" #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:52 -#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:326 +#: lib/pleroma/web/mastodon_api/controllers/status_controller.ex:382 #: lib/pleroma/web/mastodon_api/controllers/subscription_controller.ex:71 msgid "Record not found" msgstr "" @@ -264,7 +259,7 @@ msgid "The message visibility must be direct" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:492 +#: lib/pleroma/web/common_api/utils.ex:467 msgid "The status is over the character limit" msgstr "" @@ -301,22 +296,22 @@ msgid "Your login is missing a confirmed e-mail address" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:403 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:390 msgid "can't read inbox of %{nickname} as %{as_nickname}" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:502 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:489 msgid "can't update outbox of %{nickname} as %{as_nickname}" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:475 +#: lib/pleroma/web/common_api.ex:510 msgid "conversation is already muted" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:521 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:508 msgid "error" msgstr "" @@ -523,6 +518,7 @@ msgstr "" #: lib/pleroma/web/pleroma_api/controllers/notification_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/report_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/scrobble_controller.ex:6 +#: lib/pleroma/web/pleroma_api/controllers/settings_controller.ex:6 #: lib/pleroma/web/pleroma_api/controllers/two_factor_authentication_controller.ex:7 #: lib/pleroma/web/pleroma_api/controllers/user_import_controller.ex:6 #: lib/pleroma/web/static_fe/static_fe_controller.ex:6 @@ -551,7 +547,7 @@ msgid "You can't revoke your own admin/moderator status." msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:129 +#: lib/pleroma/web/mastodon_api/controllers/timeline_controller.ex:131 msgid "authorization required for timeline view" msgstr "" @@ -572,29 +568,19 @@ msgid "User is not an admin." msgstr "" #, elixir-format -#: lib/pleroma/user/backup.ex:75 +#: lib/pleroma/user/backup.ex:73 msgid "Last export was less than a day ago" msgid_plural "Last export was less than %{days} days ago" msgstr[0] "" msgstr[1] "" #, elixir-autogen, elixir-format -#: lib/pleroma/user/backup.ex:93 -msgid "Backups require enabled email" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:434 +#: lib/pleroma/web/activity_pub/activity_pub_controller.ex:421 msgid "Character limit (%{limit} characters) exceeded, contains %{length} characters" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/user/backup.ex:98 -msgid "Email is required" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api/utils.ex:507 +#: lib/pleroma/web/common_api/utils.ex:482 msgid "Too many attachments" msgstr "" diff --git a/priv/gettext/static_pages.pot b/priv/gettext/static_pages.pot index 8e1b1d9dbe..3c64f1a29c 100644 --- a/priv/gettext/static_pages.pot +++ b/priv/gettext/static_pages.pot @@ -83,6 +83,7 @@ msgid "Account followed!" msgstr "" #, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:7 #: lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex:7 msgctxt "placeholder text for account id" msgid "Your account ID, e.g. lain@quitter.se" @@ -511,3 +512,51 @@ msgstr "" msgctxt "account archive email body - admin requested" msgid "
Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:
\n\n" msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:123 +msgctxt "remote follow error message - unknown error" +msgid "Something went wrong." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:67 +msgctxt "remote follow error message - user not found" +msgid "Could not find user" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:8 +msgctxt "status interact authorization button" +msgid "Interact" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:2 +msgctxt "status interact error" +msgid "Error: %{error}" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:95 +msgctxt "status interact error message - status not found" +msgid "Could not find status" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/twitter_api/controllers/util_controller.ex:144 +msgctxt "status interact error message - unknown error" +msgid "Something went wrong." +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +msgctxt "status interact header" +msgid "Interacting with %{nickname}'s %{status_link}" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/templates/twitter_api/util/status_interact.html.eex:4 +msgctxt "status interact header - status link text" +msgid "status" +msgstr "" diff --git a/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs new file mode 100644 index 0000000000..43bc7100bd --- /dev/null +++ b/priv/repo/migrations/20220905011454_generate_unset_user_keys.exs @@ -0,0 +1,28 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2022 Pleroma Authors