Merge branch 'develop' into frontend-switcher-9000

This commit is contained in:
FloatingGhost 2023-04-14 16:56:10 +01:00
commit 4c9c959bb3
33 changed files with 338 additions and 148 deletions

View file

@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## Unreleased
## Added
- Nodeinfo keys for unauthenticated timeline visibility
- Option to disable federated timeline
- Option to make the bubble timeline publicly accessible
## 2023.03 ## 2023.03
## Fixed ## Fixed

View file

@ -1,4 +1,4 @@
FROM hexpm/elixir:1.13.4-erlang-24.3.4.5-alpine-3.15.6 FROM hexpm/elixir:1.14.3-erlang-25.3-alpine-3.17.2
ENV MIX_ENV=prod ENV MIX_ENV=prod
ENV ERL_EPMD_ADDRESS=127.0.0.1 ENV ERL_EPMD_ADDRESS=127.0.0.1

View file

@ -54,6 +54,9 @@ If your platform is not supported, or you just want to be able to edit the sourc
### Docker ### Docker
Docker installation is supported via [this setup](https://docs.akkoma.dev/stable/installation/docker_en/) Docker installation is supported via [this setup](https://docs.akkoma.dev/stable/installation/docker_en/)
### Packages
Akkoma is packaged for [YunoHost](https://yunohost.org) and can be found and installed from the [YunoHost app catalogue](https://yunohost.org/#/apps).
### Compilation Troubleshooting ### Compilation Troubleshooting
If you ever encounter compilation issues during the updating of Akkoma, you can try these commands and see if they fix things: If you ever encounter compilation issues during the updating of Akkoma, you can try these commands and see if they fix things:

View file

@ -261,7 +261,8 @@ config :pleroma, :instance,
privileged_staff: false, privileged_staff: false,
local_bubble: [], local_bubble: [],
max_frontend_settings_json_chars: 100_000, max_frontend_settings_json_chars: 100_000,
export_prometheus_metrics: true export_prometheus_metrics: true,
federated_timeline_available: true
config :pleroma, :welcome, config :pleroma, :welcome,
direct_message: [ direct_message: [
@ -813,7 +814,7 @@ config :pleroma, :majic_pool, size: 2
private_instance? = :if_instance_is_private private_instance? = :if_instance_is_private
config :pleroma, :restrict_unauthenticated, config :pleroma, :restrict_unauthenticated,
timelines: %{local: private_instance?, federated: private_instance?}, timelines: %{local: private_instance?, federated: private_instance?, bubble: true},
profiles: %{local: private_instance?, remote: private_instance?}, profiles: %{local: private_instance?, remote: private_instance?},
activities: %{local: private_instance?, remote: private_instance?} activities: %{local: private_instance?, remote: private_instance?}

View file

@ -0,0 +1,2 @@
hehe, /emoji/hehe.png, Akkoma
nothehe, /emoji/nothehe.png, Akkoma

View file

@ -969,6 +969,12 @@ config :pleroma, :config_description, [
key: :export_prometheus_metrics, key: :export_prometheus_metrics,
type: :boolean, type: :boolean,
description: "Enable prometheus metrics (at /api/v1/akkoma/metrics)" description: "Enable prometheus metrics (at /api/v1/akkoma/metrics)"
},
%{
key: :federated_timeline_available,
type: :boolean,
description:
"Let people view the 'firehose' feed of all public statuses from all instances."
} }
] ]
}, },
@ -2993,6 +2999,11 @@ config :pleroma, :config_description, [
key: :federated, key: :federated,
type: :boolean, type: :boolean,
description: "Disallow viewing the whole known network timeline." description: "Disallow viewing the whole known network timeline."
},
%{
key: :bubble,
type: :boolean,
description: "Disallow viewing the bubble timeline."
} }
] ]
}, },

View file

@ -1,8 +1,8 @@
## Required dependencies ## Required dependencies
* PostgreSQL 9.6+ * PostgreSQL 9.6+
* Elixir 1.12+ (1.13+ recommended) * Elixir 1.14+
* Erlang OTP 22.2+ * Erlang OTP 24+
* git * git
* file / libmagic * file / libmagic
* gcc (clang might also work) * gcc (clang might also work)

View file

