aboutsummaryrefslogtreecommitdiff
path: root/pkgs/akkoma
diff options
context:
space:
mode:
authorsefidel <contact@sefidel.net>2024-02-20 05:48:01 +0900
committersefidel <contact@sefidel.net>2024-02-20 06:09:18 +0900
commit7fe334c0f881b27db617aedaf233f6ae58d72278 (patch)
tree948c5e2f1493c6e7090da39174d2699a81d7a624 /pkgs/akkoma
downloadnixpkgs-exotic-7fe334c0f881b27db617aedaf233f6ae58d72278.zip
project: Initial commit
Diffstat (limited to 'pkgs/akkoma')
-rw-r--r--pkgs/akkoma/0001-Migrate-to-phoenix-1.7.patch2390
-rw-r--r--pkgs/akkoma/0002-Bump-lockfile.patch203
-rw-r--r--pkgs/akkoma/0003-Fix-OAuth-consumer-mode.patch248
-rw-r--r--pkgs/akkoma/default.nix197
-rw-r--r--pkgs/akkoma/mix.nix1611
5 files changed, 4649 insertions, 0 deletions
diff --git a/pkgs/akkoma/0001-Migrate-to-phoenix-1.7.patch b/pkgs/akkoma/0001-Migrate-to-phoenix-1.7.patch
new file mode 100644
index 0000000..d4cc790
--- /dev/null
+++ b/pkgs/akkoma/0001-Migrate-to-phoenix-1.7.patch
@@ -0,0 +1,2390 @@
+From ed0cdb8b2be55b9f33f93b3ef2c7e2fa46ba4eb3 Mon Sep 17 00:00:00 2001
+From: sefidel <contact@sefidel.net>
+Date: Mon, 19 Feb 2024 21:06:43 +0900
+Subject: [PATCH 1/3] Migrate to phoenix 1.7
+
+Original commit: https://akkoma.dev/AkkomaGang/akkoma/commit/6cb40bee26
+Backported to v3.10.4
+
+Signed-off-by: sefidel <contact@sefidel.net>
+---
+ .formatter.exs | 13 ++++-
+ .woodpecker/lint.yml | 55 ++++++++++++++++++
+ .woodpecker/test.yml | 40 ++++---------
+ CHANGELOG.md | 10 +++-
+ config/config.exs | 16 +----
+ lib/mix/tasks/pleroma/emoji.ex | 2 +
+ lib/mix/tasks/pleroma/user.ex | 15 +----
+ lib/phoenix/transports/web_socket/raw.ex | 1 -
+ lib/pleroma/emails/admin_email.ex | 9 ++-
+ lib/pleroma/emails/user_email.ex | 22 ++-----
+ lib/pleroma/user.ex | 9 +--
+ lib/pleroma/web.ex | 29 ++++++++--
+ lib/pleroma/web/activity_pub/activity_pub.ex | 5 ++
+ lib/pleroma/web/activity_pub/builder.ex | 4 +-
+ lib/pleroma/web/activity_pub/utils.ex | 15 ++---
+ .../web/activity_pub/views/user_view.ex | 14 ++---
+ .../controllers/admin_api_controller.ex | 4 +-
+ lib/pleroma/web/endpoint.ex | 2 +-
+ lib/pleroma/web/feed/user_controller.ex | 2 +-
+ lib/pleroma/web/masto_fe_controller.ex | 4 +-
+ .../controllers/auth_controller.ex | 9 +--
+ .../web/mastodon_api/views/status_view.ex | 2 +-
+ .../web/mastodon_api/views/tag_view.ex | 3 +-
+ lib/pleroma/web/metadata/providers/feed.ex | 6 +-
+ .../web/metadata/providers/twitter_card.ex | 4 +-
+ lib/pleroma/web/o_auth/o_auth_controller.ex | 4 +-
+ .../web/o_status/o_status_controller.ex | 3 +-
+ lib/pleroma/web/plugs/http_signature_plug.ex | 7 ++-
+ .../web/static_fe/static_fe_controller.ex | 11 ++--
+ lib/pleroma/web/static_fe/static_fe_view.ex | 1 -
+ .../frontend_switcher/switch.html.eex | 2 +-
+ .../web/templates/feed/feed/tag.atom.eex | 4 +-
+ .../web/templates/feed/feed/tag.rss.eex | 2 +-
+ .../web/templates/feed/feed/user.atom.eex | 6 +-
+ .../web/templates/feed/feed/user.rss.eex | 6 +-
+ .../web/templates/masto_fe/fedibird.html.heex | 58 +++++++++++++++++++
+ .../masto_fe/fedibird.index.html.eex | 35 -----------
+ .../templates/masto_fe/glitchsoc.html.heex | 57 ++++++++++++++++++
+ .../masto_fe/glitchsoc.index.html.eex | 35 -----------
+ .../templates/o_auth/mfa/recovery.html.eex | 12 ++--
+ .../web/templates/o_auth/mfa/totp.html.eex | 12 ++--
+ .../templates/o_auth/o_auth/consumer.html.eex | 2 +-
+ .../templates/o_auth/o_auth/register.html.eex | 10 ++--
+ .../web/templates/o_auth/o_auth/show.html.eex | 10 ++--
+ .../static_fe/static_fe/profile.html.eex | 2 +-
+ .../twitter_api/password/reset.html.eex | 2 +-
+ .../twitter_api/remote_follow/follow.html.eex | 2 +-
+ .../remote_follow/follow_login.html.eex | 2 +-
+ .../remote_follow/follow_mfa.html.eex | 2 +-
+ .../twitter_api/util/status_interact.html.eex | 2 +-
+ .../twitter_api/util/subscribe.html.eex | 2 +-
+ .../controllers/remote_follow_controller.ex | 2 +-
+ lib/pleroma/web/views/embed_view.ex | 3 +-
+ lib/pleroma/web/views/masto_fe_view.ex | 2 +-
+ mix.exs | 7 ++-
+ mix.lock | 12 ++--
+ test/pleroma/emails/admin_email_test.exs | 3 +-
+ test/pleroma/emails/user_email_test.exs | 10 +---
+ test/pleroma/integration/federation_test.exs | 5 +-
+ test/pleroma/user_test.exs | 14 +----
+ .../activity_pub_controller_test.exs | 10 ++--
+ .../web/activity_pub/activity_pub_test.exs | 8 +++
+ .../controllers/admin_api_controller_test.exs | 3 +-
+ .../controllers/report_controller_test.exs | 10 ++--
+ .../controllers/user_controller_test.exs | 6 +-
+ test/pleroma/web/feed/tag_controller_test.exs | 8 +--
+ .../pleroma/web/feed/user_controller_test.exs | 12 ++--
+ .../mastodon_api/update_credentials_test.exs | 2 +-
+ .../mastodon_api/views/status_view_test.exs | 2 +-
+ .../metadata/providers/twitter_card_test.exs | 3 +-
+ .../web/mongoose_im_controller_test.exs | 16 ++---
+ .../web/o_auth/o_auth_controller_test.exs | 12 ++--
+ .../remote_follow_controller_test.exs | 42 ++++++--------
+ test/pleroma/web/uploader_controller_test.exs | 4 +-
+ test/support/conn_case.ex | 2 +-
+ test/support/data_case.ex | 2 +
+ 76 files changed, 431 insertions(+), 355 deletions(-)
+ create mode 100644 .woodpecker/lint.yml
+ create mode 100644 lib/pleroma/web/templates/masto_fe/fedibird.html.heex
+ delete mode 100644 lib/pleroma/web/templates/masto_fe/fedibird.index.html.eex
+ create mode 100644 lib/pleroma/web/templates/masto_fe/glitchsoc.html.heex
+ delete mode 100644 lib/pleroma/web/templates/masto_fe/glitchsoc.index.html.eex
+
+diff --git a/.formatter.exs b/.formatter.exs
+index abd91dbbe..a96afe758 100644
+--- a/.formatter.exs
++++ b/.formatter.exs
+@@ -1,3 +1,14 @@
+ [
+- inputs: ["mix.exs", "{config,lib,test}/**/*.{ex,exs}", "priv/repo/migrations/*.exs", "priv/repo/optional_migrations/**/*.exs", "priv/scrubbers/*.ex"]
++ import_deps: [:ecto, :ecto_sql, :phoenix],
++ subdirectories: ["priv/*/migrations"],
++ plugins: [Phoenix.LiveView.HTMLFormatter],
++ inputs: [
++ "mix.exs",
++ "*.{heex,ex,exs}",
++ "{config,lib,test}/**/*.{heex,ex,exs}",
++ "priv/*/seeds.exs",
++ "priv/repo/migrations/*.exs",
++ "priv/repo/optional_migrations/**/*.exs",
++ "priv/scrubbers/*.ex"
++ ]
+ ]
+diff --git a/.woodpecker/lint.yml b/.woodpecker/lint.yml
+new file mode 100644
+index 000000000..8308e57d7
+--- /dev/null
++++ b/.woodpecker/lint.yml
+@@ -0,0 +1,55 @@
++platform: linux/amd64
++
++variables:
++ - &scw-secrets
++ - SCW_ACCESS_KEY
++ - SCW_SECRET_KEY
++ - SCW_DEFAULT_ORGANIZATION_ID
++ - &setup-hex "mix local.hex --force && mix local.rebar --force"
++ - &on-release
++ when:
++ event:
++ - push
++ - tag
++ branch:
++ - develop
++ - stable
++ - refs/tags/v*
++ - refs/tags/stable-*
++ - &on-stable
++ when:
++ event:
++ - push
++ - tag
++ branch:
++ - stable
++ - refs/tags/stable-*
++ - &on-point-release
++ when:
++ event:
++ - push
++ branch:
++ - develop
++ - stable
++ - &on-pr-open
++ when:
++ event:
++ - pull_request
++
++ - &tag-build "export BUILD_TAG=$${CI_COMMIT_TAG:-\"$CI_COMMIT_BRANCH\"} && export PLEROMA_BUILD_BRANCH=$BUILD_TAG"
++
++ - &clean "(rm -rf release || true) && (rm -rf _build || true) && (rm -rf /root/.mix)"
++ - &mix-clean "mix deps.clean --all && mix clean"
++
++pipeline:
++ lint:
++ image: akkoma/ci-base:1.15-otp26
++ <<: *on-pr-open
++ environment:
++ MIX_ENV: test
++ commands:
++ - mix local.hex --force
++ - mix local.rebar --force
++ - mix deps.get
++ - mix compile
++ - mix format --check-formatted
+diff --git a/.woodpecker/test.yml b/.woodpecker/test.yml
+index be8ea0dfa..3a8a1652e 100644
+--- a/.woodpecker/test.yml
++++ b/.woodpecker/test.yml
+@@ -1,5 +1,8 @@
+ platform: linux/amd64
+
++depends_on:
++ - lint
++
+ matrix:
+ ELIXIR_VERSION:
+ - 1.14
+@@ -69,15 +72,7 @@ services:
+ POSTGRES_PASSWORD: postgres
+
+ pipeline:
+- lint:
+- <<: *on-pr-open
+- image: akkoma/ci-base:1.15
+- commands:
+- - mix local.hex --force
+- - mix local.rebar --force
+- - mix format --check-formatted
+-
+- build:
++ test:
+ image: akkoma/ci-base:${ELIXIR_VERSION}-otp${OTP_VERSION}
+ <<: *on-pr-open
+ environment:
+@@ -91,24 +86,9 @@ pipeline:
+ - mix local.rebar --force
+ - mix deps.get
+ - mix compile
+-
+- test:
+- image: akkoma/ci-base:${ELIXIR_VERSION}-otp${OTP_VERSION}
+- <<: *on-pr-open
+- environment:
+- MIX_ENV: test
+- POSTGRES_DB: pleroma_test_${ELIXIR_VERSION}_${OTP_VERSION}
+- POSTGRES_USER: postgres
+- POSTGRES_PASSWORD: postgres
+- DB_HOST: postgres
+- commands:
+- - mix local.hex --force
+- - mix local.rebar --force
+- - mix deps.get
+- - mix compile
+- - mix ecto.drop -f -q
+- - mix ecto.create
+- - mix ecto.migrate
+- - mkdir -p test/tmp
+- - mix test --preload-modules --exclude erratic --exclude federated --exclude mocked
+- - mix test --preload-modules --only mocked
++ - mix ecto.drop -f -q
++ - mix ecto.create
++ - mix ecto.migrate
++ - mkdir -p test/tmp
++ - mix test --preload-modules --exclude erratic --exclude federated --exclude mocked
++ - mix test --preload-modules --only mocked
+diff --git a/CHANGELOG.md b/CHANGELOG.md
+index 92b3d1a71..a6c356bab 100644
+--- a/CHANGELOG.md
++++ b/CHANGELOG.md
+@@ -6,8 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
+
+ ## Unreleased
+
++## Added
++- Full compatibility with Erlang OTP26
++- handling of GET /api/v1/preferences
++
++## Changed
++- OTP builds are now built on erlang OTP26
++- The base Phoenix framework is now updated to 1.7
++
+ ## Fixed
+-- Issue where a bad inbox URL could break federation
++- Documentation issue in which a non-existing nginx file was referenced
+
+ ## 2023.08
+
+diff --git a/config/config.exs b/config/config.exs
+index 3430ee4d7..0a3cbde3f 100644
+--- a/config/config.exs
++++ b/config/config.exs
+@@ -110,17 +110,6 @@
+ "xmpp"
+ ]
+
+-websocket_config = [
+- path: "/websocket",
+- serializer: [
+- {Phoenix.Socket.V1.JSONSerializer, "~> 1.0.0"},
+- {Phoenix.Socket.V2.JSONSerializer, "~> 2.0.0"}
+- ],
+- timeout: 60_000,
+- transport_log: false,
+- compress: false
+-]
+-
+ # Configures the endpoint
+ config :pleroma, Pleroma.Web.Endpoint,
+ url: [host: "localhost"],
+@@ -130,10 +119,7 @@
+ {:_,
+ [
+ {"/api/v1/streaming", Pleroma.Web.MastodonAPI.WebsocketHandler, []},
+- {"/websocket", Phoenix.Endpoint.CowboyWebSocket,
+- {Phoenix.Transports.WebSocket,
+- {Pleroma.Web.Endpoint, Pleroma.Web.UserSocket, websocket_config}}},
+- {:_, Phoenix.Endpoint.Cowboy2Handler, {Pleroma.Web.Endpoint, []}}
++ {:_, Plug.Cowboy.Handler, {Pleroma.Web.Endpoint, []}}
+ ]}
+ ]
+ ],
+diff --git a/lib/mix/tasks/pleroma/emoji.ex b/lib/mix/tasks/pleroma/emoji.ex
+index 5dedf276a..89df511a7 100644
+--- a/lib/mix/tasks/pleroma/emoji.ex
++++ b/lib/mix/tasks/pleroma/emoji.ex
+@@ -235,6 +235,8 @@ def run(["gen-pack" | args]) do
+
+ IO.puts("#{pack_file} has been created with the #{name} pack")
+ end
++
++ Pleroma.Emoji.reload()
+ end
+
+ def run(["reload"]) do
+diff --git a/lib/mix/tasks/pleroma/user.ex b/lib/mix/tasks/pleroma/user.ex
+index 4ca1c28eb..1a8e866ef 100644
+--- a/lib/mix/tasks/pleroma/user.ex
++++ b/lib/mix/tasks/pleroma/user.ex
+@@ -11,6 +11,7 @@ defmodule Mix.Tasks.Pleroma.User do
+ alias Pleroma.UserInviteToken
+ alias Pleroma.Web.ActivityPub.Builder
+ alias Pleroma.Web.ActivityPub.Pipeline
++ use Pleroma.Web, :verified_routes
+
+ @shortdoc "Manages Pleroma users"
+ @moduledoc File.read!("docs/docs/administration/CLI_tasks/user.md")
+@@ -113,11 +114,7 @@ def run(["reset_password", nickname]) do
+ {:ok, token} <- Pleroma.PasswordResetToken.create_token(user) do
+ shell_info("Generated password reset token for #{user.nickname}")
+
+- IO.puts(
+- "URL: #{Pleroma.Web.Router.Helpers.reset_password_url(Pleroma.Web.Endpoint,
+- :reset,
+- token.token)}"
+- )
++ IO.puts("URL: #{~p[/api/v1/pleroma/password_reset/#{token.token}]}")
+ else
+ _ ->
+ shell_error("No local user #{nickname}")
+@@ -303,13 +300,7 @@ def run(["invite" | rest]) do
+ {:ok, invite} <- UserInviteToken.create_invite(options) do
+ shell_info("Generated user invite token " <> String.replace(invite.invite_type, "_", " "))
+
+- url =
+- Pleroma.Web.Router.Helpers.redirect_url(
+- Pleroma.Web.Endpoint,
+- :registration_page,
+- invite.token
+- )
+-
++ url = url(~p[/registration/#{invite.token}])
+ IO.puts(url)
+ else
+ error ->
+diff --git a/lib/phoenix/transports/web_socket/raw.ex b/lib/phoenix/transports/web_socket/raw.ex
+index 8ed64eb16..72def9dff 100644
+--- a/lib/phoenix/transports/web_socket/raw.ex
++++ b/lib/phoenix/transports/web_socket/raw.ex
+@@ -26,7 +26,6 @@ def init(%Plug.Conn{method: "GET"} = conn, {endpoint, handler, transport}) do
+ conn
+ |> fetch_query_params
+ |> Transport.transport_log(opts[:transport_log])
+- |> Transport.force_ssl(handler, endpoint, opts)
+ |> Transport.check_origin(handler, endpoint, opts)
+
+ case conn do
+diff --git a/lib/pleroma/emails/admin_email.ex b/lib/pleroma/emails/admin_email.ex
+index 88bc78aec..683de8e3b 100644
+--- a/lib/pleroma/emails/admin_email.ex
++++ b/lib/pleroma/emails/admin_email.ex
+@@ -6,10 +6,13 @@ defmodule Pleroma.Emails.AdminEmail do
+ @moduledoc "Admin emails"
+
+ import Swoosh.Email
+-
++ use Pleroma.Web, :mailer
+ alias Pleroma.Config
+ alias Pleroma.HTML
+- alias Pleroma.Web.Router.Helpers
++
++ use Phoenix.VerifiedRoutes,
++ endpoint: Pleroma.Web.Endpoint,
++ router: Pleroma.Web.Router
+
+ defp instance_config, do: Config.get(:instance)
+ defp instance_name, do: instance_config()[:name]
+@@ -45,7 +48,7 @@ def report(to, reporter, account, statuses, comment) do
+ statuses
+ |> Enum.map(fn
+ %{id: id} ->
+- status_url = Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, id)
++ status_url = url(~p[/notice/#{id}])
+ "<li><a href=\"#{status_url}\">#{status_url}</li>"
+
+ %{"id" => id} when is_binary(id) ->
+diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex
+index 1588c099c..fe319c775 100644
+--- a/lib/pleroma/emails/user_email.ex
++++ b/lib/pleroma/emails/user_email.ex
+@@ -6,12 +6,11 @@ defmodule Pleroma.Emails.UserEmail do
+ @moduledoc "User emails"
+
+ require Pleroma.Web.Gettext
++ use Pleroma.Web, :mailer
+
+ alias Pleroma.Config
+ alias Pleroma.User
+- alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Gettext
+- alias Pleroma.Web.Router
+
+ import Swoosh.Email
+ import Phoenix.Swoosh, except: [render_body: 3]
+@@ -75,7 +74,7 @@ def welcome(user, opts \\ %{}) do
+
+ def password_reset_email(user, token) when is_binary(token) do
+ Gettext.with_locale_or_default user.language do
+- password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token)
++ password_reset_url = ~p[/api/v1/pleroma/password_reset/#{token}]
+
+ html_body =
+ Gettext.dpgettext(
+@@ -108,12 +107,7 @@ def user_invitation_email(
+ to_name \\ nil
+ ) do
+ Gettext.with_locale_or_default user.language do
+- registration_url =
+- Router.Helpers.redirect_url(
+- Endpoint,
+- :registration_page,
+- user_invite_token.token
+- )
++ registration_url = ~p[/registration/#{user_invite_token.token}]
+
+ html_body =
+ Gettext.dpgettext(
+@@ -146,13 +140,7 @@ def user_invitation_email(
+
+ def account_confirmation_email(user) do
+ Gettext.with_locale_or_default user.language do
+- confirmation_url =
+- Router.Helpers.confirm_email_url(
+- Endpoint,
+- :confirm_email,
+- user.id,
+- to_string(user.confirmation_token)
+- )
++ confirmation_url = ~p[/api/account/confirm_email/#{user.id}/#{user.confirmation_token}]
+
+ html_body =
+ Gettext.dpgettext(
+@@ -342,7 +330,7 @@ def unsubscribe_url(user, notifications_type) do
+ |> Pleroma.JWT.generate_and_sign!()
+ |> Base.encode64()
+
+- Router.Helpers.subscription_url(Endpoint, :unsubscribe, token)
++ ~p[/mailer/unsubscribe/#{token}]
+ end
+
+ def backup_is_ready_email(backup, admin_user_id \\ nil) do
+diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
+index 83b45e3b4..ad87837fa 100644
+--- a/lib/pleroma/user.ex
++++ b/lib/pleroma/user.ex
+@@ -44,6 +44,8 @@ defmodule Pleroma.User do
+ alias Pleroma.Web.RelMe
+ alias Pleroma.Workers.BackgroundWorker
+
++ use Pleroma.Web, :verified_routes
++
+ require Logger
+
+ @type t :: %__MODULE__{}
+@@ -2447,12 +2449,7 @@ defp validate_rel_me_field(changeset, fields, raw_fields, %User{
+ end
+
+ if is_url(raw_value) do
+- frontend_url =
+- Pleroma.Web.Router.Helpers.redirect_url(
+- Pleroma.Web.Endpoint,
+- :redirector_with_meta,
+- nickname
+- )
++ frontend_url = url(~p[/#{nickname}])
+
+ possible_urls = [ap_id, frontend_url]
+
+diff --git a/lib/pleroma/web.ex b/lib/pleroma/web.ex
+index ecd98b6ca..5422e7896 100644
+--- a/lib/pleroma/web.ex
++++ b/lib/pleroma/web.ex
+@@ -27,6 +27,7 @@ defmodule Pleroma.Web do
+ alias Pleroma.Web.Plugs.ExpectPublicOrAuthenticatedCheckPlug
+ alias Pleroma.Web.Plugs.OAuthScopesPlug
+ alias Pleroma.Web.Plugs.PlugHelper
++ require Pleroma.Constants
+
+ def controller do
+ quote do
+@@ -37,7 +38,7 @@ def controller do
+ import Pleroma.Web.Gettext
+ import Pleroma.Web.TranslationHelpers
+
+- alias Pleroma.Web.Router.Helpers, as: Routes
++ unquote(verified_routes())
+
+ plug(:set_put_layout)
+
+@@ -184,7 +185,10 @@ def view do
+
+ # Import convenience functions from controllers
+ import Phoenix.Controller,
+- only: [get_flash: 1, get_flash: 2, view_module: 1, view_template: 1]
++ only: [view_module: 1, view_template: 1]
++
++ import Phoenix.Flash
++ alias Phoenix.Flash
+
+ # Include shared imports and aliases for views
+ unquote(view_helpers())
+@@ -218,7 +222,7 @@ def component do
+
+ def router do
+ quote do
+- use Phoenix.Router
++ use Phoenix.Router, helpers: false
+
+ import Plug.Conn
+ import Phoenix.Controller
+@@ -246,7 +250,24 @@ defp view_helpers do
+
+ import Pleroma.Web.ErrorHelpers
+ import Pleroma.Web.Gettext
+- alias Pleroma.Web.Router.Helpers, as: Routes
++ unquote(verified_routes())
++ end
++ end
++
++ def static_paths, do: Pleroma.Constants.static_only_files()
++
++ def verified_routes do
++ quote do
++ use Phoenix.VerifiedRoutes,
++ endpoint: Pleroma.Web.Endpoint,
++ router: Pleroma.Web.Router,
++ statics: Pleroma.Web.static_paths()
++ end
++ end
++
++ def mailer do
++ quote do
++ unquote(verified_routes())
+ end
+ end
+
+diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex
+index 649bf9095..e4c626d36 100644
+--- a/lib/pleroma/web/activity_pub/activity_pub.ex
++++ b/lib/pleroma/web/activity_pub/activity_pub.ex
+@@ -1792,6 +1792,11 @@ def pin_data_from_featured_collection(
+ end)
+ end
+
++ def pin_data_from_featured_collection(obj) do
++ Logger.error("Could not parse featured collection #{inspect(obj)}")
++ %{}
++ end
++
+ def fetch_and_prepare_featured_from_ap_id(nil) do
+ {:ok, %{}}
+ end
+diff --git a/lib/pleroma/web/activity_pub/builder.ex b/lib/pleroma/web/activity_pub/builder.ex
+index 6d39ad3a8..e67a14b58 100644
+--- a/lib/pleroma/web/activity_pub/builder.ex
++++ b/lib/pleroma/web/activity_pub/builder.ex
+@@ -18,6 +18,8 @@ defmodule Pleroma.Web.ActivityPub.Builder do
+ alias Pleroma.Web.CommonAPI.ActivityDraft
+ alias Pleroma.Web.Endpoint
+
++ use Pleroma.Web, :verified_routes
++
+ require Pleroma.Constants
+
+ def accept_or_reject(actor, activity, type) do
+@@ -402,6 +404,6 @@ def unpin(%User{} = user, object) do
+ end
+
+ defp pinned_url(nickname) when is_binary(nickname) do
+- Pleroma.Web.Router.Helpers.activity_pub_url(Pleroma.Web.Endpoint, :pinned, nickname)
++ url(~p[/users/#{nickname}/collections/featured])
+ end
+ end
+diff --git a/lib/pleroma/web/activity_pub/utils.ex b/lib/pleroma/web/activity_pub/utils.ex
+index 008aec475..f731b5286 100644
+--- a/lib/pleroma/web/activity_pub/utils.ex
++++ b/lib/pleroma/web/activity_pub/utils.ex
+@@ -16,10 +16,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
+ alias Pleroma.Web.ActivityPub.Visibility
+ alias Pleroma.Web.AdminAPI.AccountView
+ alias Pleroma.Web.Endpoint
+- alias Pleroma.Web.Router.Helpers
+
+ import Ecto.Query
+
++ use Pleroma.Web, :verified_routes
++
+ require Logger
+ require Pleroma.Constants
+
+@@ -124,19 +125,15 @@ def make_date do
+ end
+
+ def generate_activity_id do
+- generate_id("activities")
++ url(~p[/activities/#{UUID.generate()}])
+ end
+
+ def generate_context_id do
+- generate_id("contexts")
++ url(~p[/contexts/#{UUID.generate()}])
+ end
+
+ def generate_object_id do
+- Helpers.o_status_url(Endpoint, :object, UUID.generate())
+- end
+-
+- def generate_id(type) do
+- "#{Endpoint.url()}/#{type}/#{UUID.generate()}"
++ url(~p[/objects/#{UUID.generate()}])
+ end
+
+ def get_notified_from_object(%{"type" => type} = object) when type in @supported_object_types do
+@@ -154,7 +151,7 @@ def get_notified_from_object(object) do
+ Notification.get_notified_from_activity(%Activity{data: object}, false)
+ end
+
+- def maybe_create_context(context), do: context || generate_id("contexts")
++ def maybe_create_context(context), do: context || generate_context_id()
+
+ @doc """
+ Enqueues an activity for federation if it's local
+diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex
+index 7333fb2c1..82b59c47f 100644
+--- a/lib/pleroma/web/activity_pub/views/user_view.ex
++++ b/lib/pleroma/web/activity_pub/views/user_view.ex
+@@ -12,24 +12,22 @@ defmodule Pleroma.Web.ActivityPub.UserView do
+ alias Pleroma.Web.ActivityPub.ObjectView
+ alias Pleroma.Web.ActivityPub.Transmogrifier
+ alias Pleroma.Web.ActivityPub.Utils
+- alias Pleroma.Web.Endpoint
+- alias Pleroma.Web.Router.Helpers
+
+ require Pleroma.Web.ActivityPub.Transmogrifier
+
+ import Ecto.Query
+
+ def render("endpoints.json", %{user: %User{nickname: nil, local: true} = _user}) do
+- %{"sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox)}
++ %{"sharedInbox" => ~p"/inbox"}
+ end
+
+ def render("endpoints.json", %{user: %User{local: true} = _user}) do
+ %{
+- "oauthAuthorizationEndpoint" => Helpers.o_auth_url(Endpoint, :authorize),
+- "oauthRegistrationEndpoint" => Helpers.app_url(Endpoint, :create),
+- "oauthTokenEndpoint" => Helpers.o_auth_url(Endpoint, :token_exchange),
+- "sharedInbox" => Helpers.activity_pub_url(Endpoint, :inbox),
+- "uploadMedia" => Helpers.activity_pub_url(Endpoint, :upload_media)
++ "oauthAuthorizationEndpoint" => ~p"/oauth/authorize",
++ "oauthRegistrationEndpoint" => ~p"/api/v1/apps",
++ "oauthTokenEndpoint" => ~p"/oauth/token",
++ "sharedInbox" => ~p"/inbox",
++ "uploadMedia" => ~p"/api/ap/upload_media"
+ }
+ end
+
+diff --git a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
+index 1d7ac78a0..7344e1f77 100644
+--- a/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
++++ b/lib/pleroma/web/admin_api/controllers/admin_api_controller.ex
+@@ -17,9 +17,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIController do
+ alias Pleroma.Web.AdminAPI
+ alias Pleroma.Web.AdminAPI.AccountView
+ alias Pleroma.Web.AdminAPI.ModerationLogView
+- alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Plugs.OAuthScopesPlug
+- alias Pleroma.Web.Router
+
+ @users_page_size 50
+
+@@ -256,7 +254,7 @@ def get_password_reset(conn, %{"nickname" => nickname}) do
+ conn
+ |> json(%{
+ token: token.token,
+- link: Router.Helpers.reset_password_url(Endpoint, :reset, token.token)
++ link: url(~p[/api/v1/pleroma/password_reset/#{token.token}])
+ })
+ end
+
+diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex
+index e3a251ca1..64593767d 100644
+--- a/lib/pleroma/web/endpoint.ex
++++ b/lib/pleroma/web/endpoint.ex
+@@ -97,7 +97,7 @@ defmodule Pleroma.Web.Endpoint do
+ Plug.Static,
+ at: "/",
+ from: :pleroma,
+- only: Pleroma.Constants.static_only_files(),
++ only: Pleroma.Web.static_paths(),
+ # credo:disable-for-previous-line Credo.Check.Readability.MaxLineLength
+ gzip: true,
+ cache_control_for_etags: @static_cache_control,
+diff --git a/lib/pleroma/web/feed/user_controller.ex b/lib/pleroma/web/feed/user_controller.ex
+index dc3b1f94b..b320c9224 100644
+--- a/lib/pleroma/web/feed/user_controller.ex
++++ b/lib/pleroma/web/feed/user_controller.ex
+@@ -30,7 +30,7 @@ def feed_redirect(%{assigns: %{format: format}} = conn, _params)
+
+ def feed_redirect(conn, %{"nickname" => nickname}) do
+ with {_, %User{} = user} <- {:fetch_user, User.get_cached_by_nickname(nickname)} do
+- redirect(conn, external: "#{Routes.user_feed_url(conn, :feed, user.nickname)}.atom")
++ redirect(conn, external: "#{url(~p"/users/#{user.nickname}/feed")}.atom")
+ end
+ end
+
+diff --git a/lib/pleroma/web/masto_fe_controller.ex b/lib/pleroma/web/masto_fe_controller.ex
+index 7b6e01aad..b24f00620 100644
+--- a/lib/pleroma/web/masto_fe_controller.ex
++++ b/lib/pleroma/web/masto_fe_controller.ex
+@@ -34,9 +34,9 @@ def index(conn, _params) do
+
+ index =
+ if flavour == "fedibird-fe" do
+- "fedibird.index.html"
++ "fedibird.html"
+ else
+- "glitchsoc.index.html"
++ "glitchsoc.html"
+ end
+
+ conn
+diff --git a/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex b/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex
+index a9ccaa982..30e40ac42 100644
+--- a/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex
++++ b/lib/pleroma/web/mastodon_api/controllers/auth_controller.ex
+@@ -54,12 +54,7 @@ def login(conn, params) do
+ defp redirect_to_oauth_form(conn, _params) do
+ with {:ok, app} <- local_mastofe_app() do
+ path =
+- Routes.o_auth_path(conn, :authorize,
+- response_type: "code",
+- client_id: app.client_id,
+- redirect_uri: ".",
+- scope: Enum.join(app.scopes, " ")
+- )
++ ~p[/oauth/authorize?#{[response_type: "code", client_id: app.client_id, redirect_uri: ".", scope: Enum.join(app.scopes, " ")]}]
+
+ redirect(conn, to: path)
+ end
+@@ -91,7 +86,7 @@ def password_reset(conn, params) do
+ defp local_mastodon_post_login_path(conn) do
+ case get_session(conn, :return_to) do
+ nil ->
+- Routes.masto_fe_path(conn, :index, ["getting-started"])
++ ~p"/web/getting-started"
+
+ return_to ->
+ delete_session(conn, :return_to)
+diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
+index 47d1616c4..ac0955534 100644
+--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
++++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
+@@ -322,7 +322,7 @@ def render("show.json", %{activity: %{id: id, data: %{"object" => _object}} = ac
+
+ url =
+ if user.local do
+- Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity)
++ url(~p[/notice/#{activity}])
+ else
+ object.data["url"] || object.data["external_url"] || object.data["id"]
+ end
+diff --git a/lib/pleroma/web/mastodon_api/views/tag_view.ex b/lib/pleroma/web/mastodon_api/views/tag_view.ex
+index 02108c736..6d3ea3c1a 100644
+--- a/lib/pleroma/web/mastodon_api/views/tag_view.ex
++++ b/lib/pleroma/web/mastodon_api/views/tag_view.ex
+@@ -1,7 +1,6 @@
+ defmodule Pleroma.Web.MastodonAPI.TagView do
+ use Pleroma.Web, :view
+ alias Pleroma.User
+- alias Pleroma.Web.Router.Helpers
+
+ def render("index.json", %{tags: tags, for_user: user}) do
+ render_many(tags, __MODULE__, "show.json", %{for_user: user})
+@@ -17,7 +16,7 @@ def render("show.json", %{tag: tag, for_user: user}) do
+
+ %{
+ name: tag.name,
+- url: Helpers.tag_feed_url(Pleroma.Web.Endpoint, :feed, tag.name),
++ url: url(~p[/tags/#{tag.name}]),
+ history: [],
+ following: following
+ }
+diff --git a/lib/pleroma/web/metadata/providers/feed.ex b/lib/pleroma/web/metadata/providers/feed.ex
+index d0ab5c19e..15f47b843 100644
+--- a/lib/pleroma/web/metadata/providers/feed.ex
++++ b/lib/pleroma/web/metadata/providers/feed.ex
+@@ -3,9 +3,9 @@
+ # SPDX-License-Identifier: AGPL-3.0-only
+
+ defmodule Pleroma.Web.Metadata.Providers.Feed do
+- alias Pleroma.Web.Endpoint
+ alias Pleroma.Web.Metadata.Providers.Provider
+- alias Pleroma.Web.Router.Helpers
++
++ use Pleroma.Web, :verified_routes
+
+ @behaviour Provider
+
+@@ -16,7 +16,7 @@ def build_tags(%{user: user}) do
+ [
+ rel: "alternate",
+ type: "application/atom+xml",
+- href: Helpers.user_feed_path(Endpoint, :feed, user.nickname) <> ".atom"
++ href: ~p[/users/#{user.nickname}/feed.atom]
+ ], []}
+ ]
+ end
+diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex
+index b2497d14e..ab48ea272 100644
+--- a/lib/pleroma/web/metadata/providers/twitter_card.ex
++++ b/lib/pleroma/web/metadata/providers/twitter_card.ex
+@@ -10,6 +10,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
+ alias Pleroma.Web.Metadata.Providers.Provider
+ alias Pleroma.Web.Metadata.Utils
+
++ use Pleroma.Web, :verified_routes
++
+ @behaviour Provider
+ @media_types ["image", "audio", "video"]
+
+@@ -112,7 +114,7 @@ defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
+ defp build_attachments(_id, _object), do: []
+
+ defp player_url(id) do
+- Pleroma.Web.Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :notice_player, id)
++ url(~p[/notice/#{id}/embed_player])
+ end
+
+ # Videos have problems without dimensions, but we used to not provide WxH for images.
+diff --git a/lib/pleroma/web/o_auth/o_auth_controller.ex b/lib/pleroma/web/o_auth/o_auth_controller.ex
+index 277df1c46..ba33dc9e7 100644
+--- a/lib/pleroma/web/o_auth/o_auth_controller.ex
++++ b/lib/pleroma/web/o_auth/o_auth_controller.ex
+@@ -449,7 +449,7 @@ def prepare_request(%Plug.Conn{} = conn, %{
+ |> Map.put("state", state)
+
+ # Handing the request to Ueberauth
+- redirect(conn, to: Routes.o_auth_path(conn, :request, provider, params))
++ redirect(conn, to: ~p"/oauth/#{provider}?#{params}")
+ end
+
+ def request(%Plug.Conn{} = conn, params) do
+@@ -623,7 +623,7 @@ def login(%User{} = user, %App{} = app, requested_scopes) when is_list(requested
+ end
+
+ # Special case: Local MastodonFE
+- defp redirect_uri(%Plug.Conn{} = conn, "."), do: Routes.auth_url(conn, :login)
++ defp redirect_uri(_, "."), do: url(~p"/web/login")
+
+ defp redirect_uri(%Plug.Conn{}, redirect_uri), do: redirect_uri
+
+diff --git a/lib/pleroma/web/o_status/o_status_controller.ex b/lib/pleroma/web/o_status/o_status_controller.ex
+index 95a22895e..2b2872c9a 100644
+--- a/lib/pleroma/web/o_status/o_status_controller.ex
++++ b/lib/pleroma/web/o_status/o_status_controller.ex
+@@ -14,7 +14,6 @@ defmodule Pleroma.Web.OStatus.OStatusController do
+ alias Pleroma.Web.Fallback.RedirectController
+ alias Pleroma.Web.Metadata.PlayerView
+ alias Pleroma.Web.Plugs.RateLimiter
+- alias Pleroma.Web.Router
+
+ plug(
+ RateLimiter,
+@@ -87,7 +86,7 @@ def notice(%{assigns: %{format: format}} = conn, %{"id" => id}) do
+ %{
+ activity_id: activity.id,
+ object: object,
+- url: Router.Helpers.o_status_url(Endpoint, :notice, activity.id),
++ url: url(~p[/notice/#{activity.id}]),
+ user: user
+ }
+ )
+diff --git a/lib/pleroma/web/plugs/http_signature_plug.ex b/lib/pleroma/web/plugs/http_signature_plug.ex
+index 488108b08..eb6a46736 100644
+--- a/lib/pleroma/web/plugs/http_signature_plug.ex
++++ b/lib/pleroma/web/plugs/http_signature_plug.ex
+@@ -5,8 +5,9 @@
+ defmodule Pleroma.Web.Plugs.HTTPSignaturePlug do
+ import Plug.Conn
+ import Phoenix.Controller, only: [get_format: 1]
++
++ use Pleroma.Web, :verified_routes
+ alias Pleroma.Activity
+- alias Pleroma.Web.Router
+ alias Pleroma.Signature
+ alias Pleroma.Instances
+ require Logger
+@@ -32,10 +33,10 @@ def call(conn, _opts) do
+ end
+
+ def route_aliases(%{path_info: ["objects", id], query_string: query_string}) do
+- ap_id = Router.Helpers.o_status_url(Pleroma.Web.Endpoint, :object, id)
++ ap_id = url(~p[/objects/#{id}])
+
+ with %Activity{} = activity <- Activity.get_by_object_ap_id_with_object(ap_id) do
+- ["/notice/#{activity.id}", "/notice/#{activity.id}?#{query_string}"]
++ [~p"/notice/#{activity.id}", "/notice/#{activity.id}?#{query_string}"]
+ else
+ _ -> []
+ end
+diff --git a/lib/pleroma/web/static_fe/static_fe_controller.ex b/lib/pleroma/web/static_fe/static_fe_controller.ex
+index 56ee4e41e..f0d45293e 100644
+--- a/lib/pleroma/web/static_fe/static_fe_controller.ex
++++ b/lib/pleroma/web/static_fe/static_fe_controller.ex
+@@ -11,7 +11,6 @@ defmodule Pleroma.Web.StaticFE.StaticFEController do
+ alias Pleroma.Web.ActivityPub.ActivityPub
+ alias Pleroma.Web.ActivityPub.Visibility
+ alias Pleroma.Web.Metadata
+- alias Pleroma.Web.Router.Helpers
+
+ plug(:put_layout, :static_fe)
+ plug(:assign_id)
+@@ -111,11 +110,11 @@ def show(%{assigns: %{username_or_id: username_or_id, tab: tab}} = conn, params)
+ end
+
+ def show(%{assigns: %{object_id: _}} = conn, _params) do
+- url = Helpers.url(conn) <> conn.request_path
++ url = unverified_url(conn, conn.request_path)
+
+ case Activity.get_create_by_object_ap_id_with_object(url) do
+ %Activity{} = activity ->
+- to = Helpers.o_status_path(Pleroma.Web.Endpoint, :notice, activity)
++ to = ~p[/notice/#{activity}]
+ redirect(conn, to: to)
+
+ _ ->
+@@ -124,11 +123,11 @@ def show(%{assigns: %{object_id: _}} = conn, _params) do
+ end
+
+ def show(%{assigns: %{activity_id: _}} = conn, _params) do
+- url = Helpers.url(conn) <> conn.request_path
++ url = unverified_url(conn, conn.request_path)
+
+ case Activity.get_by_ap_id(url) do
+ %Activity{} = activity ->
+- to = Helpers.o_status_path(Pleroma.Web.Endpoint, :notice, activity)
++ to = ~p[/notice/#{activity}]
+ redirect(conn, to: to)
+
+ _ ->
+@@ -167,7 +166,7 @@ defp represent(%Activity{object: %Object{data: data}} = activity, selected) do
+
+ link =
+ case user.local do
+- true -> Helpers.o_status_url(Pleroma.Web.Endpoint, :notice, activity)
++ true -> ~p[/notice/#{activity}]
+ _ -> data["url"] || data["external_url"] || data["id"]
+ end
+
+diff --git a/lib/pleroma/web/static_fe/static_fe_view.ex b/lib/pleroma/web/static_fe/static_fe_view.ex
+index f0c9ddd22..c1d83c5a0 100644
+--- a/lib/pleroma/web/static_fe/static_fe_view.ex
++++ b/lib/pleroma/web/static_fe/static_fe_view.ex
+@@ -11,7 +11,6 @@ defmodule Pleroma.Web.StaticFE.StaticFEView do
+ alias Pleroma.Web.Gettext
+ alias Pleroma.Web.MediaProxy
+ al