diff options
Diffstat (limited to 'lib')
19 files changed, 330 insertions, 38 deletions
diff --git a/lib/mix/tasks/pleroma/ecto/rollback.ex b/lib/mix/tasks/pleroma/ecto/rollback.ex index 2b1d48048..025ebaf19 100644 --- a/lib/mix/tasks/pleroma/ecto/rollback.ex +++ b/lib/mix/tasks/pleroma/ecto/rollback.ex @@ -20,7 +20,8 @@ defmodule Mix.Tasks.Pleroma.Ecto.Rollback do      start: :boolean,      quiet: :boolean,      log_sql: :boolean, -    migrations_path: :string +    migrations_path: :string, +    env: :string    ]    @moduledoc """ @@ -59,7 +60,7 @@ defmodule Mix.Tasks.Pleroma.Ecto.Rollback do      level = Logger.level()      Logger.configure(level: :info) -    if Pleroma.Config.get(:env) == :test do +    if opts[:env] == "test" do        Logger.info("Rollback succesfully")      else        {:ok, _, _} = diff --git a/lib/pleroma/constants.ex b/lib/pleroma/constants.ex index a40741ba6..b24338cc6 100644 --- a/lib/pleroma/constants.ex +++ b/lib/pleroma/constants.ex @@ -18,7 +18,8 @@ defmodule Pleroma.Constants do        "emoji",        "context_id",        "deleted_activity_id", -      "pleroma_internal" +      "pleroma_internal", +      "generator"      ]    ) diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex index b096a9b1e..3e3f24c2c 100644 --- a/lib/pleroma/stats.ex +++ b/lib/pleroma/stats.ex @@ -23,7 +23,11 @@ defmodule Pleroma.Stats do    @impl true    def init(_args) do -    {:ok, nil, {:continue, :calculate_stats}} +    if Pleroma.Config.get(:env) != :test do +      {:ok, nil, {:continue, :calculate_stats}} +    else +      {:ok, calculate_stat_data()} +    end    end    @doc "Performs update stats" diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 51f5bc8ea..9942617d8 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -147,6 +147,7 @@ defmodule Pleroma.User do      field(:shared_inbox, :string)      field(:accepts_chat_messages, :boolean, default: nil)      field(:last_active_at, :naive_datetime) +    field(:disclose_client, :boolean, default: true)      embeds_one(        :notification_settings, @@ -513,7 +514,8 @@ defmodule Pleroma.User do          :pleroma_settings_store,          :is_discoverable,          :actor_type, -        :accepts_chat_messages +        :accepts_chat_messages, +        :disclose_client        ]      )      |> unique_constraint(:nickname) diff --git a/lib/pleroma/web.ex b/lib/pleroma/web.ex index c3aa39492..8630f244b 100644 --- a/lib/pleroma/web.ex +++ b/lib/pleroma/web.ex @@ -63,7 +63,8 @@ defmodule Pleroma.Web do        # Executed just before actual controller action, invokes before-action hooks (callbacks)        defp action(conn, params) do -        with %{halted: false} = conn <- maybe_drop_authentication_if_oauth_check_ignored(conn), +        with %{halted: false} = conn <- +               maybe_drop_authentication_if_oauth_check_ignored(conn),               %{halted: false} = conn <- maybe_perform_public_or_authenticated_check(conn),               %{halted: false} = conn <- maybe_perform_authenticated_check(conn),               %{halted: false} = conn <- maybe_halt_on_missing_oauth_scopes_check(conn) do @@ -232,4 +233,16 @@ defmodule Pleroma.Web do    def base_url do      Pleroma.Web.Endpoint.url()    end + +  # TODO: Change to Phoenix.Router.routes/1 for Phoenix 1.6.0+ +  def get_api_routes do +    Pleroma.Web.Router.__routes__() +    |> Enum.reject(fn r -> r.plug == Pleroma.Web.Fallback.RedirectController end) +    |> Enum.map(fn r -> +      r.path +      |> String.split("/", trim: true) +      |> List.first() +    end) +    |> Enum.uniq() +  end  end diff --git a/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex b/lib/pleroma/web/activity_pub/object_validators/audio_video_validator.ex index b3e738d8d..4a96fef52 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 @@ -70,19 +70,33 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AudioVideoValidator do      |> changeset(data)    end -  defp fix_url(%{"url" => url} = data) when is_list(url) do -    attachment = -      Enum.find(url, fn x -> -        mime_type = x["mimeType"] || x["mediaType"] || "" - -        is_map(x) and String.starts_with?(mime_type, ["video/", "audio/"]) +  defp find_attachment(url) do +    mpeg_url = +      Enum.find(url, fn +        %{"mediaType" => mime_type, "tag" => tags} when is_list(tags) -> +          mime_type == "application/x-mpegURL" + +        _ -> +          false        end) -    link_element = -      Enum.find(url, fn x -> -        mime_type = x["mimeType"] || x["mediaType"] || "" +    url +    |> Enum.concat(mpeg_url["tag"] || []) +    |> Enum.find(fn +      %{"mediaType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"]) +      %{"mimeType" => mime_type} -> String.starts_with?(mime_type, ["video/", "audio/"]) +      _ -> false +    end) +  end -        is_map(x) and mime_type == "text/html" +  defp fix_url(%{"url" => url} = data) when is_list(url) do +    attachment = find_attachment(url) + +    link_element = +      Enum.find(url, fn +        %{"mediaType" => "text/html"} -> true +        %{"mimeType" => "text/html"} -> true +        _ -> false        end)      data diff --git a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex index 3ea4af1e4..8d7577505 100644 --- a/lib/pleroma/web/api_spec/operations/admin/report_operation.ex +++ b/lib/pleroma/web/api_spec/operations/admin/report_operation.ex @@ -136,11 +136,11 @@ defmodule Pleroma.Web.ApiSpec.Admin.ReportOperation do      }    end -  defp report_state do +  def report_state do      %Schema{type: :string, enum: ["open", "closed", "resolved"]}    end -  defp id_param do +  def id_param do      Operation.parameter(:id, :path, FlakeID, "Report ID",        example: "9umDrYheeY451cQnEe",        required: true diff --git a/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex b/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex new file mode 100644 index 000000000..ee8870dc2 --- /dev/null +++ b/lib/pleroma/web/api_spec/operations/pleroma_report_operation.ex @@ -0,0 +1,97 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.ApiSpec.PleromaReportOperation do +  alias OpenApiSpex.Operation +  alias OpenApiSpex.Schema +  alias Pleroma.Web.ApiSpec.Admin.ReportOperation +  alias Pleroma.Web.ApiSpec.Schemas.Account +  alias Pleroma.Web.ApiSpec.Schemas.ApiError +  alias Pleroma.Web.ApiSpec.Schemas.FlakeID +  alias Pleroma.Web.ApiSpec.Schemas.Status + +  def open_api_operation(action) do +    operation = String.to_existing_atom("#{action}_operation") +    apply(__MODULE__, operation, []) +  end + +  def index_operation do +    %Operation{ +      tags: ["Reports"], +      summary: "Get a list of your own reports", +      operationId: "PleromaAPI.ReportController.index", +      security: [%{"oAuth" => ["read:reports"]}], +      parameters: [ +        Operation.parameter( +          :state, +          :query, +          ReportOperation.report_state(), +          "Filter by report state" +        ), +        Operation.parameter( +          :limit, +          :query, +          %Schema{type: :integer}, +          "The number of records to retrieve" +        ), +        Operation.parameter( +          :page, +          :query, +          %Schema{type: :integer, default: 1}, +          "Page number" +        ), +        Operation.parameter( +          :page_size, +          :query, +          %Schema{type: :integer, default: 50}, +          "Number number of log entries per page" +        ) +      ], +      responses: %{ +        200 => +          Operation.response("Response", "application/json", %Schema{ +            type: :object, +            properties: %{ +              total: %Schema{type: :integer}, +              reports: %Schema{ +                type: :array, +                items: report() +              } +            } +          }), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  def show_operation do +    %Operation{ +      tags: ["Reports"], +      summary: "Get an individual report", +      operationId: "PleromaAPI.ReportController.show", +      parameters: [ReportOperation.id_param()], +      security: [%{"oAuth" => ["read:reports"]}], +      responses: %{ +        200 => Operation.response("Report", "application/json", report()), +        404 => Operation.response("Not Found", "application/json", ApiError) +      } +    } +  end + +  # Copied from ReportOperation.report with removing notes +  defp report do +    %Schema{ +      type: :object, +      properties: %{ +        id: FlakeID, +        state: ReportOperation.report_state(), +        account: Account, +        actor: Account, +        content: %Schema{type: :string}, +        created_at: %Schema{type: :string, format: :"date-time"}, +        statuses: %Schema{type: :array, items: Status} +      } +    } +  end +end diff --git a/lib/pleroma/web/api_spec/schemas/scheduled_status.ex b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex index cc051046a..607586e32 100644 --- a/lib/pleroma/web/api_spec/schemas/scheduled_status.ex +++ b/lib/pleroma/web/api_spec/schemas/scheduled_status.ex @@ -30,7 +30,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do            visibility: %Schema{allOf: [VisibilityScope], nullable: true},            scheduled_at: %Schema{type: :string, format: :"date-time", nullable: true},            poll: StatusOperation.poll_params(), -          in_reply_to_id: %Schema{type: :string, nullable: true} +          in_reply_to_id: %Schema{type: :string, nullable: true}, +          expires_in: %Schema{type: :integer, nullable: true}          }        }      }, @@ -46,7 +47,8 @@ defmodule Pleroma.Web.ApiSpec.Schemas.ScheduledStatus do          scheduled_at: nil,          poll: nil,          idempotency: nil, -        in_reply_to_id: nil +        in_reply_to_id: nil, +        expires_in: nil        },        media_attachments: [Attachment.schema().example]      } diff --git a/lib/pleroma/web/api_spec/schemas/status.ex b/lib/pleroma/web/api_spec/schemas/status.ex index 61ebd8089..42fa98718 100644 --- a/lib/pleroma/web/api_spec/schemas/status.ex +++ b/lib/pleroma/web/api_spec/schemas/status.ex @@ -23,9 +23,10 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do        application: %Schema{          description: "The application used to post this status",          type: :object, +        nullable: true,          properties: %{            name: %Schema{type: :string}, -          website: %Schema{type: :string, nullable: true, format: :uri} +          website: %Schema{type: :string, format: :uri}          }        },        bookmarked: %Schema{type: :boolean, description: "Have you bookmarked this status?"}, @@ -291,7 +292,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do          "url" => "http://localhost:4001/users/nick6",          "username" => "nick6"        }, -      "application" => %{"name" => "Web", "website" => nil}, +      "application" => nil,        "bookmarked" => false,        "card" => nil,        "content" => "foobar", diff --git a/lib/pleroma/web/common_api/activity_draft.ex b/lib/pleroma/web/common_api/activity_draft.ex index fb059c27c..73f1b0931 100644 --- a/lib/pleroma/web/common_api/activity_draft.ex +++ b/lib/pleroma/web/common_api/activity_draft.ex @@ -190,6 +190,7 @@ defmodule Pleroma.Web.CommonAPI.ActivityDraft do        Utils.make_note_data(draft)        |> Map.put("emoji", emoji)        |> Map.put("source", draft.status) +      |> Map.put("generator", draft.params[:generator])      %__MODULE__{draft | object: object}    end diff --git a/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex b/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex new file mode 100644 index 000000000..f86d6b52b --- /dev/null +++ b/lib/pleroma/web/fallback/legacy_pleroma_api_rerouter_plug.ex @@ -0,0 +1,26 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.Fallback.LegacyPleromaApiRerouterPlug do +  alias Pleroma.Web.Endpoint +  alias Pleroma.Web.Fallback.RedirectController + +  def init(opts), do: opts + +  def call(%{path_info: ["api", "pleroma" | path_info_rest]} = conn, _opts) do +    new_path_info = ["api", "v1", "pleroma" | path_info_rest] +    new_request_path = Enum.join(new_path_info, "/") + +    conn +    |> Map.merge(%{ +      path_info: new_path_info, +      request_path: new_request_path +    }) +    |> Endpoint.call(conn.params) +  end + +  def call(conn, _opts) do +    RedirectController.api_not_implemented(conn, %{}) +  end +end diff --git a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex index 4cf2ee35c..b051fca74 100644 --- a/lib/pleroma/web/mastodon_api/controllers/status_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/status_controller.ex @@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do    alias Pleroma.Web.CommonAPI    alias Pleroma.Web.MastodonAPI.AccountView    alias Pleroma.Web.MastodonAPI.ScheduledActivityView +  alias Pleroma.Web.OAuth.Token    alias Pleroma.Web.Plugs.OAuthScopesPlug    alias Pleroma.Web.Plugs.RateLimiter @@ -138,7 +139,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do          _        )        when not is_nil(scheduled_at) do -    params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id]) +    params = +      Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id]) +      |> put_application(conn)      attrs = %{        params: Map.new(params, fn {key, value} -> {to_string(key), value} end), @@ -162,7 +165,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do    # Creates a regular status    def create(%{assigns: %{user: user}, body_params: %{status: _} = params} = conn, _) do -    params = Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id]) +    params = +      Map.put(params, :in_reply_to_status_id, params[:in_reply_to_id]) +      |> put_application(conn)      with {:ok, activity} <- CommonAPI.post(user, params) do        try_render(conn, "show.json", @@ -414,4 +419,15 @@ defmodule Pleroma.Web.MastodonAPI.StatusController do        as: :activity      )    end + +  defp put_application(params, %{assigns: %{token: %Token{user: %User{} = user} = token}} = _conn) do +    if user.disclose_client do +      %{client_name: client_name, website: website} = Repo.preload(token, :app).app +      Map.put(params, :generator, %{type: "Application", name: client_name, url: website}) +    else +      Map.put(params, :generator, nil) +    end +  end + +  defp put_application(params, _), do: Map.put(params, :generator, nil)  end diff --git a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex index 13774d237..453221f41 100644 --- a/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex +++ b/lib/pleroma/web/mastodon_api/views/scheduled_activity_view.ex @@ -37,7 +37,8 @@ defmodule Pleroma.Web.MastodonAPI.ScheduledActivityView do        visibility: params["visibility"],        scheduled_at: params["scheduled_at"],        poll: params["poll"], -      in_reply_to_id: params["in_reply_to_id"] +      in_reply_to_id: params["in_reply_to_id"], +      expires_in: params["expires_in"]      }      |> Pleroma.Maps.put_if_present(:media_ids, params["media_ids"])    end diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index bbe0b11ec..5b52b71dd 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -180,10 +180,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do        media_attachments: reblogged[:media_attachments] || [],        mentions: mentions,        tags: reblogged[:tags] || [], -      application: %{ -        name: "Web", -        website: nil -      }, +      application: build_application(activity_object.data["generator"]),        language: nil,        emojis: [],        pleroma: %{ @@ -350,10 +347,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do        poll: render(PollView, "show.json", object: object, for: opts[:for]),        mentions: mentions,        tags: build_tags(tags), -      application: %{ -        name: "Web", -        website: nil -      }, +      application: build_application(object.data["generator"]),        language: nil,        emojis: build_emojis(object.data["emoji"]),        pleroma: %{ @@ -542,4 +536,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do        me: !!(current_user && current_user.ap_id in users)      }    end + +  @spec build_application(map() | nil) :: map() | nil +  defp build_application(%{type: _type, name: name, url: url}), do: %{name: name, website: url} +  defp build_application(_), do: nil  end diff --git a/lib/pleroma/web/pleroma_api/controllers/report_controller.ex b/lib/pleroma/web/pleroma_api/controllers/report_controller.ex new file mode 100644 index 000000000..d93d7570a --- /dev/null +++ b/lib/pleroma/web/pleroma_api/controllers/report_controller.ex @@ -0,0 +1,46 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.ReportController do +  use Pleroma.Web, :controller + +  alias Pleroma.Activity +  alias Pleroma.Web.ActivityPub.Utils +  alias Pleroma.Web.AdminAPI.Report + +  action_fallback(Pleroma.Web.MastodonAPI.FallbackController) +  plug(Pleroma.Web.ApiSpec.CastAndValidate) +  plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read:reports"]}) + +  defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaReportOperation + +  @doc "GET /api/v0/pleroma/reports" +  def index(%{assigns: %{user: user}, body_params: params} = conn, _) do +    params = +      params +      |> Map.put(:actor_id, user.ap_id) + +    reports = Utils.get_reports(params, Map.get(params, :page, 1), Map.get(params, :size, 20)) + +    render(conn, "index.json", %{reports: reports, for: user}) +  end + +  @doc "GET /api/v0/pleroma/reports/:id" +  def show(%{assigns: %{user: user}} = conn, %{id: id}) do +    with %Activity{} = report <- Activity.get_report(id), +         true <- report.actor == user.ap_id, +         %{} = report_info <- Report.extract_report_info(report) do +      render(conn, "show.json", Map.put(report_info, :for, user)) +    else +      false -> +        {:error, :not_found} + +      nil -> +        {:error, :not_found} + +      e -> +        {:error, inspect(e)} +    end +  end +end diff --git a/lib/pleroma/web/pleroma_api/views/report_view.ex b/lib/pleroma/web/pleroma_api/views/report_view.ex new file mode 100644 index 000000000..a0b3f085c --- /dev/null +++ b/lib/pleroma/web/pleroma_api/views/report_view.ex @@ -0,0 +1,55 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/> +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Web.PleromaAPI.ReportView do +  use Pleroma.Web, :view + +  alias Pleroma.HTML +  alias Pleroma.Web.AdminAPI.Report +  alias Pleroma.Web.CommonAPI.Utils +  alias Pleroma.Web.MastodonAPI.AccountView +  alias Pleroma.Web.MastodonAPI.StatusView + +  def render("index.json", %{reports: reports, for: for_user}) do +    %{ +      reports: +        reports[:items] +        |> Enum.map(&Report.extract_report_info/1) +        |> Enum.map(&render(__MODULE__, "show.json", Map.put(&1, :for, for_user))), +      total: reports[:total] +    } +  end + +  def render("show.json", %{ +        report: report, +        user: actor, +        account: account, +        statuses: statuses, +        for: for_user +      }) do +    created_at = Utils.to_masto_date(report.data["published"]) + +    content = +      unless is_nil(report.data["content"]) do +        HTML.filter_tags(report.data["content"]) +      else +        nil +      end + +    %{ +      id: report.id, +      account: AccountView.render("show.json", %{user: account, for: for_user}), +      actor: AccountView.render("show.json", %{user: actor, for: for_user}), +      content: content, +      created_at: created_at, +      statuses: +        StatusView.render("index.json", %{ +          activities: statuses, +          as: :activity, +          for: for_user +        }), +      state: report.data["state"] +    } +  end +end diff --git a/lib/pleroma/web/plugs/frontend_static.ex b/lib/pleroma/web/plugs/frontend_static.ex index eecf16264..eb385e94d 100644 --- a/lib/pleroma/web/plugs/frontend_static.ex +++ b/lib/pleroma/web/plugs/frontend_static.ex @@ -10,6 +10,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do    """    @behaviour Plug +  @api_routes Pleroma.Web.get_api_routes() +    def file_path(path, frontend_type \\ :primary) do      if configuration = Pleroma.Config.get([:frontends, frontend_type]) do        instance_static_path = Pleroma.Config.get([:instance, :static_dir], "instance/static") @@ -34,7 +36,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do    end    def call(conn, opts) do -    with false <- invalid_path?(conn.path_info), +    with false <- api_route?(conn.path_info), +         false <- invalid_path?(conn.path_info),           frontend_type <- Map.get(opts, :frontend_type, :primary),           path when not is_nil(path) <- file_path("", frontend_type) do        call_static(conn, opts, path) @@ -52,6 +55,10 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do    defp invalid_path?([h | t], match), do: String.contains?(h, match) or invalid_path?(t)    defp invalid_path?([], _match), do: false +  defp api_route?([h | _]) when h in @api_routes, do: true +  defp api_route?([_ | t]), do: api_route?(t) +  defp api_route?([]), do: false +    defp call_static(conn, opts, from) do      opts = Map.put(opts, :from, from)      Plug.Static.call(conn, opts) diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index d71011033..72ad14f05 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -140,7 +140,7 @@ defmodule Pleroma.Web.Router do      plug(Pleroma.Web.Plugs.MappedSignatureToIdentityPlug)    end -  scope "/api/pleroma", Pleroma.Web.TwitterAPI do +  scope "/api/v1/pleroma", Pleroma.Web.TwitterAPI do      pipe_through(:pleroma_api)      get("/password_reset/:token", PasswordController, :reset, as: :reset_password) @@ -150,12 +150,12 @@ defmodule Pleroma.Web.Router do      get("/healthcheck", UtilController, :healthcheck)    end -  scope "/api/pleroma", Pleroma.Web do +  scope "/api/v1/pleroma", Pleroma.Web do      pipe_through(:pleroma_api)      post("/uploader_callback/:upload_path", UploaderController, :callback)    end -  scope "/api/pleroma/admin", Pleroma.Web.AdminAPI do +  scope "/api/v1/pleroma/admin", Pleroma.Web.AdminAPI do      pipe_through(:admin_api)      put("/users/disable_mfa", AdminAPIController, :disable_mfa) @@ -259,7 +259,7 @@ defmodule Pleroma.Web.Router do      post("/backups", AdminAPIController, :create_backup)    end -  scope "/api/pleroma/emoji", Pleroma.Web.PleromaAPI do +  scope "/api/v1/pleroma/emoji", Pleroma.Web.PleromaAPI do      scope "/pack" do        pipe_through(:admin_api) @@ -368,6 +368,12 @@ defmodule Pleroma.Web.Router do      get("/statuses/:id/reactions", EmojiReactionController, :index)    end +  scope "/api/v0/pleroma", Pleroma.Web.PleromaAPI do +    pipe_through(:authenticated_api) +    get("/reports", ReportController, :index) +    get("/reports/:id", ReportController, :show) +  end +    scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do      scope [] do        pipe_through(:authenticated_api) @@ -809,6 +815,7 @@ defmodule Pleroma.Web.Router do    scope "/", Pleroma.Web.Fallback do      get("/registration/:token", RedirectController, :registration_page)      get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta) +    match(:*, "/api/pleroma*path", LegacyPleromaApiRerouterPlug, [])      get("/api*path", RedirectController, :api_not_implemented)      get("/*path", RedirectController, :redirector_with_preload)  | 