@ -0,0 +1,9 @@
# Installing on Yunohost
[YunoHost](https://yunohost.org) is a server operating system aimed at self-hosting. The YunoHost community maintains a package of Akkoma which allows you to install Akkoma on YunoHost. You can install it via the normal way through the admin web interface, or through the CLI. More information can be found at [the repo of the package](https://github.com/YunoHost-Apps/akkoma_ynh).
## Questions
Questions and problems related to the YunoHost parts can be done through the [YunoHost channels](https://yunohost.org/en/help).
For questions about Akkoma, check out the [Akkoma community channels](../../#community-channels).

View file

@ -1,2 +1,2 @@
elixir_version=1.9.4 elixir_version=1.14.3
erlang_version=22.3.4.1 erlang_version=25.3

View file

@ -82,4 +82,46 @@ defmodule Mix.Tasks.Pleroma.Diagnostics do
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity) Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|> IO.puts() |> IO.puts()
end end
def run(["notifications", nickname]) do
start_pleroma()
user = Repo.get_by!(User, nickname: nickname)
account_ap_id = user.ap_id
options = %{account_ap_id: user.ap_id}
query =
user
|> Pleroma.Notification.for_user_query(options)
|> where([n, a], a.actor == ^account_ap_id)
|> limit(20)
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|> IO.puts()
end
def run(["known_network", nickname]) do
start_pleroma()
user = Repo.get_by!(User, nickname: nickname)
params =
%{}
|> Map.put(:type, ["Create"])
|> Map.put(:local_only, false)
|> Map.put(:blocking_user, user)
|> Map.put(:muting_user, user)
|> Map.put(:reply_filtering_user, user)
# Restricts unfederated content to authenticated users
|> Map.put(:includes_local_public, not is_nil(user))
|> Map.put(:restrict_unlisted, true)
query =
Pleroma.Web.ActivityPub.ActivityPub.fetch_activities_query(
[Pleroma.Constants.as_public()],
params
)
|> limit(20)
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|> IO.puts()
end
end end

View file

@ -277,6 +277,13 @@ defmodule Pleroma.Activity do
def get_create_by_object_ap_id_with_object(_), do: nil def get_create_by_object_ap_id_with_object(_), do: nil
def get_local_create_by_object_ap_id(ap_id) when is_binary(ap_id) do
ap_id
|> create_by_object_ap_id()
|> where(local: true)
|> Repo.one()
end
@spec create_by_id_with_object(String.t()) :: t() | nil @spec create_by_id_with_object(String.t()) :: t() | nil
def create_by_id_with_object(id) do def create_by_id_with_object(id) do
get_by_id_with_opts(id, preload: [:object], filter: [type: "Create"]) get_by_id_with_opts(id, preload: [:object], filter: [type: "Create"])

View file

@ -162,7 +162,7 @@ defmodule Pleroma.Instances.Instance do
%Instance{ %Instance{
host: Pleroma.Web.Endpoint.host(), host: Pleroma.Web.Endpoint.host(),
favicon: Pleroma.Web.Endpoint.url() <> "/favicon.png", favicon: Pleroma.Web.Endpoint.url() <> "/favicon.png",
nodeinfo: Pleroma.Web.Nodeinfo.NodeinfoController.raw_nodeinfo() nodeinfo: Pleroma.Web.Nodeinfo.Nodeinfo.get_nodeinfo("2.1")
} }
end end

View file

@ -366,21 +366,21 @@ defmodule Pleroma.User do
def invisible?(_), do: false def invisible?(_), do: false
def avatar_url(user, options \\ []) do def avatar_url(user, options \\ []) do
case user.avatar do default = Config.get([:assets, :default_user_avatar], "#{Endpoint.url()}/images/avi.png")
%{"url" => [%{"href" => href} | _]} -> do_optional_url(user.avatar, default, options)
href
_ ->
unless options[:no_default] do
Config.get([:assets, :default_user_avatar], "#{Endpoint.url()}/images/avi.png")
end
end
end end
def banner_url(user, options \\ []) do def banner_url(user, options \\ []) do
case user.banner do do_optional_url(user.banner, "#{Endpoint.url()}/images/banner.png", options)
%{"url" => [%{"href" => href} | _]} -> href end
_ -> !options[:no_default] && "#{Endpoint.url()}/images/banner.png"
defp do_optional_url(field, default, options) do
case field do
%{"url" => [%{"href" => href} | _]} when is_binary(href) ->
href
_ ->
unless options[:no_default], do: default
end end
end end

View file

@ -1502,13 +1502,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
@spec upload(Upload.source(), keyword()) :: {:ok, Object.t()} | {:error, any()} @spec upload(Upload.source(), keyword()) :: {:ok, Object.t()} | {:error, any()}
def upload(file, opts \\ []) do def upload(file, opts \\ []) do
with {:ok, data} <- Upload.store(file, opts) do with {:ok, data} <- Upload.store(sanitize_upload_file(file), opts) do
obj_data = Maps.put_if_present(data, "actor", opts[:actor]) obj_data = Maps.put_if_present(data, "actor", opts[:actor])
Repo.insert(%Object{data: obj_data}) Repo.insert(%Object{data: obj_data})
end end
end end
defp sanitize_upload_file(%Plug.Upload{filename: filename} = upload) when is_binary(filename) do
%Plug.Upload{
upload
| filename: Path.basename(filename)
}
end
defp sanitize_upload_file(upload), do: upload
@spec get_actor_url(any()) :: binary() | nil @spec get_actor_url(any()) :: binary() | nil
defp get_actor_url(url) when is_binary(url), do: url defp get_actor_url(url) when is_binary(url), do: url
defp get_actor_url(%{"href" => href}) when is_binary(href), do: href defp get_actor_url(%{"href" => href}) when is_binary(href), do: href

View file

@ -70,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
operationId: "TimelineController.public", operationId: "TimelineController.public",
responses: %{ responses: %{
200 => Operation.response("Array of Status", "application/json", array_of_statuses()), 200 => Operation.response("Array of Status", "application/json", array_of_statuses()),
401 => Operation.response("Error", "application/json", ApiError) 401 => Operation.response("Error", "application/json", ApiError),
404 => Operation.response("Error", "application/json", ApiError)
} }
} }
end end

View file

