From a24b2bc38a18ff25cf4d5f4f87a26fa6fee718eb Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 6 Jan 2021 12:33:09 +0100 Subject: [PATCH 01/41] Resilience Test: Add tests for killing likes. --- test/pleroma/resilience_test.exs | 87 ++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 test/pleroma/resilience_test.exs diff --git a/test/pleroma/resilience_test.exs b/test/pleroma/resilience_test.exs new file mode 100644 index 0000000000..26fa462de6 --- /dev/null +++ b/test/pleroma/resilience_test.exs @@ -0,0 +1,87 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2020 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.ResilienceTest do + use Pleroma.Web.ConnCase, async: true + + import Pleroma.Factory + + alias Pleroma.Activity + alias Pleroma.Web.CommonAPI + alias Pleroma.Repo + alias Pleroma.Web.MastodonAPI.StatusView + + setup do + # user = insert(:user) + %{user: user, conn: conn} = oauth_access(["write:statuses"]) + other_user = insert(:user) + + {:ok, post_one} = CommonAPI.post(user, %{status: "Here is a post"}) + {:ok, like} = CommonAPI.favorite(other_user, post_one.id) + + %{ + user: user, + other_user: other_user, + post_one: post_one, + like: like, + conn: conn + } + end + + test "after destruction of like activities, things still work", %{ + user: user, + post_one: post, + other_user: other_user, + conn: conn, + like: like + } do + post = Repo.get(Activity, post.id) + + # Rendering the liked status + rendered_for_user = StatusView.render("show.json", %{activity: post, for: user}) + assert rendered_for_user.favourites_count == 1 + + rendered_for_other_user = StatusView.render("show.json", %{activity: post, for: other_user}) + assert rendered_for_other_user.favourites_count == 1 + assert rendered_for_other_user.favourited + + # Getting the favourited by + [liking_user] = + conn + |> get("/api/v1/statuses/#{post.id}/favourited_by") + |> json_response(200) + + assert liking_user["id"] == other_user.id + + # Destroying the like + Repo.delete(like) + + # Rendering the liked status + rendered_for_user = StatusView.render("show.json", %{activity: post, for: user}) + assert rendered_for_user.favourites_count == 1 + + rendered_for_other_user = StatusView.render("show.json", %{activity: post, for: other_user}) + assert rendered_for_other_user.favourites_count == 1 + assert rendered_for_other_user.favourited + + # Getting the favourited by + [liking_user] = + conn + |> get("/api/v1/statuses/#{post.id}/favourited_by") + |> json_response(200) + + assert liking_user["id"] == other_user.id + + # Favoriting again doesn't hurt + {:ok, _like_two} = CommonAPI.favorite(other_user, post.id) + + post = Repo.get(Activity, post.id) + + # Rendering the liked status + rendered_for_user = StatusView.render("show.json", %{activity: post, for: user}) + assert rendered_for_user.favourites_count == 1 + + # General fallout: Can't unfavorite stuff anymore. Acceptable for remote users. + end +end From 07bf36142b57f0787717a6cf48a0e8619475abb3 Mon Sep 17 00:00:00 2001 From: lain Date: Wed, 6 Jan 2021 12:49:18 +0100 Subject: [PATCH 02/41] Resilience Test: Add notification check for killing likes. --- test/pleroma/resilience_test.exs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/test/pleroma/resilience_test.exs b/test/pleroma/resilience_test.exs index 26fa462de6..9dc5d0dd66 100644 --- a/test/pleroma/resilience_test.exs +++ b/test/pleroma/resilience_test.exs @@ -8,13 +8,13 @@ defmodule Pleroma.ResilienceTest do import Pleroma.Factory alias Pleroma.Activity - alias Pleroma.Web.CommonAPI alias Pleroma.Repo + alias Pleroma.Web.CommonAPI alias Pleroma.Web.MastodonAPI.StatusView setup do # user = insert(:user) - %{user: user, conn: conn} = oauth_access(["write:statuses"]) + %{user: user, conn: conn} = oauth_access(["write", "read"]) other_user = insert(:user) {:ok, post_one} = CommonAPI.post(user, %{status: "Here is a post"}) @@ -54,8 +54,17 @@ test "after destruction of like activities, things still work", %{ assert liking_user["id"] == other_user.id + # We have one notification + [notification] = + conn + |> get("/api/v1/notifications") + |> json_response(200) + + assert notification["type"] == "favourite" + # Destroying the like Repo.delete(like) + post = Repo.get(Activity, post.id) # Rendering the liked status rendered_for_user = StatusView.render("show.json", %{activity: post, for: user}) @@ -73,6 +82,13 @@ test "after destruction of like activities, things still work", %{ assert liking_user["id"] == other_user.id + # Notification is removed + + assert [] == + conn + |> get("/api/v1/notifications") + |> json_response(200) + # Favoriting again doesn't hurt {:ok, _like_two} = CommonAPI.favorite(other_user, post.id) From 7b56690af4793ebd64e5b4ea60dfa018866567c0 Mon Sep 17 00:00:00 2001 From: Finn Behrens Date: Mon, 10 Jan 2022 23:06:42 +0100 Subject: [PATCH 03/41] add nixos to supported distros --- README.md | 2 +- docs/installation/nixos_en.md | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 docs/installation/nixos_en.md diff --git a/README.md b/README.md index 25fde90b94..62f8fdc64a 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ If your platform is not supported, or you just want to be able to edit the sourc - [OpenBSD (fi)](https://docs-develop.pleroma.social/backend/installation/openbsd_fi/) ### OS/Distro packages -Currently Pleroma is packaged for [YunoHost](https://yunohost.org). If you want to package Pleroma for any OS/Distros, we can guide you through the process on our [community channels](#community-channels). If you want to change default options in your Pleroma package, please **discuss it with us first**. +Currently Pleroma is packaged for [YunoHost](https://yunohost.org) and [NixOS](https://nixos.org). If you want to package Pleroma for any OS/Distros, we can guide you through the process on our [community channels](#community-channels). If you want to change default options in your Pleroma package, please **discuss it with us first**. ### Docker While we don’t provide docker files, other people have written very good ones. Take a look at or . diff --git a/docs/installation/nixos_en.md b/docs/installation/nixos_en.md new file mode 100644 index 0000000000..f3c4988b17 --- /dev/null +++ b/docs/installation/nixos_en.md @@ -0,0 +1,15 @@ +# Installing on NixOS + +NixOS contains a source build package of pleroma and a NixOS module to install it. +For installation add this to your configuration.nix and add a config.exs next to it: +```nix + services.pleroma = { + enable = true; + configs = [ (lib.fileContents ./config.exs) ]; + secretConfigFile = "/var/lib/pleroma/secret.exs"; + }; +``` + +## Questions +The nix community uses matrix for communication: [#nix:nixos.org](https://matrix.to/#/#nix:nixos.org) + From 7c64f705f6ee0364f1e016004bb0baf79d88dae2 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Wed, 2 Nov 2022 21:56:43 -0400 Subject: [PATCH 04/41] Update to Phoenix 1.6 and chase dependencies Also bump minimum Elixir to 1.11 --- .gitlab-ci.yml | 12 ++--- Dockerfile | 2 +- ci/Dockerfile | 2 +- config/test.exs | 5 +- .../feed/feed/_tag_activity.atom.eex | 2 +- .../web/templates/feed/feed/tag.atom.eex | 2 +- .../web/templates/feed/feed/tag.rss.eex | 2 +- .../web/templates/feed/feed/user.atom.eex | 4 +- .../web/templates/feed/feed/user.rss.eex | 4 +- .../web/templates/layout/email.html.eex | 2 +- .../web/templates/layout/embed.html.eex | 2 +- .../templates/o_auth/o_auth/consumer.html.eex | 2 +- .../web/templates/o_auth/o_auth/show.html.eex | 4 +- mix.exs | 26 ++++----- mix.lock | 54 +++++++++++-------- .../20221103014611_create_oban_peers.exs | 7 +++ ...221103014728_swap_primary_oban_indexes.exs | 26 +++++++++ 17 files changed, 99 insertions(+), 59 deletions(-) create mode 100644 priv/repo/migrations/20221103014611_create_oban_peers.exs create mode 100644 priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 37ec483530..7c5c590ec9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -247,7 +247,7 @@ stop_review_app: amd64: stage: release - image: elixir:1.10.4 + image: elixir:1.11.4 only: &release-only - stable@pleroma/pleroma - develop@pleroma/pleroma @@ -285,7 +285,7 @@ amd64-musl: stage: release artifacts: *release-artifacts only: *release-only - image: elixir:1.10.4-alpine + image: elixir:1.11.4-alpine cache: *release-cache variables: *release-variables before_script: &before-release-musl @@ -301,7 +301,7 @@ arm: only: *release-only tags: - arm32-specified - image: arm32v7/elixir:1.10.4 + image: arm32v7/elixir:1.11.4 cache: *release-cache variables: *release-variables before_script: *before-release @@ -313,7 +313,7 @@ arm-musl: only: *release-only tags: - arm32-specified - image: arm32v7/elixir:1.10.4-alpine + image: arm32v7/elixir:1.11.4-alpine cache: *release-cache variables: *release-variables before_script: *before-release-musl @@ -325,7 +325,7 @@ arm64: only: *release-only tags: - arm - image: arm64v8/elixir:1.10.4 + image: arm64v8/elixir:1.11.4 cache: *release-cache variables: *release-variables before_script: *before-release @@ -337,7 +337,7 @@ arm64-musl: only: *release-only tags: - arm - image: arm64v8/elixir:1.10.4-alpine + image: arm64v8/elixir:1.11.4-alpine cache: *release-cache variables: *release-variables before_script: *before-release-musl diff --git a/Dockerfile b/Dockerfile index 334d954f74..64f955b782 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM elixir:1.10-alpine as build +FROM elixir:1.11.4-alpine as build COPY . . diff --git a/ci/Dockerfile b/ci/Dockerfile index d39fd8d7bc..ca28b7029c 100644 --- a/ci/Dockerfile +++ b/ci/Dockerfile @@ -1,4 +1,4 @@ -FROM elixir:1.10.4 +FROM elixir:1.11.4 # Single RUN statement, otherwise intermediate images are created # https://docs.docker.com/develop/develop-images/dockerfile_best-practices/#run diff --git a/config/test.exs b/config/test.exs index f5eb6e5c27..b1d4a8160e 100644 --- a/config/test.exs +++ b/config/test.exs @@ -81,10 +81,7 @@ "BLH1qVhJItRGCfxgTtONfsOKDc9VRAraXw-3NsmjMngWSh7NxOizN6bkuRA7iLTMPS82PjwJAr3UoK9EC1IFrz4", private_key: "_-XZ0iebPrRfZ_o0-IatTdszYa8VCH1yLN-JauK7HHA" -config :pleroma, Oban, - queues: false, - crontab: false, - plugins: false +config :pleroma, Oban, testing: :manual config :pleroma, Pleroma.ScheduledActivity, daily_user_limit: 2, 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 aa3035bca5..7e2e587e18 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex @@ -2,7 +2,7 @@ http://activitystrea.ms/schema/1.0/note http://activitystrea.ms/schema/1.0/post - <%= render @view_module, "_tag_author.atom", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %> <%= @data["id"] %> <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 6d497e84c2..8c551feaf5 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -17,6 +17,6 @@ <%= most_recent_update(@activities) %> <%= for activity <- @activities do %> - <%= render @view_module, "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.rss.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex index edcc3e436d..86466d3675 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.rss.eex @@ -9,7 +9,7 @@ <%= feed_logo() %> 2b90d9 <%= for activity <- @activities do %> - <%= render @view_module, "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.xml", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.atom.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex index 5c1f0ecbc7..97a7535aba 100644 --- a/lib/pleroma/web/templates/feed/feed/user.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -12,13 +12,13 @@ <%= logo(@user) %> - <%= render @view_module, "_author.atom", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_author.atom", assigns %> <%= if last_activity(@activities) do %> <% end %> <%= for activity <- @activities do %> - <%= render @view_module, "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_activity.atom", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex index 6b842a0854..a9fee244cb 100644 --- a/lib/pleroma/web/templates/feed/feed/user.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -7,14 +7,14 @@ <%= logo(@user) %> <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %> - <%= render @view_module, "_author.rss", assigns %> + <%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %> <%= if last_activity(@activities) do %> <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss?max_id=#{last_activity(@activities).id}' %> <% end %> <%= for activity <- @activities do %> - <%= render @view_module, "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> + <%= render Phoenix.Controller.view_module(@conn), "_activity.rss", Map.merge(assigns, prepare_activity(activity)) %> <% end %> diff --git a/lib/pleroma/web/templates/layout/email.html.eex b/lib/pleroma/web/templates/layout/email.html.eex index 087aa4fc01..5858e48b46 100644 --- a/lib/pleroma/web/templates/layout/email.html.eex +++ b/lib/pleroma/web/templates/layout/email.html.eex @@ -5,6 +5,6 @@ <%= @email.subject %> - <%= render @view_module, @view_template, assigns %> + <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %> diff --git a/lib/pleroma/web/templates/layout/embed.html.eex b/lib/pleroma/web/templates/layout/embed.html.eex index 8b905f0705..1197288e54 100644 --- a/lib/pleroma/web/templates/layout/embed.html.eex +++ b/lib/pleroma/web/templates/layout/embed.html.eex @@ -10,6 +10,6 @@ - <%= render @view_module, @view_template, assigns %> + <%= render Phoenix.Controller.view_module(@conn), Phoenix.Controller.view_template(@conn), assigns %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex index 8b894cd58a..98904ad640 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -2,7 +2,7 @@ <%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
- <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> + <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %>
<%= hidden_input f, :client_id, value: @client_id %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index a2f41618e6..b3654f3eb2 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -21,7 +21,7 @@
<%= if @app do %>

<%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application %{client_name} is requesting access to your account.", client_name: safe_to_string(html_escape(@app.client_name))) %>

