Merge branch 'develop' into stable
This commit is contained in:
commit
8504878187
51 changed files with 620 additions and 276 deletions
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -4,6 +4,20 @@ 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/).
|
||||
|
||||
## 2023.04
|
||||
|
||||
## Added
|
||||
- Nodeinfo keys for unauthenticated timeline visibility
|
||||
- Option to disable federated timeline
|
||||
- Option to make the bubble timeline publicly accessible
|
||||
- Ability to swap between installed standard frontends
|
||||
- *mastodon frontends are still not counted as standard frontends due to the complexity in serving them correctly*.
|
||||
|
||||
### Upgrade Notes
|
||||
- Elixir 1.14 is now required. If your distribution does not package this, you can
|
||||
use [asdf](https://asdf-vm.com/). At time of writing, elixir 1.14.3 / erlang 25.3
|
||||
is confirmed to work.
|
||||
|
||||
## 2023.03
|
||||
|
||||
## Fixed
|
||||
|
@ -19,6 +33,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
### Removed
|
||||
- Possibility of using the `style` parameter on `span` elements. This will break certain MFM parameters.
|
||||
- Option for "default" image description.
|
||||
|
||||
## 2023.02
|
||||
|
||||
|
|
|
@ -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 ERL_EPMD_ADDRESS=127.0.0.1
|
||||
|
|
|
@ -54,6 +54,9 @@ If your platform is not supported, or you just want to be able to edit the sourc
|
|||
### Docker
|
||||
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
|
||||
If you ever encounter compilation issues during the updating of Akkoma, you can try these commands and see if they fix things:
|
||||
|
||||
|
|
|
@ -65,7 +65,6 @@ config :pleroma, Pleroma.Upload,
|
|||
link_name: false,
|
||||
proxy_remote: false,
|
||||
filename_display_max_length: 30,
|
||||
default_description: nil,
|
||||
base_url: nil
|
||||
|
||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "uploads"
|
||||
|
@ -261,7 +260,8 @@ config :pleroma, :instance,
|
|||
privileged_staff: false,
|
||||
local_bubble: [],
|
||||
max_frontend_settings_json_chars: 100_000,
|
||||
export_prometheus_metrics: true
|
||||
export_prometheus_metrics: true,
|
||||
federated_timeline_available: true
|
||||
|
||||
config :pleroma, :welcome,
|
||||
direct_message: [
|
||||
|
@ -745,6 +745,9 @@ config :pleroma, :frontends,
|
|||
primary: %{"name" => "pleroma-fe", "ref" => "stable"},
|
||||
admin: %{"name" => "admin-fe", "ref" => "stable"},
|
||||
mastodon: %{"name" => "mastodon-fe", "ref" => "akkoma"},
|
||||
pickable: [
|
||||
"pleroma-fe/stable"
|
||||
],
|
||||
swagger: %{
|
||||
"name" => "swagger-ui",
|
||||
"ref" => "stable",
|
||||
|
@ -810,7 +813,7 @@ config :pleroma, :majic_pool, size: 2
|
|||
private_instance? = :if_instance_is_private
|
||||
|
||||
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?},
|
||||
activities: %{local: private_instance?, remote: private_instance?}
|
||||
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
hehe, /emoji/hehe.png, Akkoma
|
||||
nothehe, /emoji/nothehe.png, Akkoma
|
|
@ -969,6 +969,12 @@ config :pleroma, :config_description, [
|
|||
key: :export_prometheus_metrics,
|
||||
type: :boolean,
|
||||
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,
|
||||
type: :boolean,
|
||||
description: "Disallow viewing the whole known network timeline."
|
||||
},
|
||||
%{
|
||||
key: :bubble,
|
||||
type: :boolean,
|
||||
description: "Disallow viewing the bubble timeline."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -3148,6 +3159,12 @@ config :pleroma, :config_description, [
|
|||
description:
|
||||
"A map containing available frontends and parameters for their installation.",
|
||||
children: frontend_options
|
||||
},
|
||||
%{
|
||||
key: :pickable,
|
||||
type: {:list, :string},
|
||||
description:
|
||||
"A list containing all frontends users can pick as their preference, format is :name/:ref, e.g pleroma-fe/stable."
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -23,8 +23,7 @@ config :pleroma, :auth, oauth_consumer_strategies: []
|
|||
|
||||
config :pleroma, Pleroma.Upload,
|
||||
filters: [],
|
||||
link_name: false,
|
||||
default_description: :filename
|
||||
link_name: false
|
||||
|
||||
config :pleroma, Pleroma.Uploaders.Local, uploads: "test/uploads"
|
||||
|
||||
|
|
|
@ -562,7 +562,6 @@ the source code is here: [kocaptcha](https://github.com/koto-bank/kocaptcha). Th
|
|||
* `proxy_remote`: If you're using a remote uploader, Akkoma will proxy media requests instead of redirecting to it.
|
||||
* `proxy_opts`: Proxy options, see `Pleroma.ReverseProxy` documentation.
|
||||
* `filename_display_max_length`: Set max length of a filename to display. 0 = no limit. Default: 30.
|
||||
* `default_description`: Sets which default description an image has if none is set explicitly. Options: nil (default) - Don't set a default, :filename - use the filename of the file, a string (e.g. "attachment") - Use this string
|
||||
|
||||
!!! warning
|
||||
`strip_exif` has been replaced by `Pleroma.Upload.Filter.Mogrify`.
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## Required dependencies
|
||||
|
||||
* PostgreSQL 9.6+
|
||||
* Elixir 1.12+ (1.13+ recommended)
|
||||
* Erlang OTP 22.2+
|
||||
* Elixir 1.14+
|
||||
* Erlang OTP 24+
|
||||
* git
|
||||
* file / libmagic
|
||||
* gcc (clang might also work)
|
||||
|
|
9
docs/docs/installation/yunohost_en.md
Normal file
9
docs/docs/installation/yunohost_en.md
Normal 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).
|
|
@ -1,2 +1,2 @@
|
|||
elixir_version=1.9.4
|
||||
erlang_version=22.3.4.1
|
||||
elixir_version=1.14.3
|
||||
erlang_version=25.3
|
||||
|
|
|
@ -82,4 +82,46 @@ defmodule Mix.Tasks.Pleroma.Diagnostics do
|
|||
Ecto.Adapters.SQL.explain(Repo, :all, query, analyze: true, timeout: :infinity)
|
||||
|> IO.puts()
|
||||
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
|
||||
|
|
|
@ -277,6 +277,13 @@ defmodule Pleroma.Activity do
|
|||
|
||||
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
|
||||
def create_by_id_with_object(id) do
|
||||
get_by_id_with_opts(id, preload: [:object], filter: [type: "Create"])
|
||||
|
|
|
@ -162,7 +162,7 @@ defmodule Pleroma.Instances.Instance do
|
|||
%Instance{
|
||||
host: Pleroma.Web.Endpoint.host(),
|
||||
favicon: Pleroma.Web.Endpoint.url() <> "/favicon.png",
|
||||
nodeinfo: Pleroma.Web.Nodeinfo.NodeinfoController.raw_nodeinfo()
|
||||
nodeinfo: Pleroma.Web.Nodeinfo.Nodeinfo.get_nodeinfo("2.1")
|
||||
}
|
||||
end
|
||||
|
||||
|
|
|
@ -65,15 +65,6 @@ defmodule Pleroma.Upload do
|
|||
}
|
||||
defstruct [:id, :name, :tempfile, :content_type, :width, :height, :blurhash, :path]
|
||||
|
||||
defp get_description(opts, upload) do
|
||||
case {opts[:description], Pleroma.Config.get([Pleroma.Upload, :default_description])} do
|
||||
{description, _} when is_binary(description) -> description
|
||||
{_, :filename} -> upload.name
|
||||
{_, str} when is_binary(str) -> str
|
||||
_ -> ""
|
||||
end
|
||||
end
|
||||
|
||||
@spec store(source, options :: [option()]) :: {:ok, Map.t()} | {:error, any()}
|
||||
@doc "Store a file. If using a `Plug.Upload{}` as the source, be sure to use `Majic.Plug` to ensure its content_type and filename is correct."
|
||||
def store(upload, opts \\ []) do
|
||||
|
@ -82,7 +73,7 @@ defmodule Pleroma.Upload do
|
|||
with {:ok, upload} <- prepare_upload(upload, opts),
|
||||
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"},
|
||||
{:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload),
|
||||
description = get_description(opts, upload),
|
||||
description = Map.get(opts, :description) || "",
|
||||
{_, true} <-
|
||||
{:description_limit,
|
||||
String.length(description) <= Pleroma.Config.get([:instance, :description_limit])},
|
||||
|
|
|
@ -366,21 +366,21 @@ defmodule Pleroma.User do
|
|||
def invisible?(_), do: false
|
||||
|
||||
def avatar_url(user, options \\ []) do
|
||||
case user.avatar do
|
||||
%{"url" => [%{"href" => href} | _]} ->
|
||||
href
|
||||
|
||||
_ ->
|
||||
unless options[:no_default] do
|
||||
Config.get([:assets, :default_user_avatar], "#{Endpoint.url()}/images/avi.png")
|
||||
end
|
||||
end
|
||||
default = Config.get([:assets, :default_user_avatar], "#{Endpoint.url()}/images/avi.png")
|
||||
do_optional_url(user.avatar, default, options)
|
||||
end
|
||||
|
||||
def banner_url(user, options \\ []) do
|
||||
case user.banner do
|
||||
%{"url" => [%{"href" => href} | _]} -> href
|
||||
_ -> !options[:no_default] && "#{Endpoint.url()}/images/banner.png"
|
||||
do_optional_url(user.banner, "#{Endpoint.url()}/images/banner.png", options)
|
||||
end
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -1502,13 +1502,22 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
|||
|
||||
@spec upload(Upload.source(), keyword()) :: {:ok, Object.t()} | {:error, any()}
|
||||
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])
|
||||
|
||||
Repo.insert(%Object{data: obj_data})
|
||||
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
|
||||
defp get_actor_url(url) when is_binary(url), do: url
|
||||
defp get_actor_url(%{"href" => href}) when is_binary(href), do: href
|
||||
|
|
|
@ -8,7 +8,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
alias Pleroma.Activity
|
||||
alias Pleroma.Delivery
|
||||
alias Pleroma.Object
|
||||
alias Pleroma.Object.Fetcher
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||
alias Pleroma.Web.ActivityPub.InternalFetchActor
|
||||
|
@ -293,33 +292,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
|
|||
|> json("Invalid HTTP Signature")
|
||||
end
|
||||
|
||||
# POST /relay/inbox -or- POST /internal/fetch/inbox
|
||||
def inbox(conn, %{"type" => "Create"} = params) do
|
||||
if FederatingPlug.federating?() do
|
||||
post_inbox_relayed_create(conn, params)
|
||||
else
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("Not federating")
|
||||
end
|
||||
end
|
||||
|
||||
def inbox(conn, _params) do
|
||||
conn
|
||||
|> put_status(:bad_request)
|
||||
|> json("error, missing HTTP Signature")
|
||||
end
|
||||
|
||||
defp post_inbox_relayed_create(conn, params) do
|
||||
Logger.debug(
|
||||
"Signature missing or not from author, relayed Create message, fetching object from source"
|
||||
)
|
||||
|
||||
Fetcher.fetch_object_from_id(params["object"]["id"])
|
||||
|
||||
json(conn, "ok")
|
||||
end
|
||||
|
||||
defp represent_service_actor(%User{} = user, conn) do
|
||||
conn
|
||||
|> put_resp_content_type("application/activity+json")
|
||||
|
|
|
@ -108,15 +108,28 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
|
|||
Config.get([:mrf_simple, :reject], [])
|
||||
end
|
||||
|
||||
defp allowed_instances do
|
||||
Config.get([:mrf_simple, :accept])
|
||||
end
|
||||
|
||||
def should_federate?(url) do
|
||||
%{host: host} = URI.parse(url)
|
||||
|
||||
quarantined_instances =
|
||||
blocked_instances()
|
||||
with allowed <- allowed_instances(),
|
||||
false <- Enum.empty?(allowed) do
|
||||
allowed
|
||||
|> Pleroma.Web.ActivityPub.MRF.instance_list_from_tuples()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomains_regex()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomain_match?(host)
|
||||
else
|
||||
_ ->
|
||||
quarantined_instances =
|
||||
blocked_instances()
|
||||
|> Pleroma.Web.ActivityPub.MRF.instance_list_from_tuples()
|
||||
|> Pleroma.Web.ActivityPub.MRF.subdomains_regex()
|
||||
|
||||
!Pleroma.Web.ActivityPub.MRF.subdomain_match?(quarantined_instances, host)
|
||||
not Pleroma.Web.ActivityPub.MRF.subdomain_match?(quarantined_instances, host)
|
||||
end
|
||||
end
|
||||
|
||||
@spec recipients(User.t(), Activity.t()) :: list(User.t()) | []
|
||||
|
|
|
@ -5,6 +5,16 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
|
|||
alias Pleroma.Akkoma.FrontendSettingsProfile
|
||||
|
||||
@unauthenticated_access %{fallback: :proceed_unauthenticated, scopes: []}
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
@unauthenticated_access
|
||||
when action in [
|
||||
:available_frontends,
|
||||
:update_preferred_frontend
|
||||
]
|
||||
)
|
||||
|
||||
plug(
|
||||
OAuthScopesPlug,
|
||||
%{@unauthenticated_access | scopes: ["read:accounts"]}
|
||||
|
@ -93,4 +103,22 @@ defmodule Pleroma.Web.AkkomaAPI.FrontendSettingsController do
|
|||
|> json(profile.settings)
|
||||
end
|
||||
end
|
||||
|
||||
@doc "GET /api/v1/akkoma/preferred_frontend/available"
|
||||
def available_frontends(conn, _params) do
|
||||
available = Pleroma.Config.get([:frontends, :pickable])
|
||||
|
||||
conn
|
||||
|> json(available)
|
||||
end
|
||||
|
||||
@doc "PUT /api/v1/akkoma/preferred_frontend"
|
||||
def update_preferred_frontend(
|
||||
%{body_params: %{frontend_name: preferred_frontend}} = conn,
|
||||
_params
|
||||
) do
|
||||
conn
|
||||
|> put_resp_cookie("preferred_frontend", preferred_frontend)
|
||||
|> json(%{frontend_name: preferred_frontend})
|
||||
end
|
||||
end
|
||||
|
|
20
lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex
Normal file
20
lib/pleroma/web/akkoma_api/controllers/frontend_switcher.ex
Normal file
|
@ -0,0 +1,20 @@
|
|||
defmodule Pleroma.Web.AkkomaAPI.FrontendSwitcherController do
|
||||
use Pleroma.Web, :controller
|
||||
alias Pleroma.Config
|
||||
|
||||
@doc "GET /akkoma/frontend"
|
||||
def switch(conn, _params) do
|
||||
pickable = Config.get([:frontends, :pickable], [])
|
||||
|
||||
conn
|
||||
|> put_view(Pleroma.Web.AkkomaAPI.FrontendSwitcherView)
|
||||
|> render("switch.html", choices: pickable)
|
||||
end
|
||||
|
||||
@doc "POST /akkoma/frontend"
|
||||
def do_switch(conn, params) do
|
||||
conn
|
||||
|> put_resp_cookie("preferred_frontend", params["frontend"])
|
||||
|> html("<meta http-equiv=\"refresh\" content=\"0; url=/\">")
|
||||
end
|
||||
end
|
3
lib/pleroma/web/akkoma_api/views/frontend_switcher.ex
Normal file
3
lib/pleroma/web/akkoma_api/views/frontend_switcher.ex
Normal file
|
@ -0,0 +1,3 @@
|
|||
defmodule Pleroma.Web.AkkomaAPI.FrontendSwitcherView do
|
||||
use Pleroma.Web, :view
|
||||
end
|
|
@ -12,7 +12,7 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
|
|||
@spec list_profiles_operation() :: Operation.t()
|
||||
def list_profiles_operation() do
|
||||
%Operation{
|
||||
tags: ["Retrieve frontend setting profiles"],
|
||||
tags: ["Frontends"],
|
||||
summary: "Frontend Settings Profiles",
|
||||
description: "List frontend setting profiles",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.list_profiles",
|
||||
|
@ -37,7 +37,7 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
|
|||
@spec get_profile_operation() :: Operation.t()
|
||||
def get_profile_operation() do
|
||||
%Operation{
|
||||
tags: ["Retrieve frontend setting profile"],
|
||||
tags: ["Frontends"],
|
||||
summary: "Frontend Settings Profile",
|
||||
description: "Get frontend setting profile",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.get_profile",
|
||||
|
@ -60,7 +60,7 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
|
|||
@spec delete_profile_operation() :: Operation.t()
|
||||
def delete_profile_operation() do
|
||||
%Operation{
|
||||
tags: ["Delete frontend setting profile"],
|
||||
tags: ["Frontends"],
|
||||
summary: "Delete frontend Settings Profile",
|
||||
description: "Delete frontend setting profile",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.delete_profile",
|
||||
|
@ -76,7 +76,7 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
|
|||
@spec update_profile_operation() :: Operation.t()
|
||||
def update_profile_operation() do
|
||||
%Operation{
|
||||
tags: ["Update frontend setting profile"],
|
||||
tags: ["Frontends"],
|
||||
summary: "Frontend Settings Profile",
|
||||
description: "Update frontend setting profile",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.update_profile_operation",
|
||||
|
@ -90,6 +90,57 @@ defmodule Pleroma.Web.ApiSpec.FrontendSettingsOperation do
|
|||
}
|
||||
end
|
||||
|
||||
def available_frontends_operation() do
|
||||
%Operation{
|
||||
tags: ["Frontends"],
|
||||
summary: "Frontend Settings Profiles",
|
||||
description: "List frontend setting profiles",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.available_frontends",
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Frontends", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :string
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def update_preferred_frontend_operation() do
|
||||
%Operation{
|
||||
tags: ["Frontends"],
|
||||
summary: "Frontend Settings Profiles",
|
||||
description: "List frontend setting profiles",
|
||||
operationId: "AkkomaAPI.FrontendSettingsController.available_frontends",
|
||||
requestBody:
|
||||
request_body(
|
||||
"Frontend",
|
||||
%Schema{
|
||||
type: :object,
|
||||
required: [:frontend_name],
|
||||
properties: %{
|
||||
frontend_name: %Schema{
|
||||
type: :string,
|
||||
description: "Frontend name"
|
||||
}
|
||||
}
|
||||
},
|
||||
required: true
|
||||
),
|
||||
responses: %{
|
||||
200 =>
|
||||
Operation.response("Frontends", "application/json", %Schema{
|
||||
type: :array,
|
||||
items: %Schema{
|
||||
type: :string
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def frontend_name_param do
|
||||
Operation.parameter(:frontend_name, :path, :string, "Frontend name",
|
||||
example: "pleroma-fe",
|
||||
|
|
|
@ -70,7 +70,8 @@ defmodule Pleroma.Web.ApiSpec.TimelineOperation do
|
|||
operationId: "TimelineController.public",
|
||||
responses: %{
|
||||
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
|
||||
|
|
|
@ -20,7 +20,7 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|
|||
def redirector(conn, _params, code \\ 200) do
|
||||
conn
|
||||
|> put_resp_content_type("text/html")
|
||||
|> send_file(code, index_file_path())
|
||||
|> send_file(code, index_file_path(conn))
|
||||
end
|
||||
|
||||
def redirector_with_meta(conn, %{"maybe_nickname_or_id" => maybe_nickname_or_id} = params) do
|
||||
|
@ -33,7 +33,7 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|
|||
end
|
||||
|
||||
def redirector_with_meta(conn, params) do
|
||||
{:ok, index_content} = File.read(index_file_path())
|
||||
{:ok, index_content} = File.read(index_file_path(conn))
|
||||
|
||||
tags = build_tags(conn, params)
|
||||
preloads = preload_data(conn, params)
|
||||
|
@ -53,7 +53,7 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|
|||
end
|
||||
|
||||
def redirector_with_preload(conn, params) do
|
||||
{:ok, index_content} = File.read(index_file_path())
|
||||
{:ok, index_content} = File.read(index_file_path(conn))
|
||||
preloads = preload_data(conn, params)
|
||||
tags = Metadata.build_static_tags(params)
|
||||
title = "<title>#{Pleroma.Config.get([:instance, :name])}</title>"
|
||||
|
@ -77,8 +77,9 @@ defmodule Pleroma.Web.Fallback.RedirectController do
|
|||
|> text("")
|
||||
end
|
||||
|
||||
defp index_file_path do
|
||||
Pleroma.Web.Plugs.InstanceStatic.file_path("index.html")
|
||||
defp index_file_path(conn) do
|
||||
frontend_type = Pleroma.Web.Plugs.FrontendStatic.preferred_or_fallback(conn, :primary)
|
||||
Pleroma.Web.Plugs.InstanceStatic.file_path("index.html", frontend_type)
|
||||
end
|
||||
|
||||
defp build_tags(conn, params) do
|
||||
|
|
|
@ -16,7 +16,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
alias Pleroma.Web.Plugs.RateLimiter
|
||||
|
||||
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:
|
||||
# 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: :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: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
|
||||
|
||||
# GET /api/v1/timelines/home
|
||||
def home(%{assigns: %{user: user}} = conn, params) do
|
||||
%{nickname: nickname} = user
|
||||
|
||||
Logger.debug("TimelineController.home: #{nickname}")
|
||||
|
||||
followed_hashtags =
|
||||
user
|
||||
|> User.followed_hashtags()
|
||||
|
@ -58,11 +64,15 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
|> Map.put(:followed_hashtags, followed_hashtags)
|
||||
|> Map.delete(:local)
|
||||
|
||||
Logger.debug("TimelineController.home: #{nickname} - fetching activities")
|
||||
|
||||
activities =
|
||||
[user.ap_id | User.following(user)]
|
||||
|> ActivityPub.fetch_activities(params)
|
||||
|> Enum.reverse()
|
||||
|
||||
Logger.debug("TimelineController.home: #{nickname} - rendering")
|
||||
|
||||
conn
|
||||
|> add_link_headers(activities)
|
||||
|> render("index.json",
|
||||
|
@ -75,6 +85,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
|
||||
# GET /api/v1/timelines/direct
|
||||
def direct(%{assigns: %{user: user}} = conn, params) do
|
||||
Logger.debug("TimelineController.direct: #{user.nickname}")
|
||||
|
||||
params =
|
||||
params
|
||||
|> Map.put(:type, "Create")
|
||||
|
@ -82,11 +94,15 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
|> Map.put(:user, user)
|
||||
|> Map.put(:visibility, "direct")
|
||||
|
||||
Logger.debug("TimelineController.direct: #{user.nickname} - fetching activities")
|
||||
|
||||
activities =
|
||||
[user.ap_id]
|
||||
|> ActivityPub.fetch_activities_query(params)
|
||||
|> Pagination.fetch_paginated(params)
|
||||
|
||||
Logger.debug("TimelineController.direct: #{user.nickname} - rendering")
|
||||
|
||||
conn
|
||||
|> add_link_headers(activities)
|
||||
|> render("index.json",
|
||||
|
@ -96,21 +112,22 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
)
|
||||
end
|
||||
|
||||
defp restrict_unauthenticated?(true = _local_only) do
|
||||
Config.restrict_unauthenticated_access?(:timelines, :local)
|
||||
end
|
||||
|
||||
defp restrict_unauthenticated?(_) do
|
||||
Config.restrict_unauthenticated_access?(:timelines, :federated)
|
||||
defp restrict_unauthenticated?(type) do
|
||||
Config.restrict_unauthenticated_access?(:timelines, type)
|
||||
end
|
||||
|
||||
# GET /api/v1/timelines/public
|
||||
def public(%{assigns: %{user: user}} = conn, params) do
|
||||
Logger.debug("TimelineController.public")
|
||||
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 =
|
||||
params
|
||||
|> Map.put(:type, ["Create"])
|
||||
|
@ -123,6 +140,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
|> Map.put(:includes_local_public, not is_nil(user))
|
||||
|> ActivityPub.fetch_public_activities()
|
||||
|
||||
Logger.debug("TimelineController.public: rendering")
|
||||
|
||||
conn
|
||||
|> add_link_headers(activities, %{"local" => local_only})
|
||||
|> render("index.json",
|
||||
|
@ -131,20 +150,32 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
as: :activity,
|
||||
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
|
||||
|
||||
# GET /api/v1/timelines/bubble
|
||||
def bubble(%{assigns: %{user: user}} = conn, params) do
|
||||
bubble_instances =
|
||||
Enum.uniq(
|
||||
Config.get([:instance, :local_bubble], []) ++
|
||||
[Pleroma.Web.Endpoint.host()]
|
||||
)
|
||||
Logger.debug("TimelineController.bubble")
|
||||
|
||||
if is_nil(user) do
|
||||
if is_nil(user) and restrict_unauthenticated?(:bubble) do
|
||||
fail_on_bad_auth(conn)
|
||||
else
|
||||
bubble_instances =
|
||||
Enum.uniq(
|
||||
Config.get([:instance, :local_bubble], []) ++
|
||||
[Pleroma.Web.Endpoint.host()]
|
||||
)
|
||||
|
||||
Logger.debug("TimelineController.bubble: fetching activities")
|
||||
|
||||
activities =
|
||||
params
|
||||
|> Map.put(:type, ["Create"])
|
||||
|
@ -154,6 +185,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
|> Map.put(:instance, bubble_instances)
|
||||
|> ActivityPub.fetch_public_activities()
|
||||
|
||||
Logger.debug("TimelineController.bubble: rendering")
|
||||
|
||||
conn
|
||||
|> add_link_headers(activities)
|
||||
|> render("index.json",
|
||||
|
@ -195,7 +228,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do
|
|||
def hashtag(%{assigns: %{user: user}} = conn, params) do
|
||||
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)
|
||||
else
|
||||
activities = hashtag_fetching(params, user, local_only)
|
||||
|
|
|
@ -67,6 +67,9 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
|
|||
"pleroma:api/v1/notifications:include_types_filter",
|
||||
"quote_posting",
|
||||
"editing",
|
||||
if !Enum.empty?(Config.get([:instance, :local_bubble], [])) do
|
||||
"bubble_timeline"
|
||||
end,
|
||||
if Config.get([:media_proxy, :enabled]) do
|
||||
"media_proxy"
|
||||
end,
|
||||
|
|
|
@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
alias Pleroma.Web.MastodonAPI.StatusView
|
||||
alias Pleroma.Web.MediaProxy
|
||||
alias Pleroma.Web.PleromaAPI.EmojiReactionController
|
||||
require Logger
|
||||
|
||||
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
|
||||
|
||||
def render("index.json", opts) do
|
||||
Logger.debug("Rendering index")
|
||||
reading_user = opts[:for]
|
||||
# To do: check AdminAPIControllerTest on the reasons behind nil activities in the list
|
||||
activities = Enum.filter(opts.activities, & &1)
|
||||
|
@ -136,8 +138,10 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
|
||||
def render(
|
||||
"show.json",
|
||||
%{activity: %{data: %{"type" => "Announce", "object" => _object}} = activity} = opts
|
||||
%{activity: %{id: id, data: %{"type" => "Announce", "object" => _object}} = activity} =
|
||||
opts
|
||||
) do
|
||||
Logger.debug("Rendering reblog #{id}")
|
||||
user = CommonAPI.get_user(activity.data["actor"])
|
||||
created_at = Utils.to_masto_date(activity.data["published"])
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
@ -209,7 +213,9 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
}
|
||||
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
|
||||
user = CommonAPI.get_user(activity.data["actor"])
|
||||
user_follower_address = user.follower_address
|
||||
|
@ -428,6 +434,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
end
|
||||
|
||||
def render("history.json", %{activity: %{data: %{"object" => _object}} = activity} = opts) do
|
||||
Logger.debug("Rendering history for #{activity.id}")
|
||||
object = Object.normalize(activity, fetch: false)
|
||||
|
||||
hashtags = Object.hashtags(object)
|
||||
|
@ -614,6 +621,8 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
|
|||
def render("attachment_meta.json", _), do: nil
|
||||
|
||||
def render("context.json", %{activity: activity, activities: activities, user: user}) do
|
||||
Logger.debug("Rendering context for #{activity.id}")
|
||||
|
||||
%{ancestors: ancestors, descendants: descendants} =
|
||||
activities
|
||||
|> Enum.reverse()
|
||||
|
|
|
@ -71,7 +71,15 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
|
|||
restrictedNicknames: Config.get([Pleroma.User, :restricted_nicknames]),
|
||||
skipThreadContainment: Config.get([:instance, :skip_thread_containment], false),
|
||||
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
|
||||
|
|
|
@ -5,12 +5,8 @@
|
|||
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
||||
use Pleroma.Web, :controller
|
||||
|
||||
alias Pleroma.Config
|
||||
alias Pleroma.Stats
|
||||
alias Pleroma.User
|
||||
alias Pleroma.Web.Federator.Publisher
|
||||
alias Pleroma.Web.MastodonAPI.InstanceView
|
||||
alias Pleroma.Web.Endpoint
|
||||
alias Pleroma.Web.Nodeinfo.Nodeinfo
|
||||
|
||||
def schemas(conn, _params) do
|
||||
response = %{
|
||||
|
@ -29,101 +25,15 @@ defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
|||
json(conn, response)
|
||||
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
|
||||
# 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
|
||||
|> put_resp_header(
|
||||
"content-type",
|
||||
"application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8"
|
||||
)
|
||||
|> json(raw_nodeinfo())
|
||||
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)
|
||||
|> json(Nodeinfo.get_nodeinfo(version))
|
||||
end
|
||||
|
||||
def nodeinfo(conn, _) do
|
||||
|
|
|
@ -36,7 +36,7 @@ defmodule Pleroma.Web.OStatus.OStatusController do
|
|||
def object(conn, _params) do
|
||||
with id <- Endpoint.url() <> conn.request_path,
|
||||
{_, %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)},
|
||||
{_, false} <- {:local_public?, Visibility.is_local_public?(activity)} do
|
||||
redirect(conn, to: "/notice/#{activity.id}")
|
||||
|
|
|
@ -5,17 +5,23 @@
|
|||
defmodule Pleroma.Web.Plugs.FrontendStatic do
|
||||
require Pleroma.Constants
|
||||
|
||||
@frontend_cookie_name "preferred_frontend"
|
||||
|
||||
@moduledoc """
|
||||
This is a shim to call `Plug.Static` but with runtime `from` configuration`. It dispatches to the different frontends.
|
||||
"""
|
||||
@behaviour Plug
|
||||
|
||||
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")
|
||||
defp instance_static_path do
|
||||
Pleroma.Config.get([:instance, :static_dir], "instance/static")
|
||||
end
|
||||
|
||||
def file_path(path, frontend_type \\ :primary)
|
||||
|
||||
def file_path(path, frontend_type) when is_atom(frontend_type) do
|
||||
if configuration = Pleroma.Config.get([:frontends, frontend_type]) do
|
||||
Path.join([
|
||||
instance_static_path,
|
||||
instance_static_path(),
|
||||
"frontends",
|
||||
configuration["name"],
|
||||
configuration["ref"],
|
||||
|
@ -26,6 +32,15 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
|
|||
end
|
||||
end
|
||||
|
||||
def file_path(path, frontend_type) when is_binary(frontend_type) do
|
||||
Path.join([
|
||||
instance_static_path(),
|
||||
"frontends",
|
||||
frontend_type,
|
||||
path
|
||||
])
|
||||
end
|
||||
|
||||
def init(opts) do
|
||||
opts
|
||||
|> Keyword.put(:from, "__unconfigured_frontend_static_plug")
|
||||
|
@ -38,7 +53,8 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
|
|||
with false <- api_route?(conn.path_info),
|
||||
false <- invalid_path?(conn.path_info),
|
||||
true <- enabled?(opts[:if]),
|
||||
frontend_type <- Map.get(opts, :frontend_type, :primary),
|
||||
fallback_frontend_type <- Map.get(opts, :frontend_type, :primary),
|
||||
frontend_type <- preferred_or_fallback(conn, fallback_frontend_type),
|
||||
path when not is_nil(path) <- file_path("", frontend_type) do
|
||||
call_static(conn, opts, path)
|
||||
else
|
||||
|
@ -47,6 +63,31 @@ defmodule Pleroma.Web.Plugs.FrontendStatic do
|
|||
end
|
||||
end
|
||||
|
||||
def preferred_frontend(conn) do
|
||||
%{req_cookies: cookies} =
|
||||
conn
|
||||
|> Plug.Conn.fetch_cookies()
|
||||
|
||||
Map.get(cookies, @frontend_cookie_name)
|
||||
end
|
||||
|
||||
# Only override primary frontend
|
||||
def preferred_or_fallback(conn, :primary) do
|
||||
case preferred_frontend(conn) do
|
||||
nil ->
|
||||
:primary
|
||||
|
||||
frontend ->
|
||||
if Enum.member?(Pleroma.Config.get([:frontends, :pickable], []), frontend) do
|
||||
frontend
|
||||
else
|
||||
:primary
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def preferred_or_fallback(_conn, fallback), do: fallback
|
||||
|
||||
defp enabled?(if_opt) when is_function(if_opt), do: if_opt.()
|
||||
defp enabled?(true), do: true
|
||||
defp enabled?(_), do: false
|
||||
|
|
|
@ -8,6 +8,8 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
|
|||
|
||||
require Logger
|
||||
|
||||
@mix_env Mix.env()
|
||||
|
||||
def init(opts), do: opts
|
||||
|
||||
def call(conn, _options) do
|
||||
|
@ -114,7 +116,14 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlug do
|
|||
style_src = "style-src 'self' '#{nonce_tag}'"
|
||||
font_src = "font-src 'self'"
|
||||
|
||||
script_src = "script-src 'self' '#{nonce_tag}'"
|
||||
script_src = "script-src 'self' '#{nonce_tag}' "
|
||||
|
||||
script_src =
|
||||
if @mix_env == :dev do
|
||||
"script-src 'self' 'unsafe-eval' 'unsafe-inline'"
|
||||
else
|
||||
script_src
|
||||
end
|
||||
|
||||
report = if report_uri, do: ["report-uri ", report_uri, ";report-to csp-endpoint"]
|
||||
insecure = if scheme == "https", do: "upgrade-insecure-requests"
|
||||
|
|
|
@ -12,11 +12,11 @@ defmodule Pleroma.Web.Plugs.InstanceStatic do
|
|||
"""
|
||||
@behaviour Plug
|
||||
|
||||
def file_path(path) do
|
||||
def file_path(path, frontend_type \\ :primary) do
|
||||
instance_path =
|
||||
Path.join(Pleroma.Config.get([:instance, :static_dir], "instance/static/"), path)
|
||||
|
||||
frontend_path = Pleroma.Web.Plugs.FrontendStatic.file_path(path, :primary)
|
||||
frontend_path = Pleroma.Web.Plugs.FrontendStatic.file_path(path, frontend_type)
|
||||
|
||||
(File.exists?(instance_path) && instance_path) ||
|
||||
(frontend_path && File.exists?(frontend_path) && frontend_path) ||
|
||||
|
|
|
@ -466,6 +466,29 @@ defmodule Pleroma.Web.Router do
|
|||
put("/statuses/:id/emoji_reactions/:emoji", EmojiReactionController, :create)
|
||||
end
|
||||
|
||||
scope "/akkoma/", Pleroma.Web.AkkomaAPI do
|
||||
pipe_through(:browser)
|
||||
|
||||
get("/frontend", FrontendSwitcherController, :switch)
|
||||
post("/frontend", FrontendSwitcherController, :do_switch)
|
||||
end
|
||||
|
||||
scope "/api/v1/akkoma", Pleroma.Web.AkkomaAPI do
|
||||
pipe_through(:api)
|
||||
|
||||
get(
|
||||
"/api/v1/akkoma/preferred_frontend/available",
|
||||
FrontendSettingsController,
|
||||
:available_frontends
|
||||
)
|
||||
|
||||
put(
|
||||
"/api/v1/akkoma/preferred_frontend",
|
||||
FrontendSettingsController,
|
||||
:update_preferred_frontend
|
||||
)
|
||||
end
|
||||
|
||||
scope "/api/v1/akkoma", Pleroma.Web.AkkomaAPI do
|
||||
pipe_through(:authenticated_api)
|
||||
get("/metrics", MetricsController, :show)
|
||||
|
@ -598,7 +621,6 @@ defmodule Pleroma.Web.Router do
|
|||
get("/timelines/home", TimelineController, :home)
|
||||
get("/timelines/direct", TimelineController, :direct)
|
||||
get("/timelines/list/:list_id", TimelineController, :list)
|
||||
get("/timelines/bubble", TimelineController, :bubble)
|
||||
|
||||
get("/announcements", AnnouncementController, :index)
|
||||
post("/announcements/:id/dismiss", AnnouncementController, :mark_read)
|
||||
|
@ -653,6 +675,7 @@ defmodule Pleroma.Web.Router do
|
|||
|
||||
get("/timelines/public", TimelineController, :public)
|
||||
get("/timelines/tag/:tag", TimelineController, :hashtag)
|
||||
get("/timelines/bubble", TimelineController, :bubble)
|
||||
|
||||
get("/polls/:id", PollController, :show)
|
||||
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
<h2>Switch Frontend</h2>
|
||||
|
||||
<h3>After you submit, you will need to refresh manually to get your new frontend!</h3>
|
||||
|
||||
<%= form_for @conn, Routes.frontend_switcher_path(@conn, :do_switch), fn f -> %>
|
||||
<%= select(f, :frontend, @choices) %>
|
||||
|
||||
<%= submit do: "submit" %>
|
||||
<% end %>
|
||||
|
4
mix.exs
4
mix.exs
|
@ -4,8 +4,8 @@ defmodule Pleroma.Mixfile do
|
|||
def project do
|
||||
[
|
||||
app: :pleroma,
|
||||
version: version("3.7.1"),
|
||||
elixir: "~> 1.12",
|
||||
version: version("3.7.2"),
|
||||
elixir: "~> 1.14",
|
||||
elixirc_paths: elixirc_paths(Mix.env()),
|
||||
compilers: [:phoenix] ++ Mix.compilers(),
|
||||
elixirc_options: [warnings_as_errors: warnings_as_errors()],
|
||||
|
|
14
mix.lock
14
mix.lock
|
@ -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_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
|
||||
"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_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"},
|
||||
|
@ -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_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_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_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"},
|
||||
|
@ -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_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_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_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_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_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_crypto": {:hex, :plug_crypto, "1.2.4", "34c380ef387cc7e8d537854ddd4b7096c79a4397d53587cb80419c782b03fdbc", [:mix], [], "hexpm", "4de415f03faec94d9da9be8c12cb51e9c98cbf66d732b6df669d4562d8e91acc"},
|
||||
"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.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.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"},
|
||||
"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"},
|
||||
|
@ -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"},
|
||||
"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"},
|
||||
"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"},
|
||||
"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"},
|
||||
|
|
BIN
priv/static/emoji/hehe.png
Normal file
BIN
priv/static/emoji/hehe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
priv/static/emoji/nothehe.png
Normal file
BIN
priv/static/emoji/nothehe.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 13 KiB |
|
@ -54,7 +54,7 @@ defmodule Pleroma.UploadTest do
|
|||
assert result ==
|
||||
%{
|
||||
"id" => result["id"],
|
||||
"name" => "image.jpg",
|
||||
"name" => "",
|
||||
"type" => "Document",
|
||||
"mediaType" => "image/jpeg",
|
||||
"url" => [
|
||||
|
@ -154,19 +154,6 @@ defmodule Pleroma.UploadTest do
|
|||
"e30397b58d226d6583ab5b8b3c5defb0c682bda5c31ef07a9f57c1c4986e3781.jpg"
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder without deduping" do
|
||||
File.cp!("test/fixtures/image.jpg", "test/fixtures/image_tmp.jpg")
|
||||
|
||||
file = %Plug.Upload{
|
||||
content_type: "image/jpeg",
|
||||
path: Path.absname("test/fixtures/image_tmp.jpg"),
|
||||
filename: "an [image.jpg"
|
||||
}
|
||||
|
||||
{:ok, data} = Upload.store(file)
|
||||
assert data["name"] == "an [image.jpg"
|
||||
end
|
||||
|
||||
test "fixes incorrect content type when base64 is given" do
|
||||
params = %{
|
||||
img: "data:image/png;base64,#{Base.encode64(File.read!("test/fixtures/image.jpg"))}"
|
||||
|
@ -184,7 +171,7 @@ defmodule Pleroma.UploadTest do
|
|||
}
|
||||
|
||||
{:ok, data} = Upload.store(params)
|
||||
assert String.ends_with?(data["name"], ".jpg")
|
||||
assert String.ends_with?(List.first(data["url"])["href"], ".jpg")
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder with anonymizing filename" do
|
||||
|
|
|
@ -2509,6 +2509,16 @@ defmodule Pleroma.UserTest do
|
|||
assert User.avatar_url(user, no_default: true) == nil
|
||||
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
|
||||
user = insert(:user, ap_id: "https://lain.com/users/lain", nickname: "lain")
|
||||
assert User.get_host(user) == "lain.com"
|
||||
|
|
|
@ -662,35 +662,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
|||
assert_receive {:mix_shell, :info, ["https://relay.mastodon.host/actor"]}
|
||||
end
|
||||
|
||||
@tag capture_log: true
|
||||
test "without valid signature, " <>
|
||||
"it only accepts Create activities and requires enabled federation",
|
||||
%{conn: conn} do
|
||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Jason.decode!()
|
||||
non_create_data = File.read!("test/fixtures/mastodon-announce.json") |> Jason.decode!()
|
||||
|
||||
conn = put_req_header(conn, "content-type", "application/activity+json")
|
||||
|
||||
clear_config([:instance, :federating], false)
|
||||
|
||||
conn
|
||||
|> post("/inbox", data)
|
||||
|> json_response(403)
|
||||
|
||||
conn
|
||||
|> post("/inbox", non_create_data)
|
||||
|> json_response(403)
|
||||
|
||||
clear_config([:instance, :federating], true)
|
||||
|
||||
ret_conn = post(conn, "/inbox", data)
|
||||
assert "ok" == json_response(ret_conn, 200)
|
||||
|
||||
conn
|
||||
|> post("/inbox", non_create_data)
|
||||
|> json_response(400)
|
||||
end
|
||||
|
||||
test "accepts Add/Remove activities", %{conn: conn} do
|
||||
object_id = "c61d6733-e256-4fe1-ab13-1e369789423f"
|
||||
|
||||
|
|
|
@ -1303,33 +1303,19 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
|||
%{test_file: test_file}
|
||||
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
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file, description: "a cool file")
|
||||
assert object.data["name"] == "a cool file"
|
||||
end
|
||||
|
||||
test "it sets the default description depending on the configuration", %{test_file: file} do
|
||||
clear_config([Pleroma.Upload, :default_description])
|
||||
|
||||
clear_config([Pleroma.Upload, :default_description], nil)
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
assert object.data["name"] == ""
|
||||
|
||||
clear_config([Pleroma.Upload, :default_description], :filename)
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
assert object.data["name"] == "an_image.jpg"
|
||||
|
||||
clear_config([Pleroma.Upload, :default_description], "unnamed attachment")
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
assert object.data["name"] == "unnamed attachment"
|
||||
end
|
||||
|
||||
test "copies the file to the configured folder", %{test_file: file} do
|
||||
clear_config([Pleroma.Upload, :default_description], :filename)
|
||||
{:ok, %Object{} = object} = ActivityPub.upload(file)
|
||||
assert object.data["name"] == "an_image.jpg"
|
||||
end
|
||||
|
||||
test "works with base64 encoded images" do
|
||||
file = %{
|
||||
img: data_uri()
|
||||
|
|
|
@ -124,6 +124,23 @@ defmodule Pleroma.Web.MastodonAPI.MediaControllerTest do
|
|||
|
||||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
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
|
||||
|
||||
describe "Update media description" do
|
||||
|
|
|
@ -408,6 +408,25 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
|
||||
assert [] = result
|
||||
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)
|
||||
|
||||
build_conn()
|
||||
|> get("/api/v1/timelines/public?local=true")
|
||||
|> json_response_and_validate_schema(200)
|
||||
end
|
||||
end
|
||||
|
||||
defp local_and_remote_activities do
|
||||
|
@ -1036,9 +1055,8 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
end
|
||||
|
||||
describe "bubble" do
|
||||
setup do: oauth_access(["read:statuses"])
|
||||
|
||||
test "filtering", %{conn: conn, user: user} do
|
||||
test "filtering" do
|
||||
%{conn: conn, user: user} = oauth_access(["read:statuses"])
|
||||
clear_config([:instance, :local_bubble], [])
|
||||
# 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"})
|
||||
|
@ -1060,7 +1078,7 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
|
||||
assert local_activity.id in one_instance
|
||||
|
||||
# If we have others, also include theirs
|
||||
# If we have others, also include theirs
|
||||
clear_config([:instance, :local_bubble], ["example.com"])
|
||||
|
||||
two_instances =
|
||||
|
@ -1072,6 +1090,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineControllerTest do
|
|||
assert local_activity.id in two_instances
|
||||
assert remote_activity.id in two_instances
|
||||
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
|
||||
|
||||
defp create_remote_activity(user) do
|
||||
|
|
|
@ -396,6 +396,34 @@ defmodule Pleroma.Web.MastodonAPI.UpdateCredentialsTest do
|
|||
assert :ok == File.rm(Path.absname("test/tmp/large_binary.data"))
|
||||
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
|
||||
token1 = insert(:oauth_token, scopes: ["read"])
|
||||
token2 = insert(:oauth_token, scopes: ["write", "follow"])
|
||||
|
|
|
@ -269,8 +269,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
|||
}
|
||||
|
||||
with_mock(
|
||||
Pleroma.Web.Nodeinfo.NodeinfoController,
|
||||
raw_nodeinfo: fn -> %{version: "2.0"} end
|
||||
Pleroma.Web.Nodeinfo.Nodeinfo,
|
||||
get_nodeinfo: fn _ -> %{version: "2.0"} end
|
||||
) do
|
||||
assert expected ==
|
||||
AccountView.render("show.json", %{user: user, skip_visibility_check: true})
|
||||
|
|
|
@ -292,4 +292,38 @@ defmodule Pleroma.Web.NodeInfoTest do
|
|||
assert response["metadata"]["federation"]["mrf_simple_info"] == expected_config
|
||||
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
|
||||
|
|
|
@ -83,6 +83,7 @@ defmodule Pleroma.Web.Plugs.FrontendStaticPlugTest do
|
|||
"main",
|
||||
"ostatus_subscribe",
|
||||
"oauth",
|
||||
"akkoma",
|
||||
"objects",
|
||||
"activities",
|
||||
"notice",
|
||||
|
|
|
@ -69,6 +69,47 @@ defmodule Pleroma.Web.Plugs.MappedSignatureToIdentityPlugTest do
|
|||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
|
||||
test "allowlist federation: it considers a mapped identity to be valid when the associated instance is allowed" do
|
||||
clear_config([:activitypub, :authorized_fetch_mode], true)
|
||||
|
||||
clear_config([:mrf_simple, :accept], [
|
||||
{"mastodon.example.org", "anime is allowed"}
|
||||
])
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([:activitypub, :authorized_fetch_mode], false)
|
||||
Pleroma.Config.put([:mrf_simple, :accept], [])
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "http://mastodon.example.org/users/admin"})
|
||||
|> set_signature("http://mastodon.example.org/users/admin")
|
||||
|> MappedSignatureToIdentityPlug.call(%{})
|
||||
|
||||
assert conn.assigns[:valid_signature]
|
||||
refute is_nil(conn.assigns.user)
|
||||
end
|
||||
|
||||
test "allowlist federation: it considers a mapped identity to be invalid when the associated instance is not allowed" do
|
||||
clear_config([:activitypub, :authorized_fetch_mode], true)
|
||||
|
||||
clear_config([:mrf_simple, :accept], [
|
||||
{"misskey.example.org", "anime is allowed"}
|
||||
])
|
||||
|
||||
on_exit(fn ->
|
||||
Pleroma.Config.put([:activitypub, :authorized_fetch_mode], false)
|
||||
Pleroma.Config.put([:mrf_simple, :accept], [])
|
||||
end)
|
||||
|
||||
conn =
|
||||
build_conn(:post, "/doesntmattter", %{"actor" => "http://mastodon.example.org/users/admin"})
|
||||
|> set_signature("http://mastodon.example.org/users/admin")
|
||||
|> MappedSignatureToIdentityPlug.call(%{})
|
||||
|
||||
assert %{valid_signature: false} == conn.assigns
|
||||
end
|
||||
|
||||
@tag skip: "known breakage; the testsuite presently depends on it"
|
||||
test "it considers a mapped identity to be invalid when the identity cannot be found" do
|
||||
conn =
|
||||
|
|
Loading…
Reference in a new issue