@ -16,7 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
alias Pleroma.Web.Plugs.RateLimiter alias Pleroma.Web.Plugs.RateLimiter
plug(Pleroma.Web.ApiSpec.CastAndValidate) plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(:skip_public_check when action in [:public, :hashtag]) plug(:skip_public_check when action in [:public, :hashtag, :bubble])
# TODO: Replace with a macro when there is a Phoenix release with the following commit in it: # TODO: Replace with a macro when there is a Phoenix release with the following commit in it:
# https://github.com/phoenixframework/phoenix/commit/2e8c63c01fec4dde5467dbbbf9705ff9e780735e # https://github.com/phoenixframework/phoenix/commit/2e8c63c01fec4dde5467dbbbf9705ff9e780735e
@ -28,19 +28,25 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
plug(RateLimiter, [name: :timeline, bucket_name: :list_timeline] when action == :list) plug(RateLimiter, [name: :timeline, bucket_name: :list_timeline] when action == :list)
plug(RateLimiter, [name: :timeline, bucket_name: :bubble_timeline] when action == :bubble) plug(RateLimiter, [name: :timeline, bucket_name: :bubble_timeline] when action == :bubble)
plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct, :bubble]) plug(OAuthScopesPlug, %{scopes: ["read:statuses"]} when action in [:home, :direct])
plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list) plug(OAuthScopesPlug, %{scopes: ["read:lists"]} when action == :list)
plug( plug(
OAuthScopesPlug, OAuthScopesPlug,
%{scopes: ["read:statuses"], fallback: :proceed_unauthenticated} %{scopes: ["read:statuses"], fallback: :proceed_unauthenticated}
when action in [:public, :hashtag] when action in [:public, :hashtag, :bubble]
) )
require Logger
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.TimelineOperation
# GET /api/v1/timelines/home # GET /api/v1/timelines/home
def home(%{assigns: %{user: user}} = conn, params) do def home(%{assigns: %{user: user}} = conn, params) do
%{nickname: nickname} = user
Logger.debug("TimelineController.home: #{nickname}")
followed_hashtags = followed_hashtags =
user user
|> User.followed_hashtags() |> User.followed_hashtags()
@ -58,11 +64,15 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:followed_hashtags, followed_hashtags) |> Map.put(:followed_hashtags, followed_hashtags)
|> Map.delete(:local) |> Map.delete(:local)
Logger.debug("TimelineController.home: #{nickname} - fetching activities")
activities = activities =
[user.ap_id | User.following(user)] [user.ap_id | User.following(user)]
|> ActivityPub.fetch_activities(params) |> ActivityPub.fetch_activities(params)
|> Enum.reverse() |> Enum.reverse()
Logger.debug("TimelineController.home: #{nickname} - rendering")
conn conn
|> add_link_headers(activities) |> add_link_headers(activities)
|> render("index.json", |> render("index.json",
@ -75,6 +85,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
# GET /api/v1/timelines/direct # GET /api/v1/timelines/direct
def direct(%{assigns: %{user: user}} = conn, params) do def direct(%{assigns: %{user: user}} = conn, params) do
Logger.debug("TimelineController.direct: #{user.nickname}")
params = params =
params params
|> Map.put(:type, "Create") |> Map.put(:type, "Create")
@ -82,11 +94,15 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:user, user) |> Map.put(:user, user)
|> Map.put(:visibility, "direct") |> Map.put(:visibility, "direct")
Logger.debug("TimelineController.direct: #{user.nickname} - fetching activities")
activities = activities =
[user.ap_id] [user.ap_id]
|> ActivityPub.fetch_activities_query(params) |> ActivityPub.fetch_activities_query(params)
|> Pagination.fetch_paginated(params) |> Pagination.fetch_paginated(params)
Logger.debug("TimelineController.direct: #{user.nickname} - rendering")
conn conn
|> add_link_headers(activities) |> add_link_headers(activities)
|> render("index.json", |> render("index.json",
@ -96,21 +112,22 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
) )
end end
defp restrict_unauthenticated?(true = _local_only) do defp restrict_unauthenticated?(type) do
Config.restrict_unauthenticated_access?(:timelines, :local) Config.restrict_unauthenticated_access?(:timelines, type)
end
defp restrict_unauthenticated?(_) do
Config.restrict_unauthenticated_access?(:timelines, :federated)
end end
# GET /api/v1/timelines/public # GET /api/v1/timelines/public
def public(%{assigns: %{user: user}} = conn, params) do def public(%{assigns: %{user: user}} = conn, params) do
Logger.debug("TimelineController.public")
local_only = params[:local] local_only = params[:local]
timeline_type = if local_only, do: :local, else: :federated
with {:enabled, true} <-
{:enabled, local_only || Config.get([:instance, :federated_timeline_available], true)},
{:authenticated, true} <-
{:authenticated, !(is_nil(user) and restrict_unauthenticated?(timeline_type))} do
Logger.debug("TimelineController.public: fetching activities")
if is_nil(user) and restrict_unauthenticated?(local_only) do
fail_on_bad_auth(conn)
else
activities = activities =
params params
|> Map.put(:type, ["Create"]) |> Map.put(:type, ["Create"])
@ -123,6 +140,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:includes_local_public, not is_nil(user)) |> Map.put(:includes_local_public, not is_nil(user))
|> ActivityPub.fetch_public_activities() |> ActivityPub.fetch_public_activities()
Logger.debug("TimelineController.public: rendering")
conn conn
|> add_link_headers(activities, %{"local" => local_only}) |> add_link_headers(activities, %{"local" => local_only})
|> render("index.json", |> render("index.json",
@ -131,20 +150,32 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
as: :activity, as: :activity,
with_muted: Map.get(params, :with_muted, false) with_muted: Map.get(params, :with_muted, false)
) )
else
{:enabled, false} ->
conn
|> put_status(404)
|> json(%{error: "Federated timeline is disabled"})
{:authenticated, false} ->
fail_on_bad_auth(conn)
end end
end end
# GET /api/v1/timelines/bubble # GET /api/v1/timelines/bubble
def bubble(%{assigns: %{user: user}} = conn, params) do def bubble(%{assigns: %{user: user}} = conn, params) do
Logger.debug("TimelineController.bubble")
if is_nil(user) and restrict_unauthenticated?(:bubble) do
fail_on_bad_auth(conn)
else
bubble_instances = bubble_instances =
Enum.uniq( Enum.uniq(
Config.get([:instance, :local_bubble], []) ++ Config.get([:instance, :local_bubble], []) ++
[Pleroma.Web.Endpoint.host()] [Pleroma.Web.Endpoint.host()]
) )
if is_nil(user) do Logger.debug("TimelineController.bubble: fetching activities")
fail_on_bad_auth(conn)
else
activities = activities =
params params
|> Map.put(:type, ["Create"]) |> Map.put(:type, ["Create"])
@ -154,6 +185,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|> Map.put(:instance, bubble_instances) |> Map.put(:instance, bubble_instances)
|> ActivityPub.fetch_public_activities() |> ActivityPub.fetch_public_activities()
Logger.debug("TimelineController.bubble: rendering")
conn conn
|> add_link_headers(activities) |> add_link_headers(activities)
|> render("index.json", |> render("index.json",
@ -195,7 +228,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
def hashtag(%{assigns: %{user: user}} = conn, params) do def hashtag(%{assigns: %{user: user}} = conn, params) do
local_only = params[:local] local_only = params[:local]
if is_nil(user) and restrict_unauthenticated?(local_only) do if is_nil(user) and restrict_unauthenticated?(if local_only, do: :local, else: :federated) do
fail_on_bad_auth(conn) fail_on_bad_auth(conn)
else else
activities = hashtag_fetching(params, user, local_only) activities = hashtag_fetching(params, user, local_only)

View file

@ -67,6 +67,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
"pleroma:api/v1/notifications:include_types_filter", "pleroma:api/v1/notifications:include_types_filter",
"quote_posting", "quote_posting",
"editing", "editing",
if !Enum.empty?(Config.get([:instance, :local_bubble], [])) do
"bubble_timeline"
end,
if Config.get([:media_proxy, :enabled]) do if Config.get([:media_proxy, :enabled]) do
"media_proxy" "media_proxy"
end, end,

View file

@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
alias Pleroma.Web.MastodonAPI.StatusView alias Pleroma.Web.MastodonAPI.StatusView
alias Pleroma.Web.MediaProxy alias Pleroma.Web.MediaProxy
alias Pleroma.Web.PleromaAPI.EmojiReactionController alias Pleroma.Web.PleromaAPI.EmojiReactionController
require Logger
import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2] import Pleroma.Web.ActivityPub.Visibility, only: [get_visibility: 1, visible_for_user?: 2]
@ -87,6 +88,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
defp reblogged?(_activity, _user), do: false defp reblogged?(_activity, _user), do: false
def render("index.json", opts) do def render("index.json", opts) do
Logger.debug("Rendering index")
reading_user = opts[:for] reading_user = opts[:for]
# To do: check AdminAPIControllerTest on the reasons behind nil activities in the list # To do: check AdminAPIControllerTest on the reasons behind nil activities in the list
activities = Enum.filter(opts.activities, & &1) activities = Enum.filter(opts.activities, & &1)
@ -136,8 +138,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
def render( def render(
"show.json", "show.json",
%{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts %{activity: %{id: id, data: %{"type" => "Announce", "object" => _object}} = activity} =
opts
) do ) do
Logger.debug("Rendering reblog #{id}")
user = CommonAPI.get_user(activity.data["actor"]) user = CommonAPI.get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"]) created_at = Utils.to_masto_date(activity.data["published"])
object = Object.normalize(activity, fetch: false) object = Object.normalize(activity, fetch: false)
@ -209,7 +213,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
} }
end end
def render("show.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do def render("show.json", %{activity: %{id: id, data: %{"object" => _object}} = activity} = opts) do
Logger.debug("Rendering status #{id}")
with %Object{} = object <- Object.normalize(activity, fetch: false) do with %Object{} = object <- Object.normalize(activity, fetch: false) do
user = CommonAPI.get_user(activity.data["actor"]) user = CommonAPI.get_user(activity.data["actor"])
user_follower_address = user.follower_address user_follower_address = user.follower_address
@ -428,6 +434,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end end
def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
Logger.debug("Rendering history for #{activity.id}")
object = Object.normalize(activity, fetch: false) object = Object.normalize(activity, fetch: false)
hashtags = Object.hashtags(object) hashtags = Object.hashtags(object)
@ -614,6 +621,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
def render("attachment_meta.json", _), do: nil def render("attachment_meta.json", _), do: nil
def render("context.json", %{activity: activity, activities: activities, user: user}) do def render("context.json", %{activity: activity, activities: activities, user: user}) do
Logger.debug("Rendering context for #{activity.id}")
%{ancestors: ancestors, descendants: descendants} = %{ancestors: ancestors, descendants: descendants} =
activities activities
|> Enum.reverse() |> Enum.reverse()

View file

@ -71,7 +71,15 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]), restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
skipThreadContainment: Config.get([:instance, :skip_thread_containment], false), skipThreadContainment: Config.get([:instance, :skip_thread_containment], false),
privilegedStaff: Config.get([:instance, :privileged_staff]), privilegedStaff: Config.get([:instance, :privileged_staff]),
localBubbleInstances: Config.get([:instance, :local_bubble], []) localBubbleInstances: Config.get([:instance, :local_bubble], []),
publicTimelineVisibility: %{
federated:
!Config.restrict_unauthenticated_access?(:timelines, :federated) &&
Config.get([:instance, :federated_timeline_available], true),
local: !Config.restrict_unauthenticated_access?(:timelines, :local),
bubble: !Config.restrict_unauthenticated_access?(:timelines, :bubble)
},
federatedTimelineAvailable: Config.get([:instance, :federated_timeline_available], true)
} }
} }
end end