- <%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> + <%= render Phoenix.Controller.view_module(@conn), "_scopes.html", Map.merge(assigns, %{form: f}) %> <% end %> <%= if @user do %> @@ -63,5 +63,5 @@ <% end %> <%= if Pleroma.Config.oauth_consumer_enabled?() do %> - <%= render @view_module, Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %> + <%= render Phoenix.Controller.view_module(@conn), Pleroma.Web.Auth.WrapperAuthenticator.oauth_consumer_template(), assigns %> <% end %> diff --git a/mix.exs b/mix.exs index 00c8f7b0da..1efdc4ec96 100644 --- a/mix.exs +++ b/mix.exs @@ -5,7 +5,7 @@ def project do [ app: :pleroma, version: version("2.4.53"), - elixir: "~> 1.10", + elixir: "~> 1.11", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix, :gettext] ++ Mix.compilers(), elixirc_options: [warnings_as_errors: warnings_as_errors()], @@ -116,15 +116,19 @@ defp oauth_deps do # Type `mix help deps` for examples and options. defp deps do [ - {:phoenix, "~> 1.5.5"}, + {:phoenix, "~> 1.6.0"}, + {:phoenix_ecto, "~> 4.4.0"}, + {:ecto_enum, "~> 1.4"}, + {:postgrex, ">= 0.0.0"}, + {:phoenix_html, "~> 3.1"}, + {:phoenix_live_reload, "~> 1.3.3", only: :dev}, + {:phoenix_live_view, "~> 0.17.1"}, + {:phoenix_live_dashboard, "~> 0.6.2"}, + {:telemetry_metrics, "~> 0.6.1"}, + {:telemetry_poller, "~> 1.0"}, {:tzdata, "~> 1.0.3"}, {:plug_cowboy, "~> 2.3"}, - {:phoenix_pubsub, "~> 2.0"}, - {:phoenix_ecto, "~> 4.0"}, - {:ecto_enum, "~> 1.4"}, - {:ecto_sql, "~> 3.6.2"}, - {:postgrex, ">= 0.15.5"}, - {:oban, "~> 2.3.4"}, + {:oban, "~> 2.13"}, {:gettext, git: "https://github.com/tusooa/gettext.git", ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808", @@ -133,7 +137,6 @@ defp deps do {:trailing_format_plug, "~> 0.0.7"}, {:fast_sanitize, "~> 0.2.0"}, {:html_entities, "~> 0.5", override: true}, - {:phoenix_html, "~> 3.1", override: true}, {:calendar, "~> 1.0"}, {:cachex, "~> 3.2"}, {:poison, "~> 3.0", override: true}, @@ -155,7 +158,7 @@ defp deps do {:cors_plug, "~> 2.0"}, {:web_push_encryption, "~> 0.3.1"}, {:swoosh, "~> 1.0"}, - {:phoenix_swoosh, "~> 0.3"}, + {:phoenix_swoosh, "~> 1.1"}, {:gen_smtp, "~> 0.13"}, {:ex_syslogger, "~> 1.4"}, {:floki, "~> 0.27"}, @@ -163,7 +166,7 @@ defp deps do {:ueberauth, "~> 0.4"}, {:linkify, "~> 0.5.2"}, {:http_signatures, "~> 0.1.1"}, - {:telemetry, "~> 0.3"}, + {:telemetry, "~> 1.0.0", override: true}, {:poolboy, "~> 1.5"}, {:prometheus, "~> 4.6"}, {:prometheus_ex, @@ -197,7 +200,6 @@ defp deps do {:majic, "~> 1.0"}, {:eblurhash, "~> 1.2.2"}, {:open_api_spex, "~> 3.10"}, - {:phoenix_live_dashboard, "~> 0.6.2"}, {:ecto_psql_extras, "~> 0.6"}, # indirect dependency version override diff --git a/mix.lock b/mix.lock index 4cb6fc7da9..8ed7adc884 100644 --- a/mix.lock +++ b/mix.lock @@ -10,32 +10,33 @@ "cachex": {:hex, :cachex, "3.3.0", "6f2ebb8f27491fe39121bd207c78badc499214d76c695658b19d6079beeca5c2", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "d90e5ee1dde14cef33f6b187af4335b88748b72b30c038969176cd4e6ccc31a1"}, "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"}, "captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, - "castore": {:hex, :castore, "0.1.10", "b01a007416a0ae4188e70b3b306236021b16c11474038ead7aff79dd75538c23", [:mix], [], "hexpm", "a48314e0cb45682db2ea27b8ebfa11bd6fa0a6e21a65e5772ad83ca136ff2665"}, - "certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"}, + "castore": {:hex, :castore, "0.1.18", "deb5b9ab02400561b6f5708f3e7660fc35ca2d51bfc6a940d2f513f89c2975fc", [:mix], [], "hexpm", "61bbaf6452b782ef80b33cdb45701afbcf0a918a45ebe7e73f1130d661e66a06"}, + "certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"}, "combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"}, "comeonin": {:hex, :comeonin, "5.3.2", "5c2f893d05c56ae3f5e24c1b983c2d5dfb88c6d979c9287a76a7feb1e1d8d646", [:mix], [], "hexpm", "d0993402844c49539aeadb3fe46a3c9bd190f1ecf86b6f9ebd71957534c95f04"}, "concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"}, "connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"}, "cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"}, "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, - "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"}, + "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, "credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [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", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"}, "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": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, - "db_connection": {:hex, :db_connection, "2.4.0", "d04b1b73795dae60cead94189f1b8a51cc9e1f911c234cc23074017c43c031e5", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad416c21ad9f61b3103d254a71b63696ecadb6a917b36f563921e0de00d7d7c8"}, + "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"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "earmark": {:hex, :earmark, "1.4.18", "618c4ff1563450d1832b7fb41dc6755e470f91a6fd4c70f350a58b14f64a7db8", [:mix], [{:earmark_parser, ">= 1.4.17", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "57ac3b6da3958ed09c669a9b159e86377fcccda56bacde8a209fa4dcdef52560"}, "earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, - "ecto": {:hex, :ecto, "3.6.2", "efdf52acfc4ce29249bab5417415bd50abd62db7b0603b8bab0d7b996548c2bc", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "efad6dfb04e6f986b8a3047822b0f826d9affe8e4ebdd2aeedbfcb14fd48884e"}, + "ecto": {:hex, :ecto, "3.9.1", "67173b1687afeb68ce805ee7420b4261649d5e2deed8fe5550df23bab0bc4396", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c80bb3d736648df790f7f92f81b36c922d9dd3203ca65be4ff01d067f54eb304"}, "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.4", "5d43fd088d39a158c860b17e8d210669587f63ec89ea122a4654861c8c6e2db4", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, ">= 0.15.7", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "311db02f1b772e3d0dc7f56a05044b5e1499d78ed6abf38885e1ca70059449e5"}, - "ecto_sql": {:hex, :ecto_sql, "3.6.2", "9526b5f691701a5181427634c30655ac33d11e17e4069eff3ae1176c764e0ba3", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.6.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.4.0 or ~> 0.5.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5ec9d7e6f742ea39b63aceaea9ac1d1773d574ea40df5a53ef8afbd9242fdb6b"}, + "ecto_sql": {:hex, :ecto_sql, "3.9.0", "2bb21210a2a13317e098a420a8c1cc58b0c3421ab8e3acfa96417dab7817918c", [:mix], [{:db_connection, "~> 2.5 or ~> 2.4.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a8f3f720073b8b1ac4c978be25fa7960ed7fd44997420c304a4a2e200b596453"}, "eimp": {:hex, :eimp, "1.0.14", "fc297f0c7e2700457a95a60c7010a5f1dcb768a083b6d53f49cd94ab95a28f22", [:rebar3], [{:p1_utils, "1.0.18", [hex: :p1_utils, repo: "hexpm", optional: false]}], "hexpm", "501133f3112079b92d9e22da8b88bf4f0e13d4d67ae9c15c42c30bd25ceb83b6"}, "elixir_make": {:hex, :elixir_make, "0.6.2", "7dffacd77dec4c37b39af867cedaabb0b59f6a871f89722c25b28fcd4bd70530", [:mix], [], "hexpm", "03e49eadda22526a7e5279d53321d1cced6552f344ba4e03e619063de75348d9"}, + "esbuild": {:hex, :esbuild, "0.5.0", "d5bb08ff049d7880ee3609ed5c4b864bd2f46445ea40b16b4acead724fb4c4a3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "f183a0b332d963c4cfaf585477695ea59eef9a6f2204fdd0efa00e099694ffe5"}, "esshd": {:hex, :esshd, "0.1.1", "d4dd4c46698093a40a56afecce8a46e246eb35463c457c246dacba2e056f31b5", [:mix], [], "hexpm", "d73e341e3009d390aa36387dc8862860bf9f874c94d9fd92ade2926376f49981"}, "eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"}, "ex2ms": {:hex, :ex2ms, "1.5.0", "19e27f9212be9a96093fed8cdfbef0a2b56c21237196d26760f11dfcfae58e97", [:mix], [], "hexpm"}, @@ -49,7 +50,7 @@ "fast_html": {:hex, :fast_html, "2.0.5", "c61760340606c1077ff1f196f17834056cb1dd3d5cb92a9f2cabf28bc6221c3c", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2.0", [hex: :nimble_pool, repo: "hexpm", optional: false]}], "hexpm", "605f4f4829443c14127694ebabb681778712ceecb4470ec32aa31012330e6506"}, "fast_sanitize": {:hex, :fast_sanitize, "0.2.2", "3cbbaebaea6043865dfb5b4ecb0f1af066ad410a51470e353714b10c42007b81", [:mix], [{:fast_html, "~> 2.0", [hex: :fast_html, repo: "hexpm", optional: false]}, {:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "69f204db9250afa94a0d559d9110139850f57de2b081719fbafa1e9a89e94466"}, "file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"}, - "finch": {:hex, :finch, "0.10.0", "8e5e6101ae98e7f1ef830594f774411a2f9cbce4f92d8179502da69fbbff52bc", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "80324ba22edbdebca6fac05c8517e7457b79dfe101e3bf6b2f7c5c65c93a9077"}, + "finch": {:hex, :finch, "0.10.2", "9ad27d68270d879f73f26604bb2e573d40f29bf0e907064a9a337f90a16a0312", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: false]}, {:mint, "~> 1.3", [hex: :mint, repo: "hexpm", optional: false]}, {:nimble_options, "~> 0.4.0", [hex: :nimble_options, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "dd8b11b282072cec2ef30852283949c248bd5d2820c88d8acc89402b81db7550"}, "flake_id": {:hex, :flake_id, "0.1.0", "7716b086d2e405d09b647121a166498a0d93d1a623bead243e1f74216079ccb3", [:mix], [{:base62, "~> 1.2", [hex: :base62, repo: "hexpm", optional: false]}, {:ecto, ">= 2.0.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "31fc8090fde1acd267c07c36ea7365b8604055f897d3a53dd967658c691bd827"}, "floki": {:hex, :floki, "0.30.1", "75d35526d3a1459920b6e87fdbc2e0b8a3670f965dd0903708d2b267e0904c55", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "e9c03524447d1c4cbfccd672d739b8c18453eee377846b119d4fd71b1a176bb8"}, "gen_smtp": {:hex, :gen_smtp, "0.15.0", "9f51960c17769b26833b50df0b96123605a8024738b62db747fece14eb2fbfcc", [:rebar3], [], "hexpm", "29bd14a88030980849c7ed2447b8db6d6c9278a28b11a44cafe41b791205440f"}, @@ -57,14 +58,15 @@ "gen_state_machine": {:hex, :gen_state_machine, "2.0.5", "9ac15ec6e66acac994cc442dcc2c6f9796cf380ec4b08267223014be1c728a95", [:mix], [], "hexpm"}, "gettext": {:git, "https://github.com/tusooa/gettext.git", "72fb2496b6c5280ed911bdc3756890e7f38a4808", [ref: "72fb2496b6c5280ed911bdc3756890e7f38a4808"]}, "gun": {:hex, :gun, "2.0.0-rc.2", "7c489a32dedccb77b6e82d1f3c5a7dadfbfa004ec14e322cdb5e579c438632d2", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}], "hexpm", "6b9d1eae146410d727140dbf8b404b9631302ecc2066d1d12f22097ad7d254fc"}, - "hackney": {:hex, :hackney, "1.18.0", "c4443d960bb9fba6d01161d01cd81173089686717d9490e5d3606644c48d121f", [:rebar3], [{:certifi, "~>2.8.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "9afcda620704d720db8c6a3123e9848d09c87586dc1c10479c42627b905b5c5e"}, + "hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"}, + "hpax": {:hex, :hpax, "0.1.2", "09a75600d9d8bbd064cdd741f21fc06fc1f4cf3d0fcc335e5aa19be1a7235c84", [:mix], [], "hexpm", "2c87843d5a23f5f16748ebe77969880e29809580efdaccd615cd3bed628a8c13"}, "html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"}, "html_sanitize_ex": {:hex, :html_sanitize_ex, "1.3.0", "f005ad692b717691203f940c686208aa3d8ffd9dd4bb3699240096a51fa9564e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm"}, "http_signatures": {:hex, :http_signatures, "0.1.1", "ca7ebc1b61542b163644c8c3b1f0e0f41037d35f2395940d3c6c7deceab41fd8", [:mix], [], "hexpm", "cc3b8a007322cc7b624c0c15eec49ee58ac977254ff529a3c482f681465942a3"}, "httpoison": {:hex, :httpoison, "1.8.0", "6b85dea15820b7804ef607ff78406ab449dd78bed923a49c7160e1886e987a3d", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "28089eaa98cf90c66265b6b5ad87c59a3729bea2e74e9d08f9b51eb9729b3c3a"}, "idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"}, "inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"}, - "jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"}, + "jason": {:hex, :jason, "1.4.0", "e855647bc964a44e2f67df589ccf49105ae039d4179db7f6271dfd3843dc27e6", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "79a3791085b2a0f743ca04cec0f7be26443738779d09302e01318f97bdb82121"}, "joken": {:hex, :joken, "2.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"}, "jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"}, "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, @@ -78,7 +80,7 @@ "metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"}, "mime": {:hex, :mime, "1.6.0", "dabde576a497cef4bbdd60aceee8160e02a6c89250d6c0b29e56c0dfb00db3d2", [:mix], [], "hexpm", "31a1a8613f8321143dde1dafc36006a17d28d02bdfecb9e95a880fa7aabd19a7"}, "mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"}, - "mint": {:hex, :mint, "1.4.0", "cd7d2451b201fc8e4a8fd86257fb3878d9e3752899eb67b0c5b25b180bde1212", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}], "hexpm", "10a99e144b815cbf8522dccbc8199d15802440fc7a64d67b6853adb6fa170217"}, + "mint": {:hex, :mint, "1.4.2", "50330223429a6e1260b2ca5415f69b0ab086141bc76dc2fbf34d7c389a6675b2", [:mix], [{:castore, "~> 0.1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:hpax, "~> 0.1.1", [hex: :hpax, repo: "hexpm", optional: false]}], "hexpm", "ce75a5bbcc59b4d7d8d70f8b2fc284b1751ffb35c7b6a6302b5192f8ab4ddd80"}, "mochiweb": {:hex, :mochiweb, "2.18.0", "eb55f1db3e6e960fac4e6db4e2db9ec3602cc9f30b86cd1481d56545c3145d2e", [:rebar3], [], "hexpm"}, "mock": {:hex, :mock, "0.3.7", "75b3bbf1466d7e486ea2052a73c6e062c6256fb429d6797999ab02fa32f29e03", [:mix], [{:meck, "~> 0.9.2", [hex: :meck, repo: "hexpm", optional: false]}], "hexpm", "4da49a4609e41fd99b7836945c26f373623ea968cfb6282742bcb94440cf7e5c"}, "mogrify": {:hex, :mogrify, "0.9.1", "a26f107c4987477769f272bd0f7e3ac4b7b75b11ba597fd001b877beffa9c068", [:mix], [], "hexpm", "134edf189337d2125c0948bf0c228fdeef975c594317452d536224069a5b7f05"}, @@ -86,28 +88,32 @@ "myhtmlex": {:git, "https://git.pleroma.social/pleroma/myhtmlex.git", "ad0097e2f61d4953bfef20fb6abddf23b87111e6", [ref: "ad0097e2f61d4953bfef20fb6abddf23b87111e6", submodules: true]}, "nimble_options": {:hex, :nimble_options, "0.4.0", "c89babbab52221a24b8d1ff9e7d838be70f0d871be823165c94dd3418eea728f", [:mix], [], "hexpm", "e6701c1af326a11eea9634a3b1c62b475339ace9456c1a23ec3bc9a847bca02d"}, "nimble_parsec": {:hex, :nimble_parsec, "0.5.0", "90e2eca3d0266e5c53f8fbe0079694740b9c91b6747f2b7e3c5d21966bba8300", [:mix], [], "hexpm", "5c040b8469c1ff1b10093d3186e2e10dbe483cd73d79ec017993fb3985b8a9b3"}, - "nimble_pool": {:hex, :nimble_pool, "0.2.4", "1db8e9f8a53d967d595e0b32a17030cdb6c0dc4a451b8ac787bf601d3f7704c3", [:mix], [], "hexpm", "367e8071e137b787764e6a9992ccb57b276dc2282535f767a07d881951ebeac6"}, + "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, - "oban": {:hex, :oban, "2.3.4", "ec7509b9af2524d55f529cb7aee93d36131ae0bf0f37706f65d2fe707f4d9fd8", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c70ca0434758fd1805422ea4446af5e910ddc697c0c861549c8f0eb0cfbd2fdf"}, + "oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"}, "open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"}, "p1_utils": {:hex, :p1_utils, "1.0.18", "3fe224de5b2e190d730a3c5da9d6e8540c96484cf4b4692921d1e28f0c32b01c", [:rebar3], [], "hexpm", "1fc8773a71a15553b179c986b22fbeead19b28fe486c332d4929700ffeb71f88"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"}, - "phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"}, - "phoenix_ecto": {:hex, :phoenix_ecto, "4.2.1", "13f124cf0a3ce0f1948cf24654c7b9f2347169ff75c1123f44674afee6af3b03", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 2.15", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "478a1bae899cac0a6e02be1deec7e2944b7754c04e7d4107fc5a517f877743c0"}, - "phoenix_html": {:hex, :phoenix_html, "3.1.0", "0b499df05aad27160d697a9362f0e89fa0e24d3c7a9065c2bd9d38b4d1416c09", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "0c0a98a2cefa63433657983a2a594c7dee5927e4391e0f1bfd3a151d1def33fc"}, + "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, + "phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"}, + "phoenix_html": {:hex, :phoenix_html, "3.2.0", "1c1219d4b6cb22ac72f12f73dc5fad6c7563104d083f711c3fcd8551a1f4ae11", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "36ec97ba56d25c0136ef1992c37957e4246b649d620958a1f9fa86165f8bc54f"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.6.2", "0769470265eb13af01b5001b29cb935f4710d6adaa1ffc18417a570a337a2f0f", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.3", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:mime, "~> 1.6 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:phoenix_live_view, "~> 0.17.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "5bc6c6b38a2ca8b5020b442322fcee6afd5e641637a0b1fb059d4bd89bc58e7b"}, + "phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.17.5", "63f52a6f9f6983f04e424586ff897c016ecc5e4f8d1e2c22c2887af1c57215d8", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.1", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c5586e6a3d4df71b8214c769d4f5eb8ece2b4001711a7ca0f97323c36958b0e3"}, - "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"}, - "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.3", "039435dd975f7e55953525b88f1d596f26c6141412584c16f4db109708a8ee68", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "4a540cea32e05356541737033d666ee7fea7700eb2101bf76783adbfe06601cd"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, + "phoenix_swoosh": {:hex, :phoenix_swoosh, "1.1.0", "f8e4780705c9f254cc853f7a40e25f7198ba4d91102bcfad2226669b69766b35", [:mix], [{:finch, "~> 0.8", [hex: :finch, repo: "hexpm", optional: true]}, {:hackney, "~> 1.10", [hex: :hackney, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.5", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "aa82f10afd9a4b6080fdf3274dbb9432b25b210d42b4b6b55308f6e59cd87c3d"}, + "phoenix_template": {:hex, :phoenix_template, "1.0.0", "c57bc5044f25f007dc86ab21895688c098a9f846a8dda6bc40e2d0ddc146e38f", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "1b066f99a26fd22064c12b2600a9a6e56700f591bf7b20b418054ea38b4d4357"}, + "phoenix_view": {:hex, :phoenix_view, "2.0.1", "a653e3d9d944aace0a064e4a13ad473ffa68f7bc4ca42dbf83cc1d464f1fb295", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}], "hexpm", "6c358e2cefc5f341c728914b867c556bbfd239fed9e881bac257d70cb2b8a6f6"}, "plug": {:hex, :plug, "1.10.4", "41eba7d1a2d671faaf531fa867645bd5a3dce0957d8e2a3f398ccff7d2ef017f", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ad1e233fe73d2eec56616568d260777b67f53148a999dc2d048f4eb9778fe4a0"}, - "plug_cowboy": {:hex, :plug_cowboy, "2.5.0", "51c998f788c4e68fc9f947a5eba8c215fbb1d63a520f7604134cab0270ea6513", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5b2c8925a5e2587446f33810a58c01e66b3c345652eeec809b76ba007acde71a"}, - "plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"}, + "plug_cowboy": {:hex, :plug_cowboy, "2.5.2", "62894ccd601cf9597e2c23911ff12798a8a18d237e9739f58a6b04e4988899fe", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ea6e87f774c8608d60c8d34022a7d073bd7680a0a013f049fc62bf35efea1044"}, + "plug_crypto": {:hex, :plug_crypto, "1.2.3", "8f77d13aeb32bfd9e654cb68f0af517b371fb34c56c9f2b58fe3df1235c1251a", [:mix], [], "hexpm", "b5672099c6ad5c202c45f5a403f21a3411247f164e4a8fab056e5cd8a290f4a2"}, "plug_static_index_html": {:hex, :plug_static_index_html, "1.0.0", "840123d4d3975585133485ea86af73cb2600afd7f2a976f9f5fd8b3808e636a0", [:mix], [{:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "79fd4fcf34d110605c26560cbae8f23c603ec4158c08298bd4360fdea90bb5cf"}, "poison": {:hex, :poison, "3.1.0", "d9eb636610e096f86f25d9a46f35a9facac35609a7591b3be3326e99a0484665", [:mix], [], "hexpm", "fec8660eb7733ee4117b85f55799fd3833eb769a6df71ccf8903e8dc5447cfce"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, - "postgrex": {:hex, :postgrex, "0.15.9", "46f8fe6f25711aeb861c4d0ae09780facfdf3adbd2fb5594ead61504dd489bda", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "610719103e4cb2223d4ab78f9f0f3e720320eeca6011415ab4137ddef730adee"}, + "postgrex": {:hex, :postgrex, "0.16.5", "fcc4035cc90e23933c5d69a9cd686e329469446ef7abba2cf70f08e2c4b69810", [:mix], [{:connection, "~> 1.1", [hex: :connection, repo: "hexpm", optional: false]}, {:db_connection, "~> 2.1", [hex: :db_connection, repo: "hexpm", optional: false]}, {:decimal, "~> 1.5 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:table, "~> 0.1.0", [hex: :table, repo: "hexpm", optional: true]}], "hexpm", "edead639dc6e882618c01d8fc891214c481ab9a3788dfe38dd5e37fd1d5fb2e8"}, "pot": {:hex, :pot, "1.0.1", "81b511b1fa7c3123171c265cb7065a1528cebd7277b0cbc94257c50a8b2e4c17", [:rebar3], [], "hexpm", "ed87f5976531d91528452faa1138a5328db7f9f20d8feaae15f5051f79bcfb6d"}, + "prom_ex": {:hex, :prom_ex, "1.7.1", "39331ee3fe6f9a8587d8208bf9274a253bb80281700e127dd18786cda5e08c37", [:mix], [{:absinthe, ">= 1.6.0", [hex: :absinthe, repo: "hexpm", optional: true]}, {:broadway, ">= 1.0.2", [hex: :broadway, repo: "hexpm", optional: true]}, {:ecto, ">= 3.5.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:finch, "~> 0.10.2", [hex: :finch, repo: "hexpm", optional: false]}, {:jason, "~> 1.2", [hex: :jason, repo: "hexpm", optional: false]}, {:oban, ">= 2.4.0", [hex: :oban, repo: "hexpm", optional: true]}, {:phoenix, ">= 1.5.0", [hex: :phoenix, repo: "hexpm", optional: true]}, {:phoenix_live_view, ">= 0.14.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:plug, ">= 1.12.1", [hex: :plug, repo: "hexpm", optional: true]}, {:plug_cowboy, "~> 2.5.1", [hex: :plug_cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.1", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}, {:telemetry_metrics_prometheus_core, "~> 1.0.2", [hex: :telemetry_metrics_prometheus_core, repo: "hexpm", optional: false]}, {:telemetry_poller, "~> 1.0.0", [hex: :telemetry_poller, repo: "hexpm", optional: false]}], "hexpm", "4c978872b88a929833925a0f4d0561824804c671fdd04581e765509ed0a6ed08"}, "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://github.com/lanodan/prometheus.ex.git", "31f7fbe4b71b79ba27efc2a5085746c4011ceb8f", [branch: "fix/elixir-1.14"]}, @@ -121,12 +127,14 @@ "sleeplocks": {:hex, :sleeplocks, "1.1.1", "3d462a0639a6ef36cc75d6038b7393ae537ab394641beb59830a1b8271faeed3", [:rebar3], [], "hexpm", "84ee37aeff4d0d92b290fff986d6a95ac5eedf9b383fadfd1d88e9b84a1c02e1"}, "ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"}, "sweet_xml": {:hex, :sweet_xml, "0.7.2", "4729f997286811fabdd8288f8474e0840a76573051062f066c4b597e76f14f9f", [:mix], [], "hexpm", "6894e68a120f454534d99045ea3325f7740ea71260bc315f82e29731d570a6e8"}, - "swoosh": {:hex, :swoosh, "1.3.11", "34f79c57f19892b43bd2168de9ff5de478a721a26328ef59567aad4243e7a77b", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm", "f1e2a048db454f9982b9cf840f75e7399dd48be31ecc2a7dc10012a803b913af"}, + "swoosh": {:hex, :swoosh, "1.8.2", "af9a22ab2c0d20b266f61acca737fa11a121902de9466a39e91bacdce012101c", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d058ba750eafadb6c09a84a352c14c5d1eeeda6e84945fcc95785b7f3067b7db"}, "syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"}, "table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"}, - "telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"}, + "telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"}, "telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"}, - "tesla": {:hex, :tesla, "1.4.1", "ff855f1cac121e0d16281b49e8f066c4a0d89965f98864515713878cca849ac8", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "~> 4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "95f5de35922c8c4b3945bee7406f66eb680b0955232f78f5fb7e853aa1ce201a"}, + "telemetry_metrics_prometheus_core": {:hex, :telemetry_metrics_prometheus_core, "1.0.2", "c98b1c580de637bfeac00db41b9fb91fb4c3548ee3d512a8ed7299172312eaf3", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0.0", [hex: :telemetry, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "48351a0d56f80e38c997b44232b1043e0a081670d16766eee920e6254175b730"}, + "telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"}, + "tesla": {:hex, :tesla, "1.4.4", "bb89aa0c9745190930366f6a2ac612cdf2d0e4d7fff449861baa7875afd797b2", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "d5503a49f9dec1b287567ea8712d085947e247cb11b06bc54adb05bfde466457"}, "timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"}, "trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "tzdata": {:hex, :tzdata, "1.0.5", "69f1ee029a49afa04ad77801febaf69385f3d3e3d1e4b56b9469025677b89a28", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "55519aa2a99e5d2095c1e61cc74c9be69688f8ab75c27da724eb8279ff402a5a"}, diff --git a/priv/repo/migrations/20221103014611_create_oban_peers.exs b/priv/repo/migrations/20221103014611_create_oban_peers.exs new file mode 100644 index 0000000000..cb522a0565 --- /dev/null +++ b/priv/repo/migrations/20221103014611_create_oban_peers.exs @@ -0,0 +1,7 @@ +defmodule Pleroma.Repo.Migrations.CreateObanPeers do + use Ecto.Migration + + def up, do: Oban.Migrations.up(version: 11) + + def down, do: Oban.Migrations.down(version: 11) +end diff --git a/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs b/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs new file mode 100644 index 0000000000..54e2503de9 --- /dev/null +++ b/priv/repo/migrations/20221103014728_swap_primary_oban_indexes.exs @@ -0,0 +1,26 @@ +defmodule Pleroma.Repo.Migrations.SwapPrimaryObanIndexes do + use Ecto.Migration + + @disable_ddl_transaction true + @disable_migration_lock true + + def change do + create_if_not_exists( + index( + :oban_jobs, + [:state, :queue, :priority, :scheduled_at, :id], + concurrently: true, + prefix: "public" + ) + ) + + drop_if_exists( + index( + :oban_jobs, + [:queue, :state, :priority, :scheduled_at, :id], + concurrently: true, + prefix: "public" + ) + ) + end +end From e9c3be262cfa06edb768fe03e216070b37a2d384 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sun, 13 Nov 2022 14:17:41 -0500 Subject: [PATCH 05/41] Bump credo Old credo is throwing errors on my Elixir 1.13 / OTP 25 --- mix.exs | 2 +- mix.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/mix.exs b/mix.exs index 1efdc4ec96..c5aba8db9c 100644 --- a/mix.exs +++ b/mix.exs @@ -208,7 +208,7 @@ defp deps do ## dev & test {:ex_doc, "~> 0.22", only: :dev, runtime: false}, {:ex_machina, "~> 2.4", only: :test}, - {:credo, "~> 1.4", only: [:dev, :test], runtime: false}, + {:credo, "~> 1.6", only: [:dev, :test], runtime: false}, {:mock, "~> 0.3.5", only: :test}, # temporary downgrade for excoveralls, hackney until hackney max_connections bug will be fixed {:excoveralls, "0.12.3", only: :test}, diff --git a/mix.lock b/mix.lock index 8ed7adc884..d822fdbf9a 100644 --- a/mix.lock +++ b/mix.lock @@ -6,7 +6,7 @@ "bbcode_pleroma": {:hex, :bbcode_pleroma, "0.2.0", "d36f5bca6e2f62261c45be30fa9b92725c0655ad45c99025cb1c3e28e25803ef", [:mix], [{:nimble_parsec, "~> 0.5", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "19851074419a5fedb4ef49e1f01b30df504bb5dbb6d6adfc135238063bebd1c3"}, "bcrypt_elixir": {:hex, :bcrypt_elixir, "2.3.0", "6cb662d5c1b0a8858801cf20997bd006e7016aa8c52959c9ef80e0f34fb60b7a", [:make, :mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}, {:elixir_make, "~> 0.6", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "2c81d61d4f6ed0e5cf7bf27a9109b791ff216a1034b3d541327484f46dd43769"}, "benchee": {:hex, :benchee, "1.0.1", "66b211f9bfd84bd97e6d1beaddf8fc2312aaabe192f776e8931cb0c16f53a521", [:mix], [{:deep_merge, "~> 1.0", [hex: :deep_merge, repo: "hexpm", optional: false]}], "hexpm", "3ad58ae787e9c7c94dd7ceda3b587ec2c64604563e049b2a0e8baafae832addb"}, - "bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"}, + "bunt": {:hex, :bunt, "0.2.1", "e2d4792f7bc0ced7583ab54922808919518d0e57ee162901a16a1b6664ef3b14", [:mix], [], "hexpm", "a330bfb4245239787b15005e66ae6845c9cd524a288f0d141c148b02603777a5"}, "cachex": {:hex, :cachex, "3.3.0", "6f2ebb8f27491fe39121bd207c78badc499214d76c695658b19d6079beeca5c2", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "d90e5ee1dde14cef33f6b187af4335b88748b72b30c038969176cd4e6ccc31a1"}, "calendar": {:hex, :calendar, "1.0.0", "f52073a708528482ec33d0a171954ca610fe2bd28f1e871f247dc7f1565fa807", [:mix], [{:tzdata, "~> 0.5.20 or ~> 0.1.201603 or ~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "990e9581920c82912a5ee50e62ff5ef96da6b15949a2ee4734f935fdef0f0a6f"}, "captcha": {:git, "https://git.pleroma.social/pleroma/elixir-libraries/elixir-captcha.git", "e0f16822d578866e186a0974d65ad58cddc1e2ab", [ref: "e0f16822d578866e186a0974d65ad58cddc1e2ab"]}, @@ -20,7 +20,7 @@ "cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"}, "cowboy_telemetry": {:hex, :cowboy_telemetry, "0.4.0", "f239f68b588efa7707abce16a84d0d2acf3a0f50571f8bb7f56a15865aae820c", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7d98bac1ee4565d31b62d59f8823dfd8356a169e7fcbb83831b8a5397404c9de"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, - "credo": {:hex, :credo, "1.5.5", "e8f422026f553bc3bebb81c8e8bf1932f498ca03339856c7fec63d3faac8424b", [:mix], [{:bunt, "~> 0.2.0", [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", "dd8623ab7091956a855dc9f3062486add9c52d310dfd62748779c4315d8247de"}, + "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": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, From 2186e9b62b9c88812a616a7ad0d80f4b10a2deb1 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Sun, 13 Nov 2022 18:45:24 -0500 Subject: [PATCH 06/41] Tell newer Credo it's OK to exit 0 on single with clauses and piping into anonymous functions for now --- .credo.exs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.credo.exs b/.credo.exs index b85898af36..a467f2951d 100644 --- a/.credo.exs +++ b/.credo.exs @@ -83,6 +83,7 @@ # lanodan: I think PreferImplicitTry should be consistency, and the behaviour seems # inconsistent, see: https://github.com/rrrene/credo/issues/224 {Credo.Check.Readability.PreferImplicitTry, false}, + {Credo.Check.Readability.PipeIntoAnonymousFunctions, exit_status: 0}, {Credo.Check.Readability.RedundantBlankLines}, {Credo.Check.Readability.StringSigils}, {Credo.Check.Readability.TrailingBlankLine}, @@ -90,6 +91,7 @@ {Credo.Check.Readability.VariableNames}, {Credo.Check.Readability.Semicolons}, {Credo.Check.Readability.SpaceAfterCommas}, + {Credo.Check.Readability.WithSingleClause, exit_status: 0}, {Credo.Check.Refactor.DoubleBooleanNegation}, {Credo.Check.Refactor.CondStatements}, {Credo.Check.Refactor.CyclomaticComplexity}, From a69e9ae2ef943f57faf803441c25aee09a86f9ca Mon Sep 17 00:00:00 2001 From: tusooa Date: Sat, 19 Nov 2022 23:51:43 -0500 Subject: [PATCH 07/41] Flag an Object, not an Activity --- lib/pleroma/web/activity_pub/utils.ex | 15 ++++++++------- .../controllers/report_controller_test.exs | 2 +- test/pleroma/web/common_api_test.exs | 10 ++++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 57a2f53c40..dacacb83b6 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -695,8 +695,9 @@ defp build_flag_object(%{statuses: statuses}) do Enum.map(statuses || [], &build_flag_object/1) end - defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do - activity_actor = User.get_by_ap_id(data["actor"]) + defp build_flag_object(%Object{data: data}) do + actor = User.get_by_ap_id(data["actor"]) + id = data["id"] %{ "type" => "Note", @@ -706,7 +707,7 @@ defp build_flag_object(%Activity{data: %{"id" => id}, object: %{data: data}}) do "actor" => AccountView.render( "show.json", - %{user: activity_actor, skip_visibility_check: true} + %{user: actor, skip_visibility_check: true} ) } end @@ -720,12 +721,12 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do end case Activity.get_by_ap_id_with_object(id) do - %Activity{} = activity -> - build_flag_object(activity) + %Activity{object: object} = _ -> + build_flag_object(object) nil -> - if activity = Activity.get_by_object_ap_id_with_object(id) do - build_flag_object(activity) + if %Object{} = object = Object.get_by_ap_id(id) do + build_flag_object(object) else %{"id" => id, "deleted" => true} end diff --git a/test/pleroma/web/admin_api/controllers/report_controller_test.exs b/test/pleroma/web/admin_api/controllers/report_controller_test.exs index 164cbb95b2..6fd3fbe5a1 100644 --- a/test/pleroma/web/admin_api/controllers/report_controller_test.exs +++ b/test/pleroma/web/admin_api/controllers/report_controller_test.exs @@ -76,7 +76,7 @@ test "renders reported content even if the status is deleted", %{conn: conn} do assert response["id"] == report_id assert [status] = response["statuses"] - assert activity.data["id"] == status["uri"] + assert activity.object.data["id"] == status["uri"] assert activity.object.data["content"] == status["content"] end diff --git a/test/pleroma/web/common_api_test.exs b/test/pleroma/web/common_api_test.exs index 4dc0d9cbef..9d52bd93ef 100644 --- a/test/pleroma/web/common_api_test.exs +++ b/test/pleroma/web/common_api_test.exs @@ -1100,10 +1100,11 @@ test "creates a report" do target_user = insert(:user) {:ok, activity} = CommonAPI.post(target_user, %{status: "foobar"}) + activity = Activity.normalize(activity) reporter_ap_id = reporter.ap_id target_ap_id = target_user.ap_id - activity_ap_id = activity.data["id"] + reported_object_ap_id = activity.object.data["id"] comment = "foobar" report_data = %{ @@ -1114,7 +1115,7 @@ test "creates a report" do note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => reported_object_ap_id, "content" => "foobar", "published" => activity.object.data["published"], "actor" => AccountView.render("show.json", %{user: target_user}) @@ -1136,6 +1137,7 @@ test "creates a report" do test "updates report state" do [reporter, target_user] = insert_pair(:user) activity = insert(:note_activity, user: target_user) + object = Object.normalize(activity) {:ok, %Activity{id: report_id}} = CommonAPI.report(reporter, %{ @@ -1148,10 +1150,10 @@ test "updates report state" do assert report.data["state"] == "resolved" - [reported_user, activity_id] = report.data["object"] + [reported_user, object_id] = report.data["object"] assert reported_user == target_user.ap_id - assert activity_id == activity.data["id"] + assert object_id == object.data["id"] end test "updates report state, don't strip when report_strip_status is false" do From 0e0c316c76527fb5ac3a28f03628e62799e8694b Mon Sep 17 00:00:00 2001 From: tusooa Date: Sun, 20 Nov 2022 00:35:52 -0500 Subject: [PATCH 08/41] Fix report api --- lib/pleroma/web/activity_pub/utils.ex | 5 +++ lib/pleroma/web/admin_api/report.ex | 6 ++- .../controllers/report_controller_test.exs | 37 +++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index dacacb83b6..22057e703a 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -695,6 +695,11 @@ defp build_flag_object(%{statuses: statuses}) do Enum.map(statuses || [], &build_flag_object/1) end + defp build_flag_object(%Activity{} = activity) do + object = Object.normalize(activity, fetch: false) + build_flag_object(object) + end + defp build_flag_object(%Object{data: data}) do actor = User.get_by_ap_id(data["actor"]) id = data["id"] diff --git a/lib/pleroma/web/admin_api/report.ex b/lib/pleroma/web/admin_api/report.ex index 6856bfcb3f..c79bee27e4 100644 --- a/lib/pleroma/web/admin_api/report.ex +++ b/lib/pleroma/web/admin_api/report.ex @@ -18,10 +18,12 @@ def extract_report_info( |> Enum.reject(&is_nil(&1)) |> Enum.map(fn act when is_map(act) -> - Activity.get_by_ap_id_with_object(act["id"]) || make_fake_activity(act, user) + Activity.get_create_by_object_ap_id_with_object(act["id"]) || + Activity.get_by_ap_id_with_object(act["id"]) || make_fake_activity(act, user) act when is_binary(act) -> - Activity.get_by_ap_id_with_object(act) + Activity.get_create_by_object_ap_id_with_object(act) || + Activity.get_by_ap_id_with_object(act) end) %{report: report, user: user, account: account, statuses: statuses} diff --git a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs index 6d1a63334a..c7aa761225 100644 --- a/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/report_controller_test.exs @@ -5,6 +5,8 @@ defmodule Pleroma.Web.MastodonAPI.ReportControllerTest do use Pleroma.Web.ConnCase, async: true + alias Pleroma.Activity + alias Pleroma.Repo alias Pleroma.Web.CommonAPI import Pleroma.Factory @@ -27,6 +29,41 @@ test "submit a basic report", %{conn: conn, target_user: target_user} do |> json_response_and_validate_schema(200) end + test "submit a report with a fake Create", %{ + conn: conn + } do + target_user = insert(:user) + + note = insert(:note, user: target_user) + + activity_params = %{ + "object" => note.data["id"], + "actor" => note.data["actor"], + "to" => note.data["to"] || [], + "cc" => note.data["cc"] || [], + "type" => "Create" + } + + {:ok, fake_activity} = + Repo.insert(%Activity{ + data: activity_params, + recipients: activity_params["to"] ++ activity_params["cc"], + local: true, + actor: activity_params["actor"] + }) + + assert %{"action_taken" => false, "id" => _} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/reports", %{ + "account_id" => target_user.id, + "status_ids" => [fake_activity.id], + "comment" => "bad status!", + "forward" => "false" + }) + |> json_response_and_validate_schema(200) + end + test "submit a report with statuses and comment", %{ conn: conn, target_user: target_user, From 9d99e76a3ae7c1af8b6b03bf88534f3959b62544 Mon Sep 17 00:00:00 2001 From: tusooa Date: Sun, 20 Nov 2022 00:57:04 -0500 Subject: [PATCH 09/41] Fix unit tests --- lib/pleroma/web/activity_pub/utils.ex | 44 ++++++++++++------- .../web/activity_pub/activity_pub_test.exs | 10 +++-- .../web/activity_pub/transmogrifier_test.exs | 2 +- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex index 22057e703a..b898d6fe82 100644 --- a/lib/pleroma/web/activity_pub/utils.ex +++ b/lib/pleroma/web/activity_pub/utils.ex @@ -697,24 +697,22 @@ defp build_flag_object(%{statuses: statuses}) do defp build_flag_object(%Activity{} = activity) do object = Object.normalize(activity, fetch: false) - build_flag_object(object) + + # Do not allow people to report Creates. Instead, report the Object that is Created. + if activity.data["type"] != "Create" do + build_flag_object_with_actor_and_id( + object, + User.get_by_ap_id(activity.data["actor"]), + activity.data["id"] + ) + else + build_flag_object(object) + end end - defp build_flag_object(%Object{data: data}) do - actor = User.get_by_ap_id(data["actor"]) - id = data["id"] - - %{ - "type" => "Note", - "id" => id, - "content" => data["content"], - "published" => data["published"], - "actor" => - AccountView.render( - "show.json", - %{user: actor, skip_visibility_check: true} - ) - } + defp build_flag_object(%Object{} = object) do + actor = User.get_by_ap_id(object.data["actor"]) + build_flag_object_with_actor_and_id(object, actor, object.data["id"]) end defp build_flag_object(act) when is_map(act) or is_binary(act) do @@ -740,6 +738,20 @@ defp build_flag_object(act) when is_map(act) or is_binary(act) do defp build_flag_object(_), do: [] + defp build_flag_object_with_actor_and_id(%Object{data: data}, actor, id) do + %{ + "type" => "Note", + "id" => id, + "content" => data["content"], + "published" => data["published"], + "actor" => + AccountView.render( + "show.json", + %{user: actor, skip_visibility_check: true} + ) + } + end + #### Report-related helpers def get_reports(params, page, page_size) do params = diff --git a/test/pleroma/web/activity_pub/activity_pub_test.exs b/test/pleroma/web/activity_pub/activity_pub_test.exs index 13f3d93b8a..fc6fc039da 100644 --- a/test/pleroma/web/activity_pub/activity_pub_test.exs +++ b/test/pleroma/web/activity_pub/activity_pub_test.exs @@ -1504,6 +1504,7 @@ test "it filters broken threads" do reporter_ap_id = reporter.ap_id target_ap_id = target_account.ap_id activity_ap_id = activity.data["id"] + object_ap_id = activity.object.data["id"] activity_with_object = Activity.get_by_ap_id_with_object(activity_ap_id) @@ -1515,6 +1516,7 @@ test "it filters broken threads" do reported_activity: activity, content: content, activity_ap_id: activity_ap_id, + object_ap_id: object_ap_id, activity_with_object: activity_with_object, reporter_ap_id: reporter_ap_id, target_ap_id: target_ap_id @@ -1528,7 +1530,7 @@ test "it can create a Flag activity", target_account: target_account, reported_activity: reported_activity, content: content, - activity_ap_id: activity_ap_id, + object_ap_id: object_ap_id, activity_with_object: activity_with_object, reporter_ap_id: reporter_ap_id, target_ap_id: target_ap_id @@ -1544,7 +1546,7 @@ test "it can create a Flag activity", note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => object_ap_id, "content" => content, "published" => activity_with_object.object.data["published"], "actor" => @@ -1568,6 +1570,7 @@ test "it can create a Flag activity", context: context, target_account: target_account, reported_activity: reported_activity, + object_ap_id: object_ap_id, content: content }, Utils, @@ -1582,8 +1585,7 @@ test "it can create a Flag activity", content: content }) - new_data = - put_in(activity.data, ["object"], [target_account.ap_id, reported_activity.data["id"]]) + new_data = put_in(activity.data, ["object"], [target_account.ap_id, object_ap_id]) assert_called(Utils.maybe_federate(%{activity | data: new_data})) end diff --git a/test/pleroma/web/activity_pub/transmogrifier_test.exs b/test/pleroma/web/activity_pub/transmogrifier_test.exs index 273f2611d3..6b4636d227 100644 --- a/test/pleroma/web/activity_pub/transmogrifier_test.exs +++ b/test/pleroma/web/activity_pub/transmogrifier_test.exs @@ -61,7 +61,7 @@ test "it accepts Flag activities" do note_obj = %{ "type" => "Note", - "id" => activity.data["id"], + "id" => activity.object.data["id"], "content" => "test post", "published" => object.data["published"], "actor" => AccountView.render("show.json", %{user: user, skip_visibility_check: true}) From afe4bb2307147a160a2024f75679c97fea0cd7d1 Mon Sep 17 00:00:00 2001 From: tusooa Date: Sun, 20 Nov 2022 01:06:21 -0500 Subject: [PATCH 10/41] Fix UtilsTest --- test/pleroma/web/activity_pub/utils_test.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index e428938495..365f03010b 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -473,7 +473,7 @@ test "returns map with Flag object" do content = "foobar" target_ap_id = target_account.ap_id - activity_ap_id = activity.data["id"] + object_ap_id = activity.object.data["id"] res = Utils.make_flag_data( @@ -489,7 +489,7 @@ test "returns map with Flag object" do note_obj = %{ "type" => "Note", - "id" => activity_ap_id, + "id" => object_ap_id, "content" => content, "published" => activity.object.data["published"], "actor" => From 8f3e750530874df2a92d131e256e94dcc77260f1 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 27 Nov 2022 03:40:21 +0100 Subject: [PATCH 11/41] scrubbers: Scrub img class attribute Closes: https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3790 --- priv/scrubbers/default.ex | 3 ++- priv/scrubbers/twitter_text.ex | 3 ++- test/pleroma/html_test.exs | 26 ++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/priv/scrubbers/default.ex b/priv/scrubbers/default.ex index 79fa6dcdf2..e10e3ec87d 100644 --- a/priv/scrubbers/default.ex +++ b/priv/scrubbers/default.ex @@ -68,13 +68,14 @@ defmodule Pleroma.HTML.Scrubber.Default do @allow_inline_images Pleroma.Config.get([:markup, :allow_inline_images]) if @allow_inline_images do + Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"]) + # restrict img tags to http/https only, because of MediaProxy. Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"]) Meta.allow_tag_with_these_attributes(:img, [ "width", "height", - "class", "title", "alt" ]) diff --git a/priv/scrubbers/twitter_text.ex b/priv/scrubbers/twitter_text.ex index a121a82094..6e23b3efbe 100644 --- a/priv/scrubbers/twitter_text.ex +++ b/priv/scrubbers/twitter_text.ex @@ -45,13 +45,14 @@ defmodule Pleroma.HTML.Scrubber.TwitterText do # allow inline images for custom emoji if Pleroma.Config.get([:markup, :allow_inline_images]) do + Meta.allow_tag_with_this_attribute_values(:img, "class", ["emoji"]) + # restrict img tags to http/https only, because of MediaProxy. Meta.allow_tag_with_uri_attributes(:img, ["src"], ["http", "https"]) Meta.allow_tag_with_these_attributes(:img, [ "width", "height", - "class", "title", "alt" ]) diff --git a/test/pleroma/html_test.exs b/test/pleroma/html_test.exs index 970baf63b9..b99689903e 100644 --- a/test/pleroma/html_test.exs +++ b/test/pleroma/html_test.exs @@ -17,6 +17,7 @@ defmodule Pleroma.HTMLTest do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
""" @@ -24,6 +25,10 @@ defmodule Pleroma.HTMLTest do """ + @html_stillimage_sample """ + + """ + @html_span_class_sample """ hi """ @@ -45,6 +50,7 @@ test "works as expected" do this is a link with allowed "rel" attribute: example.com this is a link with not allowed "rel" attribute: example.com this is an image: + this is an inline emoji: alert('hacked') """ @@ -67,6 +73,7 @@ test "normalizes HTML as expected" do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
alert('hacked') """ @@ -90,6 +97,15 @@ test "does not allow spans with invalid classes" do HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.TwitterText) end + test "does not allow images with invalid classes" do + expected = """ + + """ + + assert expected == + HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText) + end + test "does allow microformats" do expected = """ @foo @@ -121,6 +137,7 @@ test "normalizes HTML as expected" do this is a link with allowed "rel" attribute: this is a link with not allowed "rel" attribute: example.com this is an image:
+ this is an inline emoji:
alert('hacked') """ @@ -143,6 +160,15 @@ test "does not allow spans with invalid classes" do assert expected == HTML.filter_tags(@html_span_class_sample, Pleroma.HTML.Scrubber.Default) end + test "does not allow images with invalid classes" do + expected = """ + + """ + + assert expected == + HTML.filter_tags(@html_stillimage_sample, Pleroma.HTML.Scrubber.TwitterText) + end + test "does allow microformats" do expected = """ @foo From f531099d2d504159de4695426339a1cd0ca7bb8d Mon Sep 17 00:00:00 2001 From: Jeremy Huffman Date: Sun, 27 Nov 2022 03:12:34 +0000 Subject: [PATCH 12/41] Skip two unicode/kanji tests that can't pass on Mac. --- test/pleroma/activity_test.exs | 1 + .../web/mastodon_api/controllers/search_controller_test.exs | 1 + 2 files changed, 2 insertions(+) diff --git a/test/pleroma/activity_test.exs b/test/pleroma/activity_test.exs index e38384c9c8..a48a688379 100644 --- a/test/pleroma/activity_test.exs +++ b/test/pleroma/activity_test.exs @@ -145,6 +145,7 @@ test "when association is not loaded" do setup do: clear_config([:instance, :limit_to_local_content]) + @tag :skip_on_mac test "finds utf8 text in statuses", %{ japanese_activity: japanese_activity, user: user diff --git a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs index 9a5d88109c..0a9240b70f 100644 --- a/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/search_controller_test.exs @@ -37,6 +37,7 @@ test "it returns empty result if user or status search return undefined error", end end + @tag :skip_on_mac test "search", %{conn: conn} do user = insert(:user) user_two = insert(:user, %{nickname: "shp@shitposter.club"}) From f6d55e1e7774492bb5b86b7d9bbc05ae9475eb4c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 27 Nov 2022 04:05:45 +0100 Subject: [PATCH 13/41] Mergeback of release 2.4.5 --- CHANGELOG.md | 14 ++++++++++++++ mix.exs | 2 +- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e95bda1452..ec34ec91e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,20 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed - Quack, the logging backend that pushes to Slack channels +## 2.4.5 - 2022-08-xx + +## Fixed +- Image `class` attributes not being scrubbed, allowing to exploit frontend special classes [!3792](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3792) +- Delete report notifs when demoting from superuser [!3642](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3642) +- Validate `mediaType` only by it's format rather than using a list [!3597](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3597) +- Pagination: Make mutes and blocks lists behave the same as other lists [!3693](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3693) +- Compatibility with Elixir 1.14 [!3740](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3740) +- Frontend installer: FediFE build URL [!3736](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3736) +- Streaming: Don't stream ChatMessage into the home timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738) +- Streaming: Stream local-only posts in the local timeline [!3738](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3738) +- Signatures: Fix `keyId` lookup for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725) +- Validator: Fix `replies` handling for GoToSocial [!3725](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3725) + ## 2.4.4 - 2022-08-19 ### Security diff --git a/mix.exs b/mix.exs index 26a9b28269..eb635cac99 100644 --- a/mix.exs +++ b/mix.exs @@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do def project do [ app: :pleroma, - version: version("2.4.53"), + version: version("2.4.55"), elixir: "~> 1.10", elixirc_paths: elixirc_paths(Mix.env()), compilers: [:phoenix, :gettext] ++ Mix.compilers(), From d6cd447cfa81cd5462ef81c0da1a0c05d14daf4c Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Sun, 27 Nov 2022 22:28:48 +0100 Subject: [PATCH 14/41] CHANGELOG.md: Fix date for 2.4.5 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ec34ec91e1..a3cff84a1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,7 +63,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Removed - Quack, the logging backend that pushes to Slack channels -## 2.4.5 - 2022-08-xx +## 2.4.5 - 2022-08-27 ## Fixed - Image `class` attributes not being scrubbed, allowing to exploit frontend special classes [!3792](https://git.pleroma.social/pleroma/pleroma/-/merge_requests/3792) From 0f88c2bca437b7d2fa6d6320aae8b8bbe4e5d6c4 Mon Sep 17 00:00:00 2001 From: ave Date: Mon, 28 Nov 2022 00:13:34 +0000 Subject: [PATCH 15/41] Change follow_operation schema to use type BooleanLike --- .../api_spec/operations/account_operation.ex | 4 +- .../controllers/account_controller_test.exs | 40 +++++++++++++------ 2 files changed, 29 insertions(+), 15 deletions(-) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index aed59293c8..012cbdc796 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -223,12 +223,12 @@ def follow_operation do type: :object, properties: %{ reblogs: %Schema{ - type: :boolean, + allOf: [BooleanLike], description: "Receive this account's reblogs in home timeline? Defaults to true.", default: true }, notify: %Schema{ - type: :boolean, + allOf: [BooleanLike], description: "Receive notifications for all statuses posted by the account? Defaults to false.", default: false diff --git a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs index 2bf4edb70f..958b7f76f9 100644 --- a/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs +++ b/test/pleroma/web/mastodon_api/controllers/account_controller_test.exs @@ -896,6 +896,12 @@ test "following without reblogs" do |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: true}) |> json_response_and_validate_schema(200) + assert %{"showing_reblogs" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "1"}) + |> json_response_and_validate_schema(200) + assert [%{"id" => ^reblog_id}] = conn |> get("/api/v1/timelines/home") @@ -925,6 +931,12 @@ test "following with reblogs" do |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: false}) |> json_response_and_validate_schema(200) + assert %{"showing_reblogs" => false} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{reblogs: "0"}) + |> json_response_and_validate_schema(200) + assert [] == conn |> get("/api/v1/timelines/home") @@ -935,21 +947,23 @@ test "following with subscription and unsubscribing" do %{conn: conn} = oauth_access(["follow"]) followed = insert(:user) - ret_conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true}) + assert %{"subscribing" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: true}) + |> json_response_and_validate_schema(200) - assert %{"id" => _id, "subscribing" => true} = - json_response_and_validate_schema(ret_conn, 200) + assert %{"subscribing" => true} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: "1"}) + |> json_response_and_validate_schema(200) - ret_conn = - conn - |> put_req_header("content-type", "application/json") - |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false}) - - assert %{"id" => _id, "subscribing" => false} = - json_response_and_validate_schema(ret_conn, 200) + assert %{"subscribing" => false} = + conn + |> put_req_header("content-type", "application/json") + |> post("/api/v1/accounts/#{followed.id}/follow", %{notify: false}) + |> json_response_and_validate_schema(200) end test "following / unfollowing errors", %{user: user, conn: conn} do From 1eb3ce956b35871aa472b52e67eeae27cb91d7b0 Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Mon, 28 Nov 2022 22:07:45 +0100 Subject: [PATCH 16/41] =?UTF-8?q?Add=20Gitlab=20Release=E2=84=A2=20into=20?= =?UTF-8?q?Release=20MR=20template?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitlab/merge_request_templates/Release.md | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.gitlab/merge_request_templates/Release.md b/.gitlab/merge_request_templates/Release.md index b2c772696f..9638d6d11c 100644 --- a/.gitlab/merge_request_templates/Release.md +++ b/.gitlab/merge_request_templates/Release.md @@ -1,6 +1,8 @@ ### Release checklist -* [ ] Bump version in `mix.exs` -* [ ] Compile a changelog -* [ ] Create an MR with an announcement to pleroma.social -* [ ] Tag the release +* [ ] Bump version in `mix.exs` +* [ ] Compile a changelog +* [ ] Create an MR with an announcement to pleroma.social +#### post-merge +* [ ] Tag the release on the merge commit +* [ ] Make the tag into a Gitlab Release™ * [ ] Merge `stable` into `develop` (in case the fixes are already in develop, use `git merge -s ours --no-commit` and manually merge the changelogs) From 3e8f49be674f50250d07b24c6a0f475f786d4d7b Mon Sep 17 00:00:00 2001 From: Xnuk Shuman Date: Thu, 1 Dec 2022 17:17:03 +0000 Subject: [PATCH 17/41] Added translation using Weblate (Korean) --- priv/gettext/ko/LC_MESSAGES/default.po | 197 +++++++++++++++++++++++++ 1 file changed, 197 insertions(+) create mode 100644 priv/gettext/ko/LC_MESSAGES/default.po diff --git a/priv/gettext/ko/LC_MESSAGES/default.po b/priv/gettext/ko/LC_MESSAGES/default.po new file mode 100644 index 0000000000..55b695d6b8 --- /dev/null +++ b/priv/gettext/ko/LC_MESSAGES/default.po @@ -0,0 +1,197 @@ +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-12-01 19:17+0300\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Translate Toolkit 3.7.2\n" + +## This file is a PO Template file. +## +## "msgid"s here are often extracted from source code. +## Add new translations manually only if they're dynamic +## translations that can't be statically extracted. +## +## Run "mix gettext.extract" to bring this file up to +## date. Leave "msgstr"s empty as changing them here as no +## effect: edit them in PO (.po) files instead. + +#: lib/pleroma/web/api_spec/render_error.ex:122 +#, elixir-autogen, elixir-format +msgid "%{name} - %{count} is not a multiple of %{multiple}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:131 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than exclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:140 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is larger than inclusive maximum %{max}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:149 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than exclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:158 +#, elixir-autogen, elixir-format +msgid "%{name} - %{value} is smaller than inclusive minimum %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:102 +#, elixir-autogen, elixir-format +msgid "%{name} - Array items must be unique." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:114 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is larger than maxItems: %{}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:106 +#, elixir-autogen, elixir-format +msgid "%{name} - Array length %{length} is smaller than minItems: %{min}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:166 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid %{type}. Got: %{value}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:174 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid format. Expected %{format}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:51 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid schema.type. Got: %{type}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:178 +#, elixir-autogen, elixir-format +msgid "%{name} - Invalid value for enum." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:95 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is larger than maxLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:88 +#, elixir-autogen, elixir-format +msgid "%{name} - String length is smaller than minLength: %{length}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:63 +#, elixir-autogen, elixir-format +msgid "%{name} - null value where %{type} expected." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:60 +#, elixir-autogen, elixir-format +msgid "%{name} - null value." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:182 +#, elixir-autogen, elixir-format +msgid "Failed to cast to any schema in %{polymorphic_type}" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:71 +#, elixir-autogen, elixir-format +msgid "Failed to cast value as %{invalid_schema}. Value must be castable using `allOf` schemas listed." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:84 +#, elixir-autogen, elixir-format +msgid "Failed to cast value to one of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:78 +#, elixir-autogen, elixir-format +msgid "Failed to cast value using any of: %{failed_schemas}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:212 +#, elixir-autogen, elixir-format +msgid "Invalid value for header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:204 +#, elixir-autogen, elixir-format +msgid "Missing field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:208 +#, elixir-autogen, elixir-format +msgid "Missing header: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:196 +#, elixir-autogen, elixir-format +msgid "No value provided for required discriminator `%{field}`." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:216 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is greater than maxProperties: %{max_properties}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:224 +#, elixir-autogen, elixir-format +msgid "Object property count %{property_count} is less than minProperties: %{min_properties}" +msgstr "" + +#: lib/pleroma/web/templates/static_fe/static_fe/error.html.eex:2 +#, elixir-autogen, elixir-format +msgid "Oops" +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:188 +#, elixir-autogen, elixir-format +msgid "Unexpected field: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:200 +#, elixir-autogen, elixir-format +msgid "Unknown schema: %{name}." +msgstr "" + +#: lib/pleroma/web/api_spec/render_error.ex:192 +#, elixir-autogen, elixir-format +msgid "Value used as discriminator for `%{field}` matches no schemas." +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:43 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:37 +#, elixir-autogen, elixir-format +msgid "announces" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:44 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:38 +#, elixir-autogen, elixir-format +msgid "likes" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:42 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:36 +#, elixir-autogen, elixir-format +msgid "replies" +msgstr "" + +#: lib/pleroma/web/templates/embed/show.html.eex:27 +#: lib/pleroma/web/templates/static_fe/static_fe/_notice.html.eex:22 +#, elixir-autogen, elixir-format +msgid "sensitive media" +msgstr "" From b6e96f63b4fdc231d09d3cefde23286d8764bfbd Mon Sep 17 00:00:00 2001 From: "Haelwenn (lanodan) Monnier" Date: Tue, 6 Dec 2022 00:08:55 +0100 Subject: [PATCH 18/41] CI: Tag amd64 releases for amd64 runners --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 329904bbe0..92ea3f494c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -260,6 +260,8 @@ amd64: - develop@pleroma/pleroma - /^maint/.*$/@pleroma/pleroma - /^release/.*$/@pleroma/pleroma + tags: + - amd64 artifacts: &release-artifacts name: "pleroma-$CI_COMMIT_REF_NAME-$CI_COMMIT_SHORT_SHA-$CI_JOB_NAME" paths: @@ -292,6 +294,8 @@ amd64-musl: stage: release artifacts: *release-artifacts only: *release-only + tags: + - amd64 image: elixir:1.10.4-alpine cache: *release-cache variables: *release-variables From 8afad1e46ebdef3a4b4b74ea4d96121c6b3684a1 Mon Sep 17 00:00:00 2001 From: jrabbit Date: Tue, 6 Dec 2022 17:24:04 +0000 Subject: [PATCH 19/41] reccomend tagged releases over pulling stable --- docs/administration/updating.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/administration/updating.md b/docs/administration/updating.md index 01d3b9b0ef..00eca36a04 100644 --- a/docs/administration/updating.md +++ b/docs/administration/updating.md @@ -17,7 +17,7 @@ su pleroma -s $SHELL -lc "./bin/pleroma_ctl migrate" ## For from source installations (using git) 1. Go to the working directory of Pleroma (default is `/opt/pleroma`) -2. Run `git pull` [^1]. This pulls the latest changes from upstream. +2. Run `git checkout ` [^1]. e.g. `git checkout v2.4.5` This pulls the [tagged release](https://git.pleroma.social/pleroma/pleroma/-/releases) from upstream. 3. Run `mix deps.get` [^1]. This pulls in any new dependencies. 4. Stop the Pleroma service. 5. Run `mix ecto.migrate` [^1] [^2]. This task performs database migrations, if there were any. From da0c6843447215fadf831c673b40f7c6035c1a15 Mon Sep 17 00:00:00 2001 From: tusooa Date: Thu, 8 Dec 2022 20:51:08 -0500 Subject: [PATCH 20/41] Add tests for flagging non-Create activities --- test/pleroma/web/activity_pub/utils_test.exs | 43 ++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/test/pleroma/web/activity_pub/utils_test.exs b/test/pleroma/web/activity_pub/utils_test.exs index 365f03010b..e7d1e01c43 100644 --- a/test/pleroma/web/activity_pub/utils_test.exs +++ b/test/pleroma/web/activity_pub/utils_test.exs @@ -504,6 +504,49 @@ test "returns map with Flag object" do "state" => "open" } = res end + + test "returns map with Flag object with a non-Create Activity" do + reporter = insert(:user) + posting_account = insert(:user) + target_account = insert(:user) + + {:ok, activity} = CommonAPI.post(posting_account, %{status: "foobar"}) + {:ok, like} = CommonAPI.favorite(target_account, activity.id) + context = Utils.generate_context_id() + content = "foobar" + + target_ap_id = target_account.ap_id + object_ap_id = activity.object.data["id"] + + res = + Utils.make_flag_data( + %{ + actor: reporter, + context: context, + account: target_account, + statuses: [%{"id" => like.data["id"]}], + content: content + }, + %{} + ) + + note_obj = %{ + "type" => "Note", + "id" => object_ap_id, + "content" => content, + "published" => activity.object.data["published"], + "actor" => + AccountView.render("show.json", %{user: posting_account, skip_visibility_check: true}) + } + + assert %{ + "type" => "Flag", + "content" => ^content, + "context" => ^context, + "object" => [^target_ap_id, ^note_obj], + "state" => "open" + } = res + end end describe "add_announce_to_object/2" do From 452595baeda8327b862d03e450ac004679efe86e Mon Sep 17 00:00:00 2001 From: duponin Date: Sun, 11 Dec 2022 22:54:47 +0100 Subject: [PATCH 21/41] Uploading an avatar media exceeding max size returns a 413 Until now it was returning a 500 because the upload plug were going through the changeset and ending in the JSON encoder, which raised because struct has to @derive the encoder. --- lib/pleroma/user.ex | 8 +++++- .../api_spec/operations/account_operation.ex | 3 +- .../controllers/account_controller.ex | 6 +++- .../mastodon_api/update_credentials_test.exs | 28 +++++++++++++++++++ 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b422e5c1db..17f6b9a0d8 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -611,7 +611,13 @@ defp put_change_if_present(changeset, map_field, value_function) do {:ok, new_value} <- value_function.(value) do put_change(changeset, map_field, new_value) else - _ -> changeset + {:error, :file_too_large} -> + Ecto.Changeset.validate_change(changeset, map_field, fn map_field, _value -> + [{map_field, "file is too large"}] + end) + + _ -> + changeset end end diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 012cbdc796..aabe988f7e 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -64,7 +64,8 @@ def update_credentials_operation do requestBody: request_body("Parameters", update_credentials_request(), required: true), responses: %{ 200 => Operation.response("Account", "application/json", Account), - 403 => Operation.response("Error", "application/json", ApiError) + 403 => Operation.response("Error", "application/json", ApiError), + 413 => Operation.response("Error", "application/json", ApiError) } } end diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 7c24c35d21..656a861cdd 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -254,7 +254,11 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p with_pleroma_settings: true ) else - _e -> render_error(conn, :forbidden, "Invalid request") + {:error, %Ecto.Changeset{errors: [avatar: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + + _e -> + render_error(conn, :forbidden, "Invalid request") end end diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index f5211a60e8..57bca897c0 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -259,6 +259,34 @@ test "updates the user's avatar", %{user: user, conn: conn} do assert user.avatar == nil end + test "updates the user's avatar, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_avatar_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + assert user.avatar == %{} + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{"avatar" => new_avatar_oversized}) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user_response["avatar"] != User.avatar_url(user) + + user = User.get_by_id(user.id) + assert user.avatar == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "updates the user's banner", %{user: user, conn: conn} do new_header = %Plug.Upload{ content_type: "image/jpeg", From 987674235814205344d320c0e4c21df17b1cdd15 Mon Sep 17 00:00:00 2001 From: duponin Date: Sun, 11 Dec 2022 23:15:08 +0100 Subject: [PATCH 22/41] Return 413 when an actor's banner or background exceeds the size limit --- .../controllers/account_controller.ex | 6 +++ .../mastodon_api/update_credentials_test.exs | 54 +++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 656a861cdd..ea6e593d93 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -257,6 +257,12 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p {:error, %Ecto.Changeset{errors: [avatar: {"file is too large", _}]}} -> render_error(conn, :request_entity_too_large, "File is too large") + {:error, %Ecto.Changeset{errors: [banner: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + + {:error, %Ecto.Changeset{errors: [background: {"file is too large", _}]}} -> + render_error(conn, :request_entity_too_large, "File is too large") + _e -> render_error(conn, :forbidden, "Invalid request") end diff --git a/test/pleroma/web/mastodon_api/update_credentials_test.exs b/test/pleroma/web/mastodon_api/update_credentials_test.exs index 57bca897c0..d5fac7e253 100644 --- a/test/pleroma/web/mastodon_api/update_credentials_test.exs +++ b/test/pleroma/web/mastodon_api/update_credentials_test.exs @@ -306,6 +306,32 @@ test "updates the user's banner", %{user: user, conn: conn} do assert user.banner == nil end + test "updates the user's banner, upload_limit, returns a HTTP 413", %{conn: conn, user: user} do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_header_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{"header" => new_header_oversized}) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user_response["header"] != User.banner_url(user) + + user = User.get_by_id(user.id) + assert user.banner == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "updates the user's background", %{conn: conn, user: user} do new_header = %Plug.Upload{ content_type: "image/jpeg", @@ -329,6 +355,34 @@ test "updates the user's background", %{conn: conn, user: user} do assert user.background == nil end + test "updates the user's background, upload_limit, returns a HTTP 413", %{ + conn: conn, + user: user + } do + upload_limit = Config.get([:instance, :upload_limit]) * 8 + 8 + + assert :ok == + File.write(Path.absname("test/tmp/large_binary.data"), <<0::size(upload_limit)>>) + + new_background_oversized = %Plug.Upload{ + content_type: nil, + path: Path.absname("test/tmp/large_binary.data"), + filename: "large_binary.data" + } + + res = + patch(conn, "/api/v1/accounts/update_credentials", %{ + "pleroma_background_image" => new_background_oversized + }) + + assert user_response = json_response_and_validate_schema(res, 413) + assert user.background == %{} + + clear_config([:instance, :upload_limit], upload_limit) + + assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) + end + test "requires 'write:accounts' permission" do token1 = insert(:oauth_token, scopes: ["read"]) token2 = insert(:oauth_token, scopes: ["write", "follow"]) From 62c27e016441d8f0649fea0ea9cfe0646e2b6f11 Mon Sep 17 00:00:00 2001 From: tusooa Date: Wed, 14 Dec 2022 01:04:42 -0500 Subject: [PATCH 23/41] Fix failure when registering a user with no email when approval required --- lib/pleroma/user.ex | 6 +++++- test/pleroma/user_test.exs | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index b422e5c1db..d2ae088884 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -905,7 +905,7 @@ def post_register_action(%User{is_approved: true, is_confirmed: true} = user) do end end - defp send_user_approval_email(user) do + defp send_user_approval_email(%User{email: email} = user) when is_binary(email) do user |> Pleroma.Emails.UserEmail.approval_pending_email() |> Pleroma.Emails.Mailer.deliver_async() @@ -913,6 +913,10 @@ defp send_user_approval_email(user) do {:ok, :enqueued} end + defp send_user_approval_email(_user) do + {:ok, :skipped} + end + defp send_admin_approval_emails(user) do all_superusers() |> Enum.filter(fn user -> not is_nil(user.email) end) diff --git a/test/pleroma/user_test.exs b/test/pleroma/user_test.exs index 303598fad8..a58c8f68b6 100644 --- a/test/pleroma/user_test.exs +++ b/test/pleroma/user_test.exs @@ -591,6 +591,21 @@ test "it fails gracefully with invalid email config" do refute_email_sent() end + test "it works when the registering user does not provide an email" do + clear_config([Pleroma.Emails.Mailer, :enabled], false) + clear_config([:instance, :account_activation_required], false) + clear_config([:instance, :account_approval_required], true) + + cng = User.register_changeset(%User{}, @full_user_data |> Map.put(:email, "")) + + # The user is still created + assert {:ok, %User{nickname: "nick"}} = User.register(cng) + + # No emails are sent + ObanHelpers.perform_all() + refute_email_sent() + end + test "it requires an email, name, nickname and password, bio is optional when account_activation_required is enabled" do clear_config([:instance, :account_activation_required], true) From dc7efcd08b822e84e893775084d3b35288462264 Mon Sep 17 00:00:00 2001 From: tusooa Date: Thu, 15 Dec 2022 11:08:24 -0500 Subject: [PATCH 24/41] Make TagPolicy Update-aware This is inspired by https://akkoma.dev/AkkomaGang/akkoma/commit/d5828f1c5e54ca236e50ef7837bfba3d1e665854 --- .../web/activity_pub/mrf/tag_policy.ex | 10 +++--- .../web/activity_pub/mrf/tag_policy_test.exs | 36 +++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex index 10072b693e..73760ca8f2 100644 --- a/lib/pleroma/web/activity_pub/mrf/tag_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/tag_policy.ex @@ -27,22 +27,22 @@ defp get_tags(_), do: [] defp process_tag( "mrf_tag:media-force-nsfw", %{ - "type" => "Create", + "type" => type, "object" => %{"attachment" => child_attachment} } = message ) - when length(child_attachment) > 0 do + when length(child_attachment) > 0 and type in ["Create", "Update"] do {:ok, Kernel.put_in(message, ["object", "sensitive"], true)} end defp process_tag( "mrf_tag:media-strip", %{ - "type" => "Create", + "type" => type, "object" => %{"attachment" => child_attachment} = object } = message ) - when length(child_attachment) > 0 do + when length(child_attachment) > 0 and type in ["Create", "Update"] do object = Map.delete(object, "attachment") message = Map.put(message, "object", object) @@ -152,7 +152,7 @@ def filter(%{"object" => target_actor, "type" => "Follow"} = message), do: filter_message(target_actor, message) @impl true - def filter(%{"actor" => actor, "type" => "Create"} = message), + def filter(%{"actor" => actor, "type" => type} = message) when type in ["Create", "Update"], do: filter_message(actor, message) @impl true diff --git a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs index 46be316ee2..a0db8df547 100644 --- a/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/tag_policy_test.exs @@ -99,6 +99,24 @@ test "removes attachments" do assert TagPolicy.filter(message) == {:ok, except_message} end + + test "removes attachments in Updates" do + actor = insert(:user, tags: ["mrf_tag:media-strip"]) + + message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"attachment" => ["file1"]} + } + + except_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{} + } + + assert TagPolicy.filter(message) == {:ok, except_message} + end end describe "mrf_tag:media-force-nsfw" do @@ -119,5 +137,23 @@ test "Mark as sensitive on presence of attachments" do assert TagPolicy.filter(message) == {:ok, except_message} end + + test "Mark as sensitive on presence of attachments in Updates" do + actor = insert(:user, tags: ["mrf_tag:media-force-nsfw"]) + + message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"tag" => ["test"], "attachment" => ["file1"]} + } + + except_message = %{ + "actor" => actor.ap_id, + "type" => "Update", + "object" => %{"tag" => ["test"], "attachment" => ["file1"], "sensitive" => true} + } + + assert TagPolicy.filter(message) == {:ok, except_message} + end end end From 2554028097b3dbc1644269f7d5612152748d3c7f Mon Sep 17 00:00:00 2001 From: tusooa Date: Thu, 15 Dec 2022 11:20:00 -0500 Subject: [PATCH 25/41] Make SimplePolicy Update-aware This is inspired by https://akkoma.dev/AkkomaGang/akkoma/commit/d5828f1c5e54ca236e50ef7837bfba3d1e665854 --- .../web/activity_pub/mrf/simple_policy.ex | 9 ++++---- .../activity_pub/mrf/simple_policy_test.exs | 22 +++++++++++++++++-- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex index c0c7f38063..829ddeaea3 100644 --- a/lib/pleroma/web/activity_pub/mrf/simple_policy.ex +++ b/lib/pleroma/web/activity_pub/mrf/simple_policy.ex @@ -40,9 +40,9 @@ defp check_reject(%{host: actor_host} = _actor_info, object) do defp check_media_removal( %{host: actor_host} = _actor_info, - %{"type" => "Create", "object" => %{"attachment" => child_attachment}} = object + %{"type" => type, "object" => %{"attachment" => child_attachment}} = object ) - when length(child_attachment) > 0 do + when length(child_attachment) > 0 and type in ["Create", "Update"] do media_removal = instance_list(:media_removal) |> MRF.subdomains_regex() @@ -63,10 +63,11 @@ defp check_media_removal(_actor_info, object), do: {:ok, object} defp check_media_nsfw( %{host: actor_host} = _actor_info, %{ - "type" => "Create", + "type" => type, "object" => %{} = _child_object } = object - ) do + ) + when type in ["Create", "Update"] do media_nsfw = instance_list(:media_nsfw) |> MRF.subdomains_regex() diff --git a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs index 674b506c31..57fc00af5d 100644 --- a/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs +++ b/test/pleroma/web/activity_pub/mrf/simple_policy_test.exs @@ -57,6 +57,16 @@ test "match with wildcard domain" do assert SimplePolicy.filter(local_message) == {:ok, local_message} end + + test "works with Updates" do + clear_config([:mrf_simple, :media_removal], [{"remote.instance", "Some reason"}]) + media_message = build_media_message(type: "Update") + + assert SimplePolicy.filter(media_message) == + {:ok, + media_message + |> Map.put("object", Map.delete(media_message["object"], "attachment"))} + end end describe "when :media_nsfw" do @@ -90,12 +100,20 @@ test "match with wildcard domain" do assert SimplePolicy.filter(local_message) == {:ok, local_message} end + + test "works with Updates" do + clear_config([:mrf_simple, :media_nsfw], [{"remote.instance", "Whetever"}]) + media_message = build_media_message(type: "Update") + + assert SimplePolicy.filter(media_message) == + {:ok, put_in(media_message, ["object", "sensitive"], true)} + end end - defp build_media_message do + defp build_media_message(opts \\ []) do %{ "actor" => "https://remote.instance/users/bob", - "type" => "Create", + "type" => opts[:type] || "Create", "object" => %{ "attachment" => [%{}], "tag" => ["foo"], From 9838790a7d14e72449af3ae53daf3df30fd1aba0 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Thu, 15 Dec 2022 17:46:20 -0500 Subject: [PATCH 26/41] AttachmentValidator: Actually require url --- .../object_validators/attachment_validator.ex | 6 +++--- .../object_validators/attachment_validator_test.exs | 13 +++++++++++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex index 14f51e2c5a..398020bff1 100644 --- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex @@ -45,9 +45,9 @@ def changeset(struct, data) do struct |> cast(data, [:id, :type, :mediaType, :name, :blurhash]) - |> cast_embed(:url, with: &url_changeset/2) + |> cast_embed(:url, with: &url_changeset/2, required: true) |> validate_inclusion(:type, ~w[Link Document Audio Image Video]) - |> validate_required([:type, :mediaType, :url]) + |> validate_required([:type, :mediaType]) end def url_changeset(struct, data) do @@ -91,6 +91,6 @@ defp fix_url(data) do defp validate_data(cng) do cng |> validate_inclusion(:type, ~w[Document Audio Image Video]) - |> validate_required([:mediaType, :url, :type]) + |> validate_required([:mediaType, :type]) end end diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs index 9a17e277ee..77f2044e97 100644 --- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs +++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs @@ -11,6 +11,19 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidatorTest do import Pleroma.Factory describe "attachments" do + test "fails without url" do + attachment = %{ + "mediaType" => "", + "name" => "", + "summary" => "298p3RG7j27tfsZ9RQ.jpg", + "type" => "Document" + } + + assert {:error, _cng} = + AttachmentValidator.cast_and_validate(attachment) + |> Ecto.Changeset.apply_action(:insert) + end + test "works with honkerific attachments" do attachment = %{ "mediaType" => "", From 4a32b584e148a5625a983e0932f2a3e16fdbbf30 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Thu, 15 Dec 2022 18:02:33 -0500 Subject: [PATCH 27/41] StatusView: Fix warning --- lib/pleroma/web/mastodon_api/views/status_view.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index b949d8f9a7..0a8c98b442 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -65,7 +65,7 @@ defp get_replied_to_activities(activities) do # This should be removed in a future version of Pleroma. Pleroma-FE currently # depends on this field, as well. defp get_context_id(%{data: %{"context" => context}}) when is_binary(context) do - use Bitwise + import Bitwise :erlang.crc32(context) |> band(bnot(0x8000_0000)) From bb27e4134b67e406810e40bbefd99fe392c25fed Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Thu, 15 Dec 2022 18:06:28 -0500 Subject: [PATCH 28/41] AudioVideoValidator: Fix embedded attachment requirements --- .../activity_pub/object_validators/audio_video_validator.ex | 4 ++-- test/pleroma/object/fetcher_test.exs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex index 432bd9039d..671a7ef0c3 100644 --- a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex +++ b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex @@ -104,14 +104,14 @@ def changeset(struct, data) do struct |> cast(data, __schema__(:fields) -- [:attachment, :tag]) - |> cast_embed(:attachment) + |> cast_embed(:attachment, required: true) |> cast_embed(:tag) end defp validate_data(data_cng) do data_cng |> validate_inclusion(:type, ["Audio", "Video"]) - |> validate_required([:id, :actor, :attributedTo, :type, :context, :attachment]) + |> validate_required([:id, :actor, :attributedTo, :type, :context]) |> CommonValidations.validate_any_presence([:cc, :to]) |> CommonValidations.validate_fields_match([:actor, :attributedTo]) |> CommonValidations.validate_actor_presence() diff --git a/test/pleroma/object/fetcher_test.exs b/test/pleroma/object/fetcher_test.exs index 51541a42cb..c8ad66ddb4 100644 --- a/test/pleroma/object/fetcher_test.exs +++ b/test/pleroma/object/fetcher_test.exs @@ -166,7 +166,7 @@ test "it resets instance reachability on successful fetch" do Instances.set_consistently_unreachable(id) refute Instances.reachable?(id) - {:ok, object} = + {:ok, _object} = Fetcher.fetch_object_from_id("http://mastodon.example.org/@admin/99541947525187367") assert Instances.reachable?(id) From cfca9544e89331e53c21a69dd8c47e2133c3d36f Mon Sep 17 00:00:00 2001 From: weblate-extractor Date: Fri, 16 Dec 2022 16:59:26 +0000 Subject: [PATCH 29/41] Extract translatable strings --- priv/gettext/config_descriptions.pot | 72 +++++++--------------------- priv/gettext/errors.pot | 47 ++++++++++-------- 2 files changed, 45 insertions(+), 74 deletions(-) diff --git a/priv/gettext/config_descriptions.pot b/priv/gettext/config_descriptions.pot index a8074ee64e..1c3a98d3eb 100644 --- a/priv/gettext/config_descriptions.pot +++ b/priv/gettext/config_descriptions.pot @@ -40,12 +40,6 @@ msgctxt "config description at :pleroma" msgid "Authenticator" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :quack" -msgid "Quack-related settings" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config label at :cors_plug" @@ -82,12 +76,6 @@ msgctxt "config label at :pleroma" msgid "Pleroma Authenticator" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config label at :quack" -msgid "Quack Logger" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config description at :logger-:console" @@ -2302,12 +2290,6 @@ msgctxt "config description at :pleroma-:mrf_mention > :actors" msgid "A list of actors for which any post mentioning them will be dropped" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :pleroma-:mrf_object_age > :actions" -msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines; `:reject` rejects the message entirely" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config description at :pleroma-:mrf_object_age > :threshold" @@ -3298,24 +3280,6 @@ msgctxt "config description at :prometheus-Pleroma.Web.Endpoint.MetricsExporter msgid "App metrics endpoint URI path." msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :quack > :level" -msgid "Log level" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :quack > :meta" -msgid "Configure which metadata you want to report on" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config description at :quack > :webhook_url" -msgid "Configure the Slack incoming webhook" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config description at :web_push_encryption-:vapid_details > :private_key" @@ -5956,24 +5920,6 @@ msgctxt "config label at :prometheus-Pleroma.Web.Endpoint.MetricsExporter > :pat msgid "Path" msgstr "" -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config label at :quack > :level" -msgid "Level" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config label at :quack > :meta" -msgid "Meta" -msgstr "" - -#, elixir-autogen, elixir-format -#: lib/pleroma/docs/translator.ex:5 -msgctxt "config label at :quack > :webhook_url" -msgid "Webhook URL" -msgstr "" - #, elixir-autogen, elixir-format #: lib/pleroma/docs/translator.ex:5 msgctxt "config label at :web_push_encryption-:vapid_details > :private_key" @@ -6057,3 +6003,21 @@ msgstr "" msgctxt "config label at :pleroma-:delete_context_objects > :sleep_interval_ms" msgid "Sleep interval ms" msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:instance > :report_strip_status" +msgid "Strip associated statuses in reports to ids when closed/resolved, otherwise keep a copy" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config description at :pleroma-:mrf_object_age > :actions" +msgid "A list of actions to apply to the post. `:delist` removes the post from public timelines; `:strip_followers` removes followers from the ActivityPub recipient list ensuring they won't be delivered to home timelines, additionally for followers-only it degrades to a direct message; `:reject` rejects the message entirely" +msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/docs/translator.ex:5 +msgctxt "config label at :pleroma-:instance > :report_strip_status" +msgid "Report strip status" +msgstr "" diff --git a/priv/gettext/errors.pot b/priv/gettext/errors.pot index 9e0af21815..19a0039ca3 100644 --- a/priv/gettext/errors.pot +++ b/priv/gettext/errors.pot @@ -90,12 +90,12 @@ msgid "must be equal to %{number}" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:558 +#: lib/pleroma/web/common_api.ex:574 msgid "Account not found" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:316 +#: lib/pleroma/web/common_api.ex:332 msgid "Already voted" msgstr "" @@ -111,7 +111,7 @@ msgid "Can't display this activity" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:327 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:337 msgid "Can't find user" msgstr "" @@ -131,34 +131,34 @@ msgid "Comment must be up to %{max_size} characters" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/config_db.ex:200 +#: lib/pleroma/config_db.ex:199 msgid "Config with params %{params} not found" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:167 -#: lib/pleroma/web/common_api.ex:171 +#: lib/pleroma/web/common_api.ex:183 +#: lib/pleroma/web/common_api.ex:187 msgid "Could not delete" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:217 +#: lib/pleroma/web/common_api.ex:233 msgid "Could not favorite" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:254 +#: lib/pleroma/web/common_api.ex:270 msgid "Could not unfavorite" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:202 +#: lib/pleroma/web/common_api.ex:218 msgid "Could not unrepeat" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:565 -#: lib/pleroma/web/common_api.ex:574 +#: lib/pleroma/web/common_api.ex:581 +#: lib/pleroma/web/common_api.ex:590 msgid "Could not update state" msgstr "" @@ -184,7 +184,7 @@ msgid "Invalid credentials." msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:337 +#: lib/pleroma/web/common_api.ex:353 msgid "Invalid indices" msgstr "" @@ -199,7 +199,7 @@ msgid "Invalid password." msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:257 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:267 msgid "Invalid request" msgstr "" @@ -231,12 +231,12 @@ msgid "Not found" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:308 +#: lib/pleroma/web/common_api.ex:324 msgid "Poll's author can't vote" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:492 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:502 #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 @@ -275,7 +275,7 @@ msgid "Throttled" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:338 +#: lib/pleroma/web/common_api.ex:354 msgid "Too many choices" msgstr "" @@ -307,7 +307,7 @@ msgid "can't update outbox of %{nickname} as %{as_nickname}" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:510 +#: lib/pleroma/web/common_api.ex:526 msgid "conversation is already muted" msgstr "" @@ -419,12 +419,12 @@ msgid "CAPTCHA Error" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:266 +#: lib/pleroma/web/common_api.ex:282 msgid "Could not add reaction emoji" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/common_api.ex:277 +#: lib/pleroma/web/common_api.ex:293 msgid "Could not remove reaction emoji" msgstr "" @@ -558,7 +558,7 @@ msgid "Access denied" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:324 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334 msgid "This API requires an authenticated user" msgstr "" @@ -595,3 +595,10 @@ msgstr "" #: lib/pleroma/web/o_auth/o_auth_controller.ex:366 msgid "Your account is awaiting approval." msgstr "" + +#, elixir-autogen, elixir-format +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:258 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:261 +#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:264 +msgid "File is too large" +msgstr "" From 8e6f2624a808f3aa2e16af903a3b16b506c71cd1 Mon Sep 17 00:00:00 2001 From: Lain Soykaf Date: Fri, 16 Dec 2022 14:32:30 -0500 Subject: [PATCH 30/41] CI: Fix image for amd64-musl --- .gitlab-ci.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7fca81f4d9..8b0381d110 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -297,7 +297,6 @@ amd64-musl: image: elixir:1.11.4-alpine tags: - amd64 - image: elixir:1.10.4-alpine cache: *release-cache variables: *release-variables before_script: &before-release-musl From 3f0783c0a50c99ba4697829f9571b57d8b08f5de Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Mon, 14 Nov 2022 01:50:52 +0500 Subject: [PATCH 31/41] fix atom and rss feeds for users and tags Changes: - make the XML closer to spec (RSS does not pass w3c's validator, but works) - fix dates (RFC3339 for Atom, doc says RFC822 for RSS but RFC1123 is closer) - fix attachment/enclosure links (but see below) - set feed item title to post's "summary" if present - pruned several elements that validators did not like - examples: ap_enabled, user banner urls. Specs: - https://www.rssboard.org/rss-specification - https://validator.w3.org/feed/docs/atom.html - https://www.intertwingly.net/wiki/pie/Rss20AndAtom10Compared Validators: - https://validator.w3.org/feed/ - https://rssatom.com/feedvalidator.php Attachment/enclosure links should have a "length" field (mandatory according to the spec). This is not present in the object's data map. --- lib/pleroma/web/feed/feed_view.ex | 71 +++++++++++++++++-- .../templates/feed/feed/_activity.atom.eex | 8 +-- .../web/templates/feed/feed/_activity.rss.eex | 11 +-- .../web/templates/feed/feed/_author.atom.eex | 19 +++-- .../web/templates/feed/feed/_author.rss.eex | 27 +++---- .../feed/feed/_tag_activity.atom.eex | 64 ++++++++--------- .../templates/feed/feed/_tag_author.atom.eex | 28 ++++---- .../web/templates/feed/feed/tag.atom.eex | 32 ++++----- .../web/templates/feed/feed/user.atom.eex | 4 +- .../web/templates/feed/feed/user.rss.eex | 17 +++-- 10 files changed, 162 insertions(+), 119 deletions(-) diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 35a5f94829..323ede90a4 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -21,7 +21,7 @@ def pub_date(date) when is_binary(date) do |> pub_date end - def pub_date(%DateTime{} = date), do: Timex.format!(date, "{RFC822}") + def pub_date(%DateTime{} = date), do: to_rfc1123(date) def prepare_activity(activity, opts \\ []) do object = Object.normalize(activity, fetch: false) @@ -41,13 +41,18 @@ def prepare_activity(activity, opts \\ []) do def most_recent_update(activities) do with %{updated_at: updated_at} <- List.first(activities) do - NaiveDateTime.to_iso8601(updated_at) + to_rfc3339(updated_at) end end - def most_recent_update(activities, user) do + def most_recent_update(activities, user, :atom) do (List.first(activities) || user).updated_at - |> NaiveDateTime.to_iso8601() + |> to_rfc3339() + end + + def most_recent_update(activities, user, :rss) do + (List.first(activities) || user).updated_at + |> to_rfc1123() end def feed_logo do @@ -61,6 +66,10 @@ def feed_logo do |> MediaProxy.url() end + def email(user) do + user.nickname <> "@" <> Pleroma.Web.Endpoint.host() + end + def logo(user) do user |> User.avatar_url() @@ -69,18 +78,35 @@ def logo(user) do def last_activity(activities), do: List.last(activities) - def activity_title(%{"content" => content}, opts \\ %{}) do - content + def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ %{}) do + title = + cond do + summary != "" -> summary + content != "" -> activity_content(data) + true -> "a post" + end + + title |> Pleroma.Web.Metadata.Utils.scrub_html() |> Pleroma.Emoji.Formatter.demojify() |> Formatter.truncate(opts[:max_length], opts[:omission]) |> escape() end + def activity_description(data) do + content = activity_content(data) + summary = data["summary"] + + cond do + content != "" -> escape(content) + summary != "" -> escape(summary) + true -> escape(data["type"]) + end + end + def activity_content(%{"content" => content}) do content |> String.replace(~r/[\n\r]/, "") - |> escape() end def activity_content(_), do: "" @@ -112,4 +138,35 @@ def escape(html) do |> html_escape() |> safe_to_string() end + + @spec to_rfc3339(String.t() | NativeDateTime.t()) :: String.t() + def to_rfc3339(date) when is_binary(date) do + date + |> Timex.parse!("{ISO:Extended}") + |> to_rfc3339() + end + + def to_rfc3339(nd) do + nd + |> Timex.to_datetime() + |> Timex.format!("{RFC3339}") + end + + @spec to_rfc1123(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t() + def to_rfc1123(datestr) when is_binary(datestr) do + datestr + |> Timex.parse!("{ISO:Extended}") + |> to_rfc1123() + end + + def to_rfc1123(%DateTime{} = date) do + date + |> Timex.format!("{RFC1123}") + end + + def to_rfc1123(nd) do + nd + |> Timex.to_datetime() + |> Timex.format!("{RFC1123}") + end end diff --git a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex index 57bd924683..260338772a 100644 --- a/lib/pleroma/web/templates/feed/feed/_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_activity.atom.eex @@ -3,15 +3,15 @@ http://activitystrea.ms/schema/1.0/post <%= @data["id"] %> <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_content(@data) %> - <%= @activity.data["published"] %> - <%= @activity.data["published"] %> + <%= activity_description(@data) %> + <%= to_rfc3339(@activity.data["published"]) %> + <%= to_rfc3339(@activity.data["published"]) %> <%= activity_context(@activity) %> - <%= if @data["summary"] do %> + <%= if @data["summary"] != "" do %> <%= escape(@data["summary"]) %> <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex index 279f2171d8..7a7e494c0a 100644 --- a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex @@ -3,17 +3,12 @@ http://activitystrea.ms/schema/1.0/post <%= @data["id"] %> <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_content(@data) %> - <%= @activity.data["published"] %> - <%= @activity.data["published"] %> + <%= activity_description(@data) %> + <%= to_rfc1123(@activity.data["published"]) %> <%= activity_context(@activity) %> - <%= if @data["summary"] do %> - <%= escape(@data["summary"]) %> - <% end %> - <%= if @activity.local do %> <%= @data["id"] %> <% else %> @@ -27,7 +22,7 @@ <% end %> <%= for attachment <- @data["attachment"] || [] do %> - <%= attachment_href(attachment) %> + <% end %> <%= if @data["inReplyTo"] do %> diff --git a/lib/pleroma/web/templates/feed/feed/_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_author.atom.eex index 25cbffada0..90be8a559e 100644 --- a/lib/pleroma/web/templates/feed/feed/_author.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_author.atom.eex @@ -1,17 +1,14 @@ - <%= @user.ap_id %> - http://activitystrea.ms/schema/1.0/person <%= @user.ap_id %> + <%= @user.nickname %> + http://activitystrea.ms/schema/1.0/person + <%= @user.name %> + <%= User.avatar_url(@user) %> + <%= @user.ap_id %> + <%= to_rfc3339(@user.inserted_at) %> + <%= to_rfc3339(@user.updated_at) %> + <%= @user.ap_id %> <%= @user.nickname %> <%= @user.name %> <%= escape(@user.bio) %> - <%= escape(@user.bio) %> - <%= @user.nickname %> - - <%= if User.banner_url(@user) do %> - - <% end %> - <%= if @user.local do %> - true - <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/_author.rss.eex b/lib/pleroma/web/templates/feed/feed/_author.rss.eex index 526aeddcfc..22477e6b1a 100644 --- a/lib/pleroma/web/templates/feed/feed/_author.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/_author.rss.eex @@ -1,17 +1,10 @@ - - <%= @user.ap_id %> - http://activitystrea.ms/schema/1.0/person - <%= @user.ap_id %> - <%= @user.nickname %> - <%= @user.name %> - <%= escape(@user.bio) %> - <%= escape(@user.bio) %> - <%= @user.nickname %> - <%= User.avatar_url(@user) %> - <%= if User.banner_url(@user) do %> - <%= User.banner_url(@user) %> - <% end %> - <%= if @user.local do %> - true - <% end %> - +<%= "#{email(@user)} (#{escape(@user.name)})" %> +http://activitystrea.ms/schema/1.0/person +<%= @user.name %> +<%= User.avatar_url(@user) %> +<%= @user.ap_id %> +<%= to_rfc3339(@user.inserted_at) %> +<%= to_rfc3339(@user.updated_at) %> +<%= @user.nickname %> +<%= @user.name %> +<%= escape(@user.bio) %> 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 7e2e587e18..25980c1e42 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.atom.eex @@ -1,12 +1,22 @@ - http://activitystrea.ms/schema/1.0/note - http://activitystrea.ms/schema/1.0/post + http://activitystrea.ms/schema/1.0/note + http://activitystrea.ms/schema/1.0/post <%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %> - <%= @data["id"] %> - <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> - <%= activity_content(@data) %> + <%= @data["id"] %> + <%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %> + <%= activity_description(@data) %> + <%= to_rfc3339(@activity.data["published"]) %> + <%= to_rfc3339(@activity.data["published"]) %> + + <%= activity_context(@activity) %> + + + + <%= if @data["summary"] != "" do %> + <%= @data["summary"] %> + <% end %> <%= if @activity.local do %> @@ -15,37 +25,25 @@ <% end %> - <%= @activity.data["published"] %> - <%= @activity.data["published"] %> - - - <%= activity_context(@activity) %> - - - - <%= if @data["summary"] do %> - <%= @data["summary"] %> - <% end %> - - <%= for id <- @activity.recipients do %> - <%= if id == Pleroma.Constants.as_public() do %> + <%= for id <- @activity.recipients do %> + <%= if id == Pleroma.Constants.as_public() do %> + + <% else %> + <%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %> - <% else %> - <%= unless Regex.match?(~r/^#{Pleroma.Web.Endpoint.url()}.+followers$/, id) do %> - - <% end %> + ostatus:object-type="http://activitystrea.ms/schema/1.0/person" + href="<%= id %>" /> <% end %> <% end %> + <% end %> - <%= for tag <- Pleroma.Object.hashtags(@object) do %> - - <% end %> + <%= for tag <- Pleroma.Object.hashtags(@object) do %> + + <% end %> - <%= for {emoji, file} <- @data["emoji"] || %{} do %> - - <% end %> + <%= for {emoji, file} <- @data["emoji"] || %{} do %> + + <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex index 997c4936e2..71c6968329 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_author.atom.eex @@ -1,18 +1,14 @@ - http://activitystrea.ms/schema/1.0/person - <%= @actor.ap_id %> - <%= @actor.ap_id %> - <%= @actor.nickname %> - <%= escape(@actor.bio) %> - - <%= if User.banner_url(@actor) do %> - - <% end %> - <%= if @actor.local do %> - true - <% end %> - - <%= @actor.nickname %> - <%= @actor.name %> - <%= escape(@actor.bio) %> + <%= @actor.ap_id %> + <%= @actor.nickname %> + http://activitystrea.ms/schema/1.0/person + <%= @actor.name %> + <%= User.avatar_url(@actor) %> + <%= @actor.ap_id %> + <%= to_rfc3339(@actor.inserted_at) %> + <%= to_rfc3339(@actor.updated_at) %> + <%= @actor.ap_id %> + <%= @actor.nickname %> + <%= @actor.name %> + <%= escape(@actor.bio) %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 8c551feaf5..4955996c93 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -1,22 +1,20 @@ - + - <%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %> - #<%= @tag %> + <%= Routes.tag_feed_url(@conn, :feed, @tag) <> ".atom" %> + #<%= @tag %> + <%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %> + <%= feed_logo() %> + <%= most_recent_update(@activities) %> + - <%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %> - <%= feed_logo() %> - <%= most_recent_update(@activities) %> - - <%= for activity <- @activities do %> - <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> - <% end %> + <%= for activity <- @activities do %> + <%= render Phoenix.Controller.view_module(@conn), "_tag_activity.atom", Map.merge(assigns, prepare_activity(activity, actor: true)) %> + <% end %> diff --git a/lib/pleroma/web/templates/feed/feed/user.atom.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex index 97a7535aba..a0148d768e 100644 --- a/lib/pleroma/web/templates/feed/feed/user.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -1,14 +1,14 @@ <%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".atom" %> <%= @user.nickname <> "'s timeline" %> - <%= most_recent_update(@activities, @user) %> + <%= escape(@user.bio) %> + <%= most_recent_update(@activities, @user, :atom) %> <%= logo(@user) %> diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex index a9fee244cb..80ad8b1617 100644 --- a/lib/pleroma/web/templates/feed/feed/user.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -1,11 +1,20 @@ - + - <%= Routes.user_feed_url(@conn, :feed, @user.nickname) <> ".rss" %> <%= @user.nickname <> "'s timeline" %> - <%= most_recent_update(@activities, @user) %> - <%= logo(@user) %> <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %> + " + rel="self" type="application/rss+xml" /> + <%= escape(@user.bio) %> + + <%= logo(@user) %> + <%= @user.nickname <> "'s timeline" %> + <%= '#{Routes.user_feed_url(@conn, :feed, @user.nickname)}.rss' %> + <%= render Phoenix.Controller.view_module(@conn), "_author.rss", assigns %> From f3253c0c6a0f6350437fc701023b375ecb1b7bc6 Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Tue, 15 Nov 2022 11:45:32 -0500 Subject: [PATCH 32/41] Implement RFC2822 timestamp formatting --- lib/pleroma/web/feed/feed_view.ex | 46 +++++++++++++++---- .../web/templates/feed/feed/_activity.rss.eex | 2 +- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 323ede90a4..35136897f2 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -14,6 +14,9 @@ defmodule Pleroma.Web.Feed.FeedView do require Pleroma.Constants + @days ~w(Mon Tue Wed Thu Fri Sat Sun) + @months ~w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) + @spec pub_date(String.t() | DateTime.t()) :: String.t() def pub_date(date) when is_binary(date) do date @@ -21,7 +24,7 @@ def pub_date(date) when is_binary(date) do |> pub_date end - def pub_date(%DateTime{} = date), do: to_rfc1123(date) + def pub_date(%DateTime{} = date), do: to_rfc2822(date) def prepare_activity(activity, opts \\ []) do object = Object.normalize(activity, fetch: false) @@ -52,7 +55,7 @@ def most_recent_update(activities, user, :atom) do def most_recent_update(activities, user, :rss) do (List.first(activities) || user).updated_at - |> to_rfc1123() + |> to_rfc2822() end def feed_logo do @@ -152,21 +155,46 @@ def to_rfc3339(nd) do |> Timex.format!("{RFC3339}") end - @spec to_rfc1123(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t() - def to_rfc1123(datestr) when is_binary(datestr) do + @spec to_rfc2822(String.t() | DateTime.t() | NativeDateTime.t()) :: String.t() + def to_rfc2822(datestr) when is_binary(datestr) do datestr |> Timex.parse!("{ISO:Extended}") - |> to_rfc1123() + |> to_rfc2822() end - def to_rfc1123(%DateTime{} = date) do + def to_rfc2822(%DateTime{} = date) do date - |> Timex.format!("{RFC1123}") + |> DateTime.to_naive() + |> NaiveDateTime.to_erl() + |> rfc2822_from_erl() end - def to_rfc1123(nd) do + def to_rfc2822(nd) do nd |> Timex.to_datetime() - |> Timex.format!("{RFC1123}") + |> DateTime.to_naive() + |> NaiveDateTime.to_erl() + |> rfc2822_from_erl() + end + + @doc """ + Builds a RFC2822 timestamp from an Erlang timestamp + [RFC2822 3.3 - Date and Time Specification](https://tools.ietf.org/html/rfc2822#section-3.3) + This function always assumes the Erlang timestamp is in Universal time, not Local time + """ + def rfc2822_from_erl({{year, month, day} = date, {hour, minute, second}}) do + day_name = Enum.at(@days, :calendar.day_of_the_week(date) - 1) + month_name = Enum.at(@months, month - 1) + + date_part = "#{day_name}, #{day} #{month_name} #{year}" + time_part = "#{pad(hour)}:#{pad(minute)}:#{pad(second)}" + + date_part <> " " <> time_part <> " +0000" + end + + defp pad(num) do + num + |> Integer.to_string() + |> String.pad_leading(2, "0") end end diff --git a/lib/pleroma/web/templates/feed/feed/_activity.rss.eex b/lib/pleroma/web/templates/feed/feed/_activity.rss.eex index 7a7e494c0a..5c8f35fe47 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_rfc1123(@activity.data["published"]) %> + <%= to_rfc2822(@activity.data["published"]) %> <%= activity_context(@activity) %> From 8d500977a6ce9b0fd461c16ee2b343bab510e27f Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:29:40 +0500 Subject: [PATCH 33/41] fix: feed item title was escaped twice --- lib/pleroma/web/feed/feed_view.ex | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 35136897f2..3e24397aa2 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -93,7 +93,6 @@ def activity_title(%{"content" => content, "summary" => summary} = data, opts \\ |> Pleroma.Web.Metadata.Utils.scrub_html() |> Pleroma.Emoji.Formatter.demojify() |> Formatter.truncate(opts[:max_length], opts[:omission]) - |> escape() end def activity_description(data) do From 3f63caee2ade363719591edf7f6cb4c56587efda Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:30:56 +0500 Subject: [PATCH 34/41] fix: add xmlns:thr for in-reply-to refs --- lib/pleroma/web/templates/feed/feed/tag.atom.eex | 2 +- lib/pleroma/web/templates/feed/feed/tag.rss.eex | 5 +++-- lib/pleroma/web/templates/feed/feed/user.atom.eex | 1 + lib/pleroma/web/templates/feed/feed/user.rss.eex | 1 + 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 4955996c93..14b0ee5944 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -1,7 +1,7 @@ - - + - #<%= @tag %> <%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %> <%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %> diff --git a/lib/pleroma/web/templates/feed/feed/user.atom.eex b/lib/pleroma/web/templates/feed/feed/user.atom.eex index a0148d768e..e36bfc66c4 100644 --- a/lib/pleroma/web/templates/feed/feed/user.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/user.atom.eex @@ -1,6 +1,7 @@ diff --git a/lib/pleroma/web/templates/feed/feed/user.rss.eex b/lib/pleroma/web/templates/feed/feed/user.rss.eex index 80ad8b1617..fae3fcf3d2 100644 --- a/lib/pleroma/web/templates/feed/feed/user.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/user.rss.eex @@ -1,6 +1,7 @@ From f597b1b3e6f04125422c0f7d8e076be44e578e48 Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:42:12 +0500 Subject: [PATCH 35/41] remove ap_id test -- the element makes the feed break --- test/pleroma/web/feed/tag_controller_test.exs | 1 - 1 file changed, 1 deletion(-) diff --git a/test/pleroma/web/feed/tag_controller_test.exs b/test/pleroma/web/feed/tag_controller_test.exs index 1bd2b157c7..a67acdb47c 100644 --- a/test/pleroma/web/feed/tag_controller_test.exs +++ b/test/pleroma/web/feed/tag_controller_test.exs @@ -63,7 +63,6 @@ test "gets a feed (ATOM)", %{conn: conn} do ] assert xpath(xml, ~x"//feed/entry/author/name/text()"ls) == [user.nickname, user.nickname] - assert xpath(xml, ~x"//feed/entry/author/id/text()"ls) == [user.ap_id, user.ap_id] conn = conn From 0f67eab38483c574db82a00b53fb29e13c7df089 Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:42:54 +0500 Subject: [PATCH 36/41] remove pub_date() -- use to_rfc2822 instead _tag_activity.xml.eex used activity_content() instead of activity_description(), and did not escape html properly. --- lib/pleroma/web/feed/feed_view.ex | 9 --------- .../web/templates/feed/feed/_tag_activity.xml.eex | 4 ++-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index 3e24397aa2..449659f4bb 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -17,15 +17,6 @@ defmodule Pleroma.Web.Feed.FeedView do @days ~w(Mon Tue Wed Thu Fri Sat Sun) @months ~w(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec) - @spec pub_date(String.t() | DateTime.t()) :: String.t() - def pub_date(date) when is_binary(date) do - date - |> Timex.parse!("{ISO:Extended}") - |> pub_date - end - - def pub_date(%DateTime{} = date), do: to_rfc2822(date) - def prepare_activity(activity, opts \\ []) do object = Object.normalize(activity, fetch: false) 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 2334e24a21..d582c83e8c 100644 --- a/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex +++ b/lib/pleroma/web/templates/feed/feed/_tag_activity.xml.eex @@ -4,9 +4,9 @@ <%= activity_context(@activity) %> <%= activity_context(@activity) %> - <%= pub_date(@activity.data["published"]) %> + <%= to_rfc2822(@activity.data["published"]) %> - <%= activity_content(@data) %> + <%= activity_description(@data) %> <%= for attachment <- @data["attachment"] || [] do %> <% end %> From c49316faee3d49df6236c8a57d0ed5c26d7d528e Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:45:08 +0500 Subject: [PATCH 37/41] modify user feed controller test to expect summary for title --- test/pleroma/web/feed/user_controller_test.exs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/pleroma/web/feed/user_controller_test.exs b/test/pleroma/web/feed/user_controller_test.exs index 38cde3315e..de32d3d4bf 100644 --- a/test/pleroma/web/feed/user_controller_test.exs +++ b/test/pleroma/web/feed/user_controller_test.exs @@ -74,7 +74,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 == ['42 & Thi...', 'This & t...'] + assert activity_titles == ['2hu', '2hu & as'] assert resp =~ FeedView.escape(object.data["content"]) assert resp =~ FeedView.escape(object.data["summary"]) assert resp =~ FeedView.escape(object.data["context"]) @@ -90,7 +90,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 == ['This & t...'] + assert activity_titles == ['2hu & as'] end test "gets a rss feed", %{conn: conn, user: user, object: object, max_id: max_id} do @@ -105,7 +105,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 == ['42 & Thi...', 'This & t...'] + assert activity_titles == ['2hu', '2hu & as'] assert resp =~ FeedView.escape(object.data["content"]) assert resp =~ FeedView.escape(object.data["summary"]) assert resp =~ FeedView.escape(object.data["context"]) @@ -121,7 +121,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 == ['This & t...'] + assert activity_titles == ['2hu & as'] end test "returns 404 for a missing feed", %{conn: conn} do From 96cfc9575c4c1b10402a40195e1ab4b9b20def26 Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Tue, 15 Nov 2022 23:45:23 +0500 Subject: [PATCH 38/41] document rss/atom fix in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3cff84a1b..0e34fcae15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed lowercase HTTP HEAD method in the Media Proxy Preview code - Removed useless notification call on Delete activities - Improved performance for filtering out deactivated and invisible users +- RSS and Atom feeds for users work again ### Removed - Quack, the logging backend that pushes to Slack channels From fce29984813b05e827b720656989b27bd6322ddf Mon Sep 17 00:00:00 2001 From: faried nawaz Date: Wed, 16 Nov 2022 00:44:28 +0500 Subject: [PATCH 39/41] use to_rfc2822 instead of pub_date in tests, too --- test/pleroma/web/feed/tag_controller_test.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/pleroma/web/feed/tag_controller_test.exs b/test/pleroma/web/feed/tag_controller_test.exs index a67acdb47c..58ab8f1377 100644 --- a/test/pleroma/web/feed/tag_controller_test.exs +++ b/test/pleroma/web/feed/tag_controller_test.exs @@ -137,8 +137,8 @@ test "gets a feed (RSS)", %{conn: conn} do ] assert xpath(xml, ~x"//channel/item/pubDate/text()"sl) == [ - FeedView.pub_date(activity2.data["published"]), - FeedView.pub_date(activity1.data["published"]) + FeedView.to_rfc2822(activity2.data["published"]), + FeedView.to_rfc2822(activity1.data["published"]) ] assert xpath(xml, ~x"//channel/item/enclosure/@url"sl) == [ From 72d4d1b392c7889e13b238a190a437090c360f2e Mon Sep 17 00:00:00 2001 From: Mark Felder Date: Mon, 19 Dec 2022 14:40:08 -0500 Subject: [PATCH 40/41] Fix TwitterCard meta tags MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit TwitterCard meta tags are supposed to use the attributes "name" and "content". OpenGraph tags use the attributes "property" and "content". Twitter itself is smart enough to detect broken meta tags and discover the TwitterCard using "property" and "content", but other platforms that only implement parsing of TwitterCards and not OpenGraph may fail to correctly detect the tags as they're under the wrong attributes. > "Open Graph protocol also specifies the use of property and content attributes for markup while > Twitter cards use name and content. Twitter’s parser will fall back to using property and content, > so there is no need to modify existing Open Graph protocol markup if it already exists." [0] [0] https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started --- CHANGELOG.md | 1 + .../web/metadata/providers/twitter_card.ex | 43 +++++++------- .../metadata/providers/twitter_card_test.exs | 56 +++++++++---------- 3 files changed, 50 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3cff84a1b..3d42a4cfed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -59,6 +59,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). - Fixed lowercase HTTP HEAD method in the Media Proxy Preview code - Removed useless notification call on Delete activities - Improved performance for filtering out deactivated and invisible users +- TwitterCard meta tags conformance ### Removed - Quack, the logging backend that pushes to Slack channels diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex index bf0a122121..2dac22ee2a 100644 --- a/lib/pleroma/web/metadata/providers/twitter_card.ex +++ b/lib/pleroma/web/metadata/providers/twitter_card.ex @@ -20,12 +20,12 @@ def build_tags(%{activity_id: id, object: object, user: user}) do [ title_tag(user), - {:meta, [property: "twitter:description", content: scrubbed_content], []} + {:meta, [name: "twitter:description", content: scrubbed_content], []} ] ++ if attachments == [] or Metadata.activity_nsfw?(object) do [ image_tag(user), - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:card", content: "summary"], []} ] else attachments @@ -37,20 +37,19 @@ def build_tags(%{user: user}) do with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do [ title_tag(user), - {:meta, [property: "twitter:description", content: truncated_bio], []}, + {:meta, [name: "twitter:description", content: truncated_bio], []}, image_tag(user), - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:card", content: "summary"], []} ] end end defp title_tag(user) do - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []} + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []} end def image_tag(user) do - {:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], - []} + {:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []} end defp build_attachments(id, %{data: %{"attachment" => attachments}}) do @@ -60,10 +59,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do case Utils.fetch_media_type(@media_types, url["mediaType"]) do "audio" -> [ - {:meta, [property: "twitter:card", content: "player"], []}, - {:meta, [property: "twitter:player:width", content: "480"], []}, - {:meta, [property: "twitter:player:height", content: "80"], []}, - {:meta, [property: "twitter:player", content: player_url(id)], []} + {:meta, [name: "twitter:card", content: "player"], []}, + {:meta, [name: "twitter:player:width", content: "480"], []}, + {:meta, [name: "twitter:player:height", content: "80"], []}, + {:meta, [name: "twitter:player", content: player_url(id)], []} | acc ] @@ -74,10 +73,10 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do # workaround. "image" -> [ - {:meta, [property: "twitter:card", content: "summary_large_image"], []}, + {:meta, [name: "twitter:card", content: "summary_large_image"], []}, {:meta, [ - property: "twitter:player", + name: "twitter:player", content: MediaProxy.url(url["href"]) ], []} | acc @@ -90,14 +89,14 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do width = url["width"] || 480 [ - {:meta, [property: "twitter:card", content: "player"], []}, - {:meta, [property: "twitter:player", content: player_url(id)], []}, - {:meta, [property: "twitter:player:width", content: "#{width}"], []}, - {:meta, [property: "twitter:player:height", content: "#{height}"], []}, - {:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])], + {:meta, [name: "twitter:card", content: "player"], []}, + {:meta, [name: "twitter:player", content: player_url(id)], []}, + {:meta, [name: "twitter:player:width", content: "#{width}"], []}, + {:meta, [name: "twitter:player:height", content: "#{height}"], []}, + {:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])], []}, - {:meta, - [property: "twitter:player:stream:content_type", content: url["mediaType"]], []} + {:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]], + []} | acc ] @@ -123,8 +122,8 @@ defp maybe_add_dimensions(metadata, url) do !is_nil(url["height"]) && !is_nil(url["width"]) -> metadata ++ [ - {:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []}, - {:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []} + {:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []}, + {:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []} ] true -> diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs index 1a0cea9cec..be4cfbe7b2 100644 --- a/test/pleroma/web/metadata/providers/twitter_card_test.exs +++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs @@ -22,10 +22,10 @@ test "it renders twitter card for user info" do res = TwitterCard.build_tags(%{user: user}) assert res == [ - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, - {:meta, [property: "twitter:description", content: "born 19 March 1994"], []}, - {:meta, [property: "twitter:image", content: avatar_url], []}, - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [name: "twitter:description", content: "born 19 March 1994"], []}, + {:meta, [name: "twitter:image", content: avatar_url], []}, + {:meta, [name: "twitter:card", content: "summary"], []} ] end @@ -47,11 +47,11 @@ test "it uses summary twittercard if post has no attachment" do result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) assert [ - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, - {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []}, - {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []}, + {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"], []}, - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:card", content: "summary"], []} ] == result end @@ -73,15 +73,15 @@ test "it uses summary as description if post has one" do result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) assert [ - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}, {:meta, [ - property: "twitter:description", + name: "twitter:description", content: "Public service announcement on caffeine consumption" ], []}, - {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], + {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"], []}, - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:card", content: "summary"], []} ] == result end @@ -123,11 +123,11 @@ test "it renders avatar not attachment if post is nsfw and unfurl_nsfw is disabl result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) assert [ - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, - {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []}, - {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"], + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []}, + {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"], []}, - {:meta, [property: "twitter:card", content: "summary"], []} + {:meta, [name: "twitter:card", content: "summary"], []} ] == result end @@ -179,26 +179,26 @@ test "it renders supported types of attachments and skips unknown types" do result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id}) assert [ - {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}, - {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []}, - {:meta, [property: "twitter:card", content: "summary_large_image"], []}, - {:meta, [property: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []}, - {:meta, [property: "twitter:player:width", content: "1280"], []}, - {:meta, [property: "twitter:player:height", content: "1024"], []}, - {:meta, [property: "twitter:card", content: "player"], []}, + {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}, + {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []}, + {:meta, [name: "twitter:card", content: "summary_large_image"], []}, + {:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []}, + {:meta, [name: "twitter:player:width", content: "1280"], []}, + {:meta, [name: "twitter:player:height", content: "1024"], []}, + {:meta, [name: "twitter:card", content: "player"], []}, {:meta, [ - property: "twitter:player", + name: "twitter:player", content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id) ], []}, - {:meta, [property: "twitter:player:width", content: "800"], []}, - {:meta, [property: "twitter:player:height", content: "600"], []}, + {:meta, [name: "twitter:player:width", content: "800"], []}, + {:meta, [name: "twitter:player:height", content: "600"], []}, {:meta, [ - property: "twitter:player:stream", + name: "twitter:player:stream", content: "https://pleroma.gov/about/juche.webm" ], []}, - {:meta, [property: "twitter:player:stream:content_type", content: "video/webm"], []} + {:meta, [name: "twitter:player:stream:content_type", content: "video/webm"], []} ] == result end end From b3d250a70af2c14dd4c0fb2162beae063d5c9f95 Mon Sep 17 00:00:00 2001 From: weblate-extractor Date: Tue, 20 Dec 2022 06:11:50 +0000 Subject: [PATCH 41/41] Extract translatable strings --- priv/gettext/static_pages.pot | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/priv/gettext/static_pages.pot b/priv/gettext/static_pages.pot index 3c64f1a29c..4c372ac4d5 100644 --- a/priv/gettext/static_pages.pot +++ b/priv/gettext/static_pages.pot @@ -156,8 +156,8 @@ msgid "Password changed!" msgstr "" #, elixir-autogen, elixir-format -#: lib/pleroma/web/templates/feed/feed/tag.atom.eex:15 -#: lib/pleroma/web/templates/feed/feed/tag.rss.eex:7 +#: lib/pleroma/web/templates/feed/feed/tag.atom.eex:12 +#: lib/pleroma/web/templates/feed/feed/tag.rss.eex:8 msgctxt "tag feed description" msgid "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse." msgstr ""