View file

@ -11,6 +11,7 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
alias Pleroma.Web.Federator.Publisher alias Pleroma.Web.Federator.Publisher
alias Pleroma.Web.MastodonAPI.InstanceView alias Pleroma.Web.MastodonAPI.InstanceView
alias Pleroma.Web.Endpoint alias Pleroma.Web.Endpoint
alias Pleroma.Web.Nodeinfo.Nodeinfo
def schemas(conn, _params) do def schemas(conn, _params) do
response = %{ response = %{
@ -29,101 +30,15 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
json(conn, response) json(conn, response)
end end
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
# under software.
def raw_nodeinfo do
stats = Stats.get_stats()
staff_accounts =
User.all_superusers()
|> Enum.map(fn u -> u.ap_id end)
|> Enum.filter(fn u -> not Enum.member?(Config.get([:instance, :staff_transparency]), u) end)
features = InstanceView.features()
federation = InstanceView.federation()
%{
version: "2.0",
software: %{
name: Pleroma.Application.name() |> String.downcase(),
version: Pleroma.Application.version()
},
protocols: Publisher.gather_nodeinfo_protocol_names(),
services: %{
inbound: [],
outbound: []
},
openRegistrations: Config.get([:instance, :registrations_open]),
usage: %{
users: %{
total: Map.get(stats, :user_count, 0)
},
localPosts: Map.get(stats, :status_count, 0)
},
metadata: %{
nodeName: Config.get([:instance, :name]),
nodeDescription: Config.get([:instance, :description]),
private: !Config.get([:instance, :public], true),
suggestions: %{
enabled: false
},
staffAccounts: staff_accounts,
federation: federation,
pollLimits: Config.get([:instance, :poll_limits]),
postFormats: Config.get([:instance, :allowed_post_formats]),
uploadLimits: %{
general: Config.get([:instance, :upload_limit]),
avatar: Config.get([:instance, :avatar_upload_limit]),
banner: Config.get([:instance, :banner_upload_limit]),
background: Config.get([:instance, :background_upload_limit])
},
fieldsLimits: %{
maxFields: Config.get([:instance, :max_account_fields]),
maxRemoteFields: Config.get([:instance, :max_remote_account_fields]),
nameLength: Config.get([:instance, :account_field_name_length]),
valueLength: Config.get([:instance, :account_field_value_length])
},
accountActivationRequired: Config.get([:instance, :account_activation_required], false),
invitesEnabled: Config.get([:instance, :invites_enabled], false),
mailerEnabled: Config.get([Pleroma.Emails.Mailer, :enabled], false),
features: features,
restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
skipThreadContainment: Config.get([:instance, :skip_thread_containment], false),
localBubbleInstances: Config.get([:instance, :local_bubble], [])
}
}
end
# Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json # Schema definition: https://github.com/jhass/nodeinfo/blob/master/schemas/2.0/schema.json
# and https://github.com/jhass/nodeinfo/blob/master/schemas/2.1/schema.json # and https://github.com/jhass/nodeinfo/blob/master/schemas/2.1/schema.json
def nodeinfo(conn, %{"version" => "2.0"}) do def nodeinfo(conn, %{"version" => version}) when version in ["2.0", "2.1"] do
conn conn
|> put_resp_header( |> put_resp_header(
"content-type", "content-type",
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8" "application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8"
) )
|> json(raw_nodeinfo()) |> json(Nodeinfo.get_nodeinfo(version))
end
def nodeinfo(conn, %{"version" => "2.1"}) do
raw_response = raw_nodeinfo()
updated_software =
raw_response
|> Map.get(:software)
|> Map.put(:repository, Pleroma.Application.repository())
response =
raw_response
|> Map.put(:software, updated_software)
|> Map.put(:version, "2.1")
conn
|> put_resp_header(
"content-type",
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.1#; charset=utf-8"
)
|> json(response)
end end
def nodeinfo(conn, _) do def nodeinfo(conn, _) do

View file

@ -36,7 +36,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
def object(conn, _params) do def object(conn, _params) do
with id <- Endpoint.url() <> conn.request_path, with id <- Endpoint.url() <> conn.request_path,
{_, %Activity{} = activity} <- {_, %Activity{} = activity} <-
{:activity, Activity.get_create_by_object_ap_id_with_object(id)}, {:activity, Activity.get_local_create_by_object_ap_id(id)},
{_, true} <- {:public?, Visibility.is_public?(activity)}, {_, true} <- {:public?, Visibility.is_public?(activity)},
{_, false} <- {:local_public?, Visibility.is_local_public?(activity)} do {_, false} <- {:local_public?, Visibility.is_local_public?(activity)} do
redirect(conn, to: "/notice/#{activity.id}") redirect(conn, to: "/notice/#{activity.id}")

View file

@ -621,7 +621,6 @@ defmodule Pleroma.Web.Router do
get("/timelines/home", TimelineController, :home) get("/timelines/home", TimelineController, :home)
get("/timelines/direct", TimelineController, :direct) get("/timelines/direct", TimelineController, :direct)
get("/timelines/list/:list_id", TimelineController, :list) get("/timelines/list/:list_id", TimelineController, :list)
get("/timelines/bubble", TimelineController, :bubble)
get("/announcements", AnnouncementController, :index) get("/announcements", AnnouncementController, :index)
post("/announcements/:id/dismiss", AnnouncementController, :mark_read) post("/announcements/:id/dismiss", AnnouncementController, :mark_read)
@ -676,6 +675,7 @@ defmodule Pleroma.Web.Router do
get("/timelines/public", TimelineController, :public) get("/timelines/public", TimelineController, :public)
get("/timelines/tag/:tag", TimelineController, :hashtag) get("/timelines/tag/:tag", TimelineController, :hashtag)
get("/timelines/bubble", TimelineController, :bubble)
get("/polls/:id", PollController, :show) get("/polls/:id", PollController, :show)

View file

@ -5,7 +5,7 @@ defmodule Pleroma.Mixfile do
[ [
app: :pleroma, app: :pleroma,
version: version("3.7.1"), version: version("3.7.1"),
elixir: "~> 1.12", elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()), elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix] ++ Mix.compilers(), compilers: [:phoenix] ++ Mix.compilers(),
elixirc_options: [warnings_as_errors: warnings_as_errors()], elixirc_options: [warnings_as_errors: warnings_as_errors()],

View file

@ -27,7 +27,7 @@
"earmark": {:hex, :earmark, "1.4.37", "56ce845c543393aa3f9b294c818c3d783452a4a67e4ab18c4303a954a8b59363", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "d86d5e12868db86d5321b00e62a4bbcb4150346e4acc9a90a041fb188a5cb106"}, "earmark": {:hex, :earmark, "1.4.37", "56ce845c543393aa3f9b294c818c3d783452a4a67e4ab18c4303a954a8b59363", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "d86d5e12868db86d5321b00e62a4bbcb4150346e4acc9a90a041fb188a5cb106"},
"earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"}, "earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
"eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"},
"ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [: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", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, "ecto": {:hex, :ecto, "3.9.5", "9f0aa7ae44a1577b651c98791c6988cd1b69b21bc724e3fd67090b97f7604263", [: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", "d4f3115d8cbacdc0bfa4b742865459fb1371d0715515842a1fb17fe31920b74c"},
"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_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.10", "e14d400930f401ca9f541b3349212634e44027d7f919bbb71224d7ac0d0e8acd", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "505e8cd81e4f17c090be0f99e92b1b3f0fd915f98e76965130b8ccfb891e7088"}, "ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.10", "e14d400930f401ca9f541b3349212634e44027d7f919bbb71224d7ac0d0e8acd", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "505e8cd81e4f17c090be0f99e92b1b3f0fd915f98e76965130b8ccfb891e7088"},
"ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [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", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"}, "ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [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", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"},
@ -38,7 +38,7 @@
"ex_aws": {:hex, :ex_aws, "2.1.9", "dc4865ecc20a05190a34a0ac5213e3e5e2b0a75a0c2835e923ae7bfeac5e3c31", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "3e6c776703c9076001fbe1f7c049535f042cb2afa0d2cbd3b47cbc4e92ac0d10"}, "ex_aws": {:hex, :ex_aws, "2.1.9", "dc4865ecc20a05190a34a0ac5213e3e5e2b0a75a0c2835e923ae7bfeac5e3c31", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "3e6c776703c9076001fbe1f7c049535f042cb2afa0d2cbd3b47cbc4e92ac0d10"},
"ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"}, "ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"},
"ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"}, "ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"},
"ex_doc": {:hex, :ex_doc, "0.29.2", "dfa97532ba66910b2a3016a4bbd796f41a86fc71dd5227e96f4c8581fdf0fdf0", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "6b5d7139eda18a753e3250e27e4a929f8d2c880dd0d460cb9986305dea3e03af"}, "ex_doc": {:hex, :ex_doc, "0.29.3", "f07444bcafb302db86e4f02d8bbcd82f2e881a0dcf4f3e4740e4b8128b9353f7", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3dc6787d7b08801ec3b51e9bd26be5e8826fbf1a17e92d1ebc252e1a1c75bfe1"},
"ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"}, "ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"}, "ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
"excoveralls": {:hex, :excoveralls, "0.15.1", "83c8cf7973dd9d1d853dce37a2fb98aaf29b564bf7d01866e409abf59dac2c0e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f8416bd90c0082d56a2178cf46c837595a06575f70a5624f164a1ffe37de07e7"}, "excoveralls": {:hex, :excoveralls, "0.15.1", "83c8cf7973dd9d1d853dce37a2fb98aaf29b564bf7d01866e409abf59dac2c0e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f8416bd90c0082d56a2178cf46c837595a06575f70a5624f164a1ffe37de07e7"},
@ -86,14 +86,14 @@
"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_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.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"}, "phoenix_html": {:hex, :phoenix_html, "3.3.1", "4788757e804a30baac6b3fc9695bf5562465dd3f1da8eb8460ad5b404d9a2178", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "bed1906edd4906a15fd7b412b85b05e521e1f67c9a85418c55999277e553d0d3"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [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.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"}, "phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.7.2", "97cc4ff2dba1ebe504db72cb45098cb8e91f11160528b980bd282cc45c73b29c", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.5", [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.18.3", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6 or ~> 1.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "0e5fdf063c7a3b620c566a30fcf68b7ee02e5e46fe48ee46a6ec3ba382dc05b7"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.18.17", "74938b02f3c531bed3f87fe1ea39af6b5b2d26ab1405e77e76b8ef5df9ffa8a1", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "f4b5710e19a29b8dc93b7af4bab4739c067a3cb759af01ffc3057165453dce38"}, "phoenix_live_view": {:hex, :phoenix_live_view, "0.18.18", "1f38fbd7c363723f19aad1a04b5490ff3a178e37daaf6999594d5f34796c47fc", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.6.15 or ~> 1.7.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.3", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:phoenix_template, "~> 1.0", [hex: :phoenix_template, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a5810d0472f3189ede6d2a95bda7f31c6113156b91784a3426cb0ab6a6d85214"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"}, "phoenix_pubsub": {:hex, :phoenix_pubsub, "2.1.1", "ba04e489ef03763bf28a17eb2eaddc2c20c6d217e2150a61e3298b0f4c2012b5", [:mix], [], "hexpm", "81367c6d1eea5878ad726be80808eb5a787a23dee699f96e72b1109c57cdd8d9"},
"phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.4", "615f8f393135de7e0cbb4bd00ba238b1e0cd324b0d90efbaee613c2f02ca5e5c", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "3971221846232021ab5e3c7489fd62ec5bfd6a2e01cae10a317ccf6fb350571c"}, "phoenix_swoosh": {:hex, :phoenix_swoosh, "0.3.4", "615f8f393135de7e0cbb4bd00ba238b1e0cd324b0d90efbaee613c2f02ca5e5c", [:mix], [{:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:swoosh, "~> 1.0", [hex: :swoosh, repo: "hexpm", optional: false]}], "hexpm", "3971221846232021ab5e3c7489fd62ec5bfd6a2e01cae10a317ccf6fb350571c"},
"phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"}, "phoenix_template": {:hex, :phoenix_template, "1.0.1", "85f79e3ad1b0180abb43f9725973e3b8c2c3354a87245f91431eec60553ed3ef", [:mix], [{:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}], "hexpm", "157dc078f6226334c91cb32c1865bf3911686f8bcd6bcff86736f6253e6993ee"},
"phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [: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", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"}, "phoenix_view": {:hex, :phoenix_view, "2.0.2", "6bd4d2fd595ef80d33b439ede6a19326b78f0f1d8d62b9a318e3d9c1af351098", [: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", "a929e7230ea5c7ee0e149ffcf44ce7cf7f4b6d2bfe1752dd7c084cdff152d36f"},
"plug": {:hex, :plug, "1.14.0", "ba4f558468f69cbd9f6b356d25443d0b796fbdc887e03fa89001384a9cac638f", [:mix], [{:mime, "~> 1.0 or ~> 2.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.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "bf020432c7d4feb7b3af16a0c2701455cbbbb95e5b6866132cb09eb0c29adc14"}, "plug": {:hex, :plug, "1.14.2", "cff7d4ec45b4ae176a227acd94a7ab536d9b37b942c8e8fa6dfc0fff98ff4d80", [:mix], [{:mime, "~> 1.0 or ~> 2.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.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "842fc50187e13cf4ac3b253d47d9474ed6c296a8732752835ce4a86acdf68d13"},
"plug_cowboy": {:hex, :plug_cowboy, "2.6.0", "d1cf12ff96a1ca4f52207c5271a6c351a4733f413803488d75b70ccf44aebec2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "073cf20b753ce6682ed72905cd62a2d4bd9bad1bf9f7feb02a1b8e525bd94fa6"}, "plug_cowboy": {:hex, :plug_cowboy, "2.6.1", "9a3bbfceeb65eff5f39dab529e5cd79137ac36e913c02067dba3963a26efe9b2", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "de36e1a21f451a18b790f37765db198075c25875c64834bcc82d90b309eb6613"},
"plug_crypto": {:hex, :plug_crypto, "1.2.4", "34c380ef387cc7e8d537854ddd4b7096c79a4397d53587cb80419c782b03fdbc", [:mix], [], "hexpm", "4de415f03faec94d9da9be8c12cb51e9c98cbf66d732b6df669d4562d8e91acc"}, "plug_crypto": {:hex, :plug_crypto, "1.2.5", "918772575e48e81e455818229bf719d4ab4181fcbf7f85b68a35620f78d89ced", [:mix], [], "hexpm", "26549a1d6345e2172eb1c233866756ae44a9609bd33ee6f99147ab3fd87fd842"},
"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"}, "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, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"}, "poison": {:hex, :poison, "5.0.0", "d2b54589ab4157bbb82ec2050757779bfed724463a544b6e20d79855a9e43b24", [:mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "11dc6117c501b80c62a7594f941d043982a1bd05a1184280c0d9166eb4d8d3fc"},
"poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"}, "poolboy": {:hex, :poolboy, "1.5.2", "392b007a1693a64540cead79830443abf5762f5d30cf50bc95cb2c1aaafa006b", [:rebar3], [], "hexpm", "dad79704ce5440f3d5a3681c8590b9dc25d1a561e8f5a9c995281012860901e3"},
@ -117,7 +117,7 @@
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"}, "telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
"temple": {:git, "https://akkoma.dev/AkkomaGang/temple.git", "066a699ade472d8fa42a9d730b29a61af9bc8b59", [ref: "066a699ade472d8fa42a9d730b29a61af9bc8b59"]}, "temple": {:git, "https://akkoma.dev/AkkomaGang/temple.git", "066a699ade472d8fa42a9d730b29a61af9bc8b59", [ref: "066a699ade472d8fa42a9d730b29a61af9bc8b59"]},
"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"}, "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.9", "790cdfc4acfce434e442f98c02ea6d84d0239073bfd668968f82ac63e9a6788d", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "64691582e5bb87130f721fc709acfb70f24405833998fabf35be968984860ce1"}, "timex": {:hex, :timex, "3.7.11", "bb95cb4eb1d06e27346325de506bcc6c30f9c6dea40d1ebe390b262fad1862d1", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.20", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.1", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "8b9024f7efbabaf9bd7aa04f65cf8dcd7c9818ca5737677c7b76acbc6a94d1aa"},
"trailing_format_plug": {:hex, :trailing_format_plug, "0.0.7", "64b877f912cf7273bed03379936df39894149e35137ac9509117e59866e10e45", [:mix], [{:plug, "> 0.12.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "bd4fde4c15f3e993a999e019d64347489b91b7a9096af68b2bdadd192afa693f"}, "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.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"}, "tzdata": {:hex, :tzdata, "1.1.1", "20c8043476dfda8504952d00adac41c6eda23912278add38edc140ae0c5bcc46", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a69cec8352eafcd2e198dea28a34113b60fdc6cb57eb5ad65c10292a6ba89787"},
"ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"}, "ueberauth": {:hex, :ueberauth, "0.10.5", "806adb703df87e55b5615cf365e809f84c20c68aa8c08ff8a416a5a6644c4b02", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "3efd1f31d490a125c7ed453b926f7c31d78b97b8a854c755f5c40064bf3ac9e1"},

BIN
priv/static/emoji/hehe.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

View file

@ -2509,6 +2509,16 @@ defmodule Pleroma.UserTest do
assert User.avatar_url(user, no_default: true) == nil assert User.avatar_url(user, no_default: true) == nil
end end
test "avatar object with nil in href" do
user = insert(:user, avatar: %{"url" => [%{"href" => nil}]})
assert User.avatar_url(user) != nil
end
test "banner object with nil in href" do
user = insert(:user, banner: %{"url" => [%{"href" => nil}]})
assert User.banner_url(user) != nil
end
test "get_host/1" do test "get_host/1" do
user = insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain") user = insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain")
assert User.get_host(user) == "lain.com" assert User.get_host(user) == "lain.com"

View file

@ -1303,6 +1303,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
%{test_file: test_file} %{test_file: test_file}
end end
test "strips / from filename", %{test_file: file} do
file = %Plug.Upload{file | filename: "../../../../../nested/bad.jpg"}
{:ok, %Object{} = object} = ActivityPub.upload(file)
[%{"href" => href}] = object.data["url"]
assert Regex.match?(~r"/bad.jpg$", href)
refute Regex.match?(~r"/nested/", href)
end
test "sets a description if given", %{test_file: file} do test "sets a description if given", %{test_file: file} do
{:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file") {:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file")
assert object.data["name"] == "a cool file" assert object.data["name"] == "a cool file"

View file

@ -124,6 +124,23 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
end end
test "Do not allow nested filename", %{conn: conn, image: image} do
image = %Plug.Upload{
image
| filename: "../../../../../nested/file.jpg"
}
desc = "Description of the image"
media =
conn
|> put_req_header("content-type", "multipart/form-data")
|> post("/api/v1/media", %{"file" => image, "description" => desc})
|> json_response_and_validate_schema(:ok)
refute Regex.match?(~r"/nested/", media["url"])
end
end end
describe "Update media description" do describe "Update media description" do

View file

@ -408,6 +408,26 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert [] = result assert [] = result
end end
test "should return 404 if disabled" do
clear_config([:instance, :federated_timeline_available], false)
result =
build_conn()
|> get("/api/v1/timelines/public")
|> json_response_and_validate_schema(404)
assert %{"error" => "Federated timeline is disabled"} = result
end
test "should not return 404 if local is specified" do
clear_config([:instance, :federated_timeline_available], false)
result =
build_conn()
|> get("/api/v1/timelines/public?local=true")
|> json_response_and_validate_schema(200)
end
end end
defp local_and_remote_activities do defp local_and_remote_activities do
@ -1036,9 +1056,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
end end
describe "bubble" do describe "bubble" do
setup do: oauth_access(["read:statuses"]) test "filtering" do
%{conn: conn, user: user} = oauth_access(["read:statuses"])
test "filtering", %{conn: conn, user: user} do
clear_config([:instance, :local_bubble], []) clear_config([:instance, :local_bubble], [])
# our endpoint host has a port in it so let's set the AP ID # our endpoint host has a port in it so let's set the AP ID
local_user = insert(:user, %{ap_id: "https://localhost/users/user"}) local_user = insert(:user, %{ap_id: "https://localhost/users/user"})
@ -1072,6 +1091,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
assert local_activity.id in two_instances assert local_activity.id in two_instances
assert remote_activity.id in two_instances assert remote_activity.id in two_instances
end end
test "restrict_unauthenticated with bubble timeline", %{conn: conn} do
clear_config([:restrict_unauthenticated, :timelines, :bubble], true)
conn
|> get("/api/v1/timelines/bubble")
|> json_response_and_validate_schema(:unauthorized)
clear_config([:restrict_unauthenticated, :timelines, :bubble], false)
conn
|> get("/api/v1/timelines/bubble")
|> json_response_and_validate_schema(200)
end
end end
defp create_remote_activity(user) do defp create_remote_activity(user) do

View file

@ -396,6 +396,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data")) assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
end end
test "Strip / from upload files", %{user: user, conn: conn} do
new_image = %Plug.Upload{
content_type: "image/jpeg",
path: Path.absname("test/fixtures/image.jpg"),
filename: "../../../../nested/an_image.jpg"
}
assert user.avatar == %{}
res =
patch(conn, "/api/v1/accounts/update_credentials", %{
"avatar" => new_image,
"header" => new_image,
"pleroma_background_image" => new_image
})
assert user_response = json_response_and_validate_schema(res, 200)
assert user_response["avatar"]
assert user_response["header"]
assert user_response["pleroma"]["background_image"]
refute Regex.match?(~r"/nested/", user_response["avatar"])
refute Regex.match?(~r"/nested/", user_response["header"])
refute Regex.match?(~r"/nested/", user_response["pleroma"]["background_image"])
user = User.get_by_id(user.id)
refute user.avatar == %{}
end
test "requires 'write:accounts' permission" do test "requires 'write:accounts' permission" do
token1 = insert(:oauth_token, scopes: ["read"]) token1 = insert(:oauth_token, scopes: ["read"])
token2 = insert(:oauth_token, scopes: ["write", "follow"]) token2 = insert(:oauth_token, scopes: ["write", "follow"])

View file

@ -269,8 +269,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
} }
with_mock( with_mock(
Pleroma.Web.Nodeinfo.NodeinfoController, Pleroma.Web.Nodeinfo.Nodeinfo,
raw_nodeinfo: fn -> %{version: "2.0"} end get_nodeinfo: fn _ -> %{version: "2.0"} end
) do ) do
assert expected == assert expected ==
AccountView.render("show.json", %{user: user, skip_visibility_check: true}) AccountView.render("show.json", %{user: user, skip_visibility_check: true})

View file

@ -292,4 +292,38 @@ defmodule Pleroma.Web.NodeInfoTest do
assert response["metadata"]["federation"]["mrf_simple_info"] == expected_config assert response["metadata"]["federation"]["mrf_simple_info"] == expected_config
end end
end end
describe "public timeline visibility" do
test "shows public timeline visibility", %{conn: conn} do
clear_config([:restrict_unauthenticated, :timelines], %{local: false, federated: false})
response =
conn
|> get("/nodeinfo/2.1.json")
|> json_response(:ok)
assert response["metadata"]["publicTimelineVisibility"]["local"] == true
assert response["metadata"]["publicTimelineVisibility"]["federated"] == true
clear_config([:restrict_unauthenticated, :timelines], %{local: true, federated: false})
response =
conn
|> get("/nodeinfo/2.1.json")
|> json_response(:ok)
assert response["metadata"]["publicTimelineVisibility"]["local"] == false
assert response["metadata"]["publicTimelineVisibility"]["federated"] == true
clear_config([:restrict_unauthenticated, :timelines], %{local: false, federated: true})
response =
conn
|> get("/nodeinfo/2.1.json")
|> json_response(:ok)
assert response["metadata"]["publicTimelineVisibility"]["local"] == true
assert response["metadata"]["publicTimelineVisibility"]["federated"] == false
end
end
end end