Merge branch 'develop' into refactor/notification_settings
This commit is contained in:
commit
b950fb01db
|
@ -434,6 +434,14 @@
|
||||||
],
|
],
|
||||||
unfurl_nsfw: false
|
unfurl_nsfw: false
|
||||||
|
|
||||||
|
config :pleroma, Pleroma.Web.Preload,
|
||||||
|
providers: [
|
||||||
|
Pleroma.Web.Preload.Providers.Instance,
|
||||||
|
Pleroma.Web.Preload.Providers.User,
|
||||||
|
Pleroma.Web.Preload.Providers.Timelines,
|
||||||
|
Pleroma.Web.Preload.Providers.StatusNet
|
||||||
|
]
|
||||||
|
|
||||||
config :pleroma, :http_security,
|
config :pleroma, :http_security,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
sts: false,
|
sts: false,
|
||||||
|
|
|
@ -234,3 +234,43 @@ Has these additional fields under the `pleroma` object:
|
||||||
## Streaming
|
## Streaming
|
||||||
|
|
||||||
There is an additional `user:pleroma_chat` stream. Incoming chat messages will make the current chat be sent to this `user` stream. The `event` of an incoming chat message is `pleroma:chat_update`. The payload is the updated chat with the incoming chat message in the `last_message` field.
|
There is an additional `user:pleroma_chat` stream. Incoming chat messages will make the current chat be sent to this `user` stream. The `event` of an incoming chat message is `pleroma:chat_update`. The payload is the updated chat with the incoming chat message in the `last_message` field.
|
||||||
|
|
||||||
|
## Not implemented
|
||||||
|
|
||||||
|
Pleroma is generally compatible with the Mastodon 2.7.2 API, but some newer features and non-essential features are omitted. These features usually return an HTTP 200 status code, but with an empty response. While they may be added in the future, they are considered low priority.
|
||||||
|
|
||||||
|
### Suggestions
|
||||||
|
|
||||||
|
*Added in Mastodon 2.4.3*
|
||||||
|
|
||||||
|
- `GET /api/v1/suggestions`: Returns an empty array, `[]`
|
||||||
|
|
||||||
|
### Trends
|
||||||
|
|
||||||
|
*Added in Mastodon 3.0.0*
|
||||||
|
|
||||||
|
- `GET /api/v1/trends`: Returns an empty array, `[]`
|
||||||
|
|
||||||
|
### Identity proofs
|
||||||
|
|
||||||
|
*Added in Mastodon 2.8.0*
|
||||||
|
|
||||||
|
- `GET /api/v1/identity_proofs`: Returns an empty array, `[]`
|
||||||
|
|
||||||
|
### Endorsements
|
||||||
|
|
||||||
|
*Added in Mastodon 2.5.0*
|
||||||
|
|
||||||
|
- `GET /api/v1/endorsements`: Returns an empty array, `[]`
|
||||||
|
|
||||||
|
### Profile directory
|
||||||
|
|
||||||
|
*Added in Mastodon 3.0.0*
|
||||||
|
|
||||||
|
- `GET /api/v1/directory`: Returns HTTP 404
|
||||||
|
|
||||||
|
### Featured tags
|
||||||
|
|
||||||
|
*Added in Mastodon 3.0.0*
|
||||||
|
|
||||||
|
- `GET /api/v1/featured_tags`: Returns HTTP 404
|
||||||
|
|
|
@ -9,6 +9,7 @@ defmodule Fallback.RedirectController do
|
||||||
|
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Metadata
|
alias Pleroma.Web.Metadata
|
||||||
|
alias Pleroma.Web.Preload
|
||||||
|
|
||||||
def api_not_implemented(conn, _params) do
|
def api_not_implemented(conn, _params) do
|
||||||
conn
|
conn
|
||||||
|
@ -16,16 +17,7 @@ def api_not_implemented(conn, _params) do
|
||||||
|> json(%{error: "Not implemented"})
|
|> json(%{error: "Not implemented"})
|
||||||
end
|
end
|
||||||
|
|
||||||
def redirector(conn, _params, code \\ 200)
|
def redirector(conn, _params, code \\ 200) do
|
||||||
|
|
||||||
# redirect to admin section
|
|
||||||
# /pleroma/admin -> /pleroma/admin/
|
|
||||||
#
|
|
||||||
def redirector(conn, %{"path" => ["pleroma", "admin"]} = _, _code) do
|
|
||||||
redirect(conn, to: "/pleroma/admin/")
|
|
||||||
end
|
|
||||||
|
|
||||||
def redirector(conn, _params, code) do
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("text/html")
|
|> put_resp_content_type("text/html")
|
||||||
|> send_file(code, index_file_path())
|
|> send_file(code, index_file_path())
|
||||||
|
@ -43,28 +35,33 @@ def redirector_with_meta(conn, %{"maybe_nickname_or_id" => maybe_nickname_or_id}
|
||||||
def redirector_with_meta(conn, params) do
|
def redirector_with_meta(conn, params) do
|
||||||
{:ok, index_content} = File.read(index_file_path())
|
{:ok, index_content} = File.read(index_file_path())
|
||||||
|
|
||||||
tags =
|
tags = build_tags(conn, params)
|
||||||
try do
|
preloads = preload_data(conn, params)
|
||||||
Metadata.build_tags(params)
|
|
||||||
rescue
|
|
||||||
e ->
|
|
||||||
Logger.error(
|
|
||||||
"Metadata rendering for #{conn.request_path} failed.\n" <>
|
|
||||||
Exception.format(:error, e, __STACKTRACE__)
|
|
||||||
)
|
|
||||||
|
|
||||||
""
|
response =
|
||||||
end
|
index_content
|
||||||
|
|> String.replace("<!--server-generated-meta-->", tags <> preloads)
|
||||||
response = String.replace(index_content, "<!--server-generated-meta-->", tags)
|
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("text/html")
|
|> put_resp_content_type("text/html")
|
||||||
|> send_resp(200, response)
|
|> send_resp(200, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
def index_file_path do
|
def redirector_with_preload(conn, %{"path" => ["pleroma", "admin"]}) do
|
||||||
Pleroma.Plugs.InstanceStatic.file_path("index.html")
|
redirect(conn, to: "/pleroma/admin/")
|
||||||
|
end
|
||||||
|
|
||||||
|
def redirector_with_preload(conn, params) do
|
||||||
|
{:ok, index_content} = File.read(index_file_path())
|
||||||
|
preloads = preload_data(conn, params)
|
||||||
|
|
||||||
|
response =
|
||||||
|
index_content
|
||||||
|
|> String.replace("<!--server-generated-meta-->", preloads)
|
||||||
|
|
||||||
|
conn
|
||||||
|
|> put_resp_content_type("text/html")
|
||||||
|
|> send_resp(200, response)
|
||||||
end
|
end
|
||||||
|
|
||||||
def registration_page(conn, params) do
|
def registration_page(conn, params) do
|
||||||
|
@ -76,4 +73,36 @@ def empty(conn, _params) do
|
||||||
|> put_status(204)
|
|> put_status(204)
|
||||||
|> text("")
|
|> text("")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp index_file_path do
|
||||||
|
Pleroma.Plugs.InstanceStatic.file_path("index.html")
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_tags(conn, params) do
|
||||||
|
try do
|
||||||
|
Metadata.build_tags(params)
|
||||||
|
rescue
|
||||||
|
e ->
|
||||||
|
Logger.error(
|
||||||
|
"Metadata rendering for #{conn.request_path} failed.\n" <>
|
||||||
|
Exception.format(:error, e, __STACKTRACE__)
|
||||||
|
)
|
||||||
|
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp preload_data(conn, params) do
|
||||||
|
try do
|
||||||
|
Preload.build_tags(conn, params)
|
||||||
|
rescue
|
||||||
|
e ->
|
||||||
|
Logger.error(
|
||||||
|
"Preloading for #{conn.request_path} failed.\n" <>
|
||||||
|
Exception.format(:error, e, __STACKTRACE__)
|
||||||
|
)
|
||||||
|
|
||||||
|
""
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,91 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
|
||||||
|
alias Pleroma.Config
|
||||||
|
alias Pleroma.Stats
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Web.Federator.Publisher
|
||||||
|
alias Pleroma.Web.MastodonAPI.InstanceView
|
||||||
|
|
||||||
|
# returns a nodeinfo 2.0 map, since 2.1 just adds a repository field
|
||||||
|
# under software.
|
||||||
|
def get_nodeinfo("2.0") do
|
||||||
|
stats = Stats.get_stats()
|
||||||
|
|
||||||
|
staff_accounts =
|
||||||
|
User.all_superusers()
|
||||||
|
|> Enum.map(fn u -> u.ap_id end)
|
||||||
|
|
||||||
|
federation = InstanceView.federation()
|
||||||
|
features = InstanceView.features()
|
||||||
|
|
||||||
|
%{
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_nodeinfo("2.1") do
|
||||||
|
raw_response = get_nodeinfo("2.0")
|
||||||
|
|
||||||
|
updated_software =
|
||||||
|
raw_response
|
||||||
|
|> Map.get(:software)
|
||||||
|
|> Map.put(:repository, Pleroma.Application.repository())
|
||||||
|
|
||||||
|
raw_response
|
||||||
|
|> Map.put(:software, updated_software)
|
||||||
|
|> Map.put(:version, "2.1")
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_nodeinfo(_version) do
|
||||||
|
{:error, :missing}
|
||||||
|
end
|
||||||
|
end
|
|
@ -5,12 +5,8 @@
|
||||||
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
defmodule Pleroma.Web.Nodeinfo.NodeinfoController do
|
||||||
use Pleroma.Web, :controller
|
use Pleroma.Web, :controller
|
||||||
|
|
||||||
alias Pleroma.Config
|
|
||||||
alias Pleroma.Stats
|
|
||||||
alias Pleroma.User
|
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.Federator.Publisher
|
alias Pleroma.Web.Nodeinfo.Nodeinfo
|
||||||
alias Pleroma.Web.MastodonAPI.InstanceView
|
|
||||||
|
|
||||||
def schemas(conn, _params) do
|
def schemas(conn, _params) do
|
||||||
response = %{
|
response = %{
|
||||||
|
@ -29,102 +25,20 @@ def schemas(conn, _params) 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)
|
|
||||||
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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}) do
|
||||||
|
case Nodeinfo.get_nodeinfo(version) do
|
||||||
|
{:error, :missing} ->
|
||||||
|
render_error(conn, :not_found, "Nodeinfo schema version not handled")
|
||||||
|
|
||||||
|
node_info ->
|
||||||
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(node_info)
|
||||||
end
|
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
|
|
||||||
|
|
||||||
def nodeinfo(conn, _) do
|
|
||||||
render_error(conn, :not_found, "Nodeinfo schema version not handled")
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload do
|
||||||
|
alias Phoenix.HTML
|
||||||
|
require Logger
|
||||||
|
|
||||||
|
def build_tags(_conn, params) do
|
||||||
|
preload_data =
|
||||||
|
Enum.reduce(Pleroma.Config.get([__MODULE__, :providers], []), %{}, fn parser, acc ->
|
||||||
|
terms =
|
||||||
|
params
|
||||||
|
|> parser.generate_terms()
|
||||||
|
|> Enum.map(fn {k, v} -> {k, Base.encode64(Jason.encode!(v))} end)
|
||||||
|
|> Enum.into(%{})
|
||||||
|
|
||||||
|
Map.merge(acc, terms)
|
||||||
|
end)
|
||||||
|
|
||||||
|
rendered_html =
|
||||||
|
preload_data
|
||||||
|
|> Jason.encode!()
|
||||||
|
|> build_script_tag()
|
||||||
|
|> HTML.safe_to_string()
|
||||||
|
|
||||||
|
rendered_html
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_script_tag(content) do
|
||||||
|
HTML.Tag.content_tag(:script, HTML.raw(content),
|
||||||
|
id: "initial-results",
|
||||||
|
type: "application/json"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,49 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.Instance do
|
||||||
|
alias Pleroma.Web.MastodonAPI.InstanceView
|
||||||
|
alias Pleroma.Web.Nodeinfo.Nodeinfo
|
||||||
|
alias Pleroma.Web.Preload.Providers.Provider
|
||||||
|
|
||||||
|
@behaviour Provider
|
||||||
|
@instance_url :"/api/v1/instance"
|
||||||
|
@panel_url :"/instance/panel.html"
|
||||||
|
@nodeinfo_url :"/nodeinfo/2.0"
|
||||||
|
|
||||||
|
@impl Provider
|
||||||
|
def generate_terms(_params) do
|
||||||
|
%{}
|
||||||
|
|> build_info_tag()
|
||||||
|
|> build_panel_tag()
|
||||||
|
|> build_nodeinfo_tag()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_info_tag(acc) do
|
||||||
|
info_data = InstanceView.render("show.json", %{})
|
||||||
|
|
||||||
|
Map.put(acc, @instance_url, info_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_panel_tag(acc) do
|
||||||
|
instance_path = Path.join(:code.priv_dir(:pleroma), "static/instance/panel.html")
|
||||||
|
|
||||||
|
if File.exists?(instance_path) do
|
||||||
|
panel_data = File.read!(instance_path)
|
||||||
|
Map.put(acc, @panel_url, panel_data)
|
||||||
|
else
|
||||||
|
acc
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_nodeinfo_tag(acc) do
|
||||||
|
case Nodeinfo.get_nodeinfo("2.0") do
|
||||||
|
{:error, _} ->
|
||||||
|
acc
|
||||||
|
|
||||||
|
nodeinfo_data ->
|
||||||
|
Map.put(acc, @nodeinfo_url, nodeinfo_data)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.Provider do
|
||||||
|
@callback generate_terms(map()) :: map()
|
||||||
|
end
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.StatusNet do
|
||||||
|
alias Pleroma.Web.Preload.Providers.Provider
|
||||||
|
alias Pleroma.Web.TwitterAPI.UtilView
|
||||||
|
|
||||||
|
@behaviour Provider
|
||||||
|
@config_url :"/api/statusnet/config.json"
|
||||||
|
|
||||||
|
@impl Provider
|
||||||
|
def generate_terms(_params) do
|
||||||
|
%{}
|
||||||
|
|> build_config_tag()
|
||||||
|
end
|
||||||
|
|
||||||
|
defp build_config_tag(acc) do
|
||||||
|
instance = Pleroma.Config.get(:instance)
|
||||||
|
info_data = UtilView.status_net_config(instance)
|
||||||
|
|
||||||
|
Map.put(acc, @config_url, info_data)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.Timelines do
|
||||||
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
alias Pleroma.Web.Preload.Providers.Provider
|
||||||
|
|
||||||
|
@behaviour Provider
|
||||||
|
@public_url :"/api/v1/timelines/public"
|
||||||
|
|
||||||
|
@impl Provider
|
||||||
|
def generate_terms(params) do
|
||||||
|
build_public_tag(%{}, params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_public_tag(acc, params) do
|
||||||
|
if Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated], true) do
|
||||||
|
acc
|
||||||
|
else
|
||||||
|
Map.put(acc, @public_url, public_timeline(params))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
defp public_timeline(%{"path" => ["main", "all"]}), do: get_public_timeline(false)
|
||||||
|
|
||||||
|
defp public_timeline(_params), do: get_public_timeline(true)
|
||||||
|
|
||||||
|
defp get_public_timeline(local_only) do
|
||||||
|
activities =
|
||||||
|
ActivityPub.fetch_public_activities(%{
|
||||||
|
type: ["Create"],
|
||||||
|
local_only: local_only
|
||||||
|
})
|
||||||
|
|
||||||
|
StatusView.render("index.json", activities: activities, for: nil, as: :activity)
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,25 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.User do
|
||||||
|
alias Pleroma.Web.MastodonAPI.AccountView
|
||||||
|
alias Pleroma.Web.Preload.Providers.Provider
|
||||||
|
|
||||||
|
@behaviour Provider
|
||||||
|
@account_url :"/api/v1/accounts"
|
||||||
|
|
||||||
|
@impl Provider
|
||||||
|
def generate_terms(%{user: user}) do
|
||||||
|
build_accounts_tag(%{}, user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_terms(_params), do: %{}
|
||||||
|
|
||||||
|
def build_accounts_tag(acc, nil), do: acc
|
||||||
|
|
||||||
|
def build_accounts_tag(acc, user) do
|
||||||
|
account_data = AccountView.render("show.json", %{user: user, for: user})
|
||||||
|
Map.put(acc, @account_url, account_data)
|
||||||
|
end
|
||||||
|
end
|
|
@ -726,7 +726,7 @@ defmodule Pleroma.Web.Router do
|
||||||
get("/registration/:token", RedirectController, :registration_page)
|
get("/registration/:token", RedirectController, :registration_page)
|
||||||
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
|
get("/:maybe_nickname_or_id", RedirectController, :redirector_with_meta)
|
||||||
get("/api*path", RedirectController, :api_not_implemented)
|
get("/api*path", RedirectController, :api_not_implemented)
|
||||||
get("/*path", RedirectController, :redirector)
|
get("/*path", RedirectController, :redirector_with_preload)
|
||||||
|
|
||||||
options("/*path", RedirectController, :empty)
|
options("/*path", RedirectController, :empty)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
|
alias Pleroma.Web.TwitterAPI.UtilView
|
||||||
alias Pleroma.Web.WebFinger
|
alias Pleroma.Web.WebFinger
|
||||||
|
|
||||||
plug(Pleroma.Web.FederatingPlug when action == :remote_subscribe)
|
plug(Pleroma.Web.FederatingPlug when action == :remote_subscribe)
|
||||||
|
@ -90,17 +91,7 @@ def notifications_read(%{assigns: %{user: user}} = conn, %{"id" => notification_
|
||||||
|
|
||||||
def config(%{assigns: %{format: "xml"}} = conn, _params) do
|
def config(%{assigns: %{format: "xml"}} = conn, _params) do
|
||||||
instance = Pleroma.Config.get(:instance)
|
instance = Pleroma.Config.get(:instance)
|
||||||
|
response = UtilView.status_net_config(instance)
|
||||||
response = """
|
|
||||||
<config>
|
|
||||||
<site>
|
|
||||||
<name>#{Keyword.get(instance, :name)}</name>
|
|
||||||
<site>#{Web.base_url()}</site>
|
|
||||||
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
|
|
||||||
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
|
|
||||||
</site>
|
|
||||||
</config>
|
|
||||||
"""
|
|
||||||
|
|
||||||
conn
|
conn
|
||||||
|> put_resp_content_type("application/xml")
|
|> put_resp_content_type("application/xml")
|
||||||
|
|
|
@ -5,4 +5,18 @@
|
||||||
defmodule Pleroma.Web.TwitterAPI.UtilView do
|
defmodule Pleroma.Web.TwitterAPI.UtilView do
|
||||||
use Pleroma.Web, :view
|
use Pleroma.Web, :view
|
||||||
import Phoenix.HTML.Form
|
import Phoenix.HTML.Form
|
||||||
|
alias Pleroma.Web
|
||||||
|
|
||||||
|
def status_net_config(instance) do
|
||||||
|
"""
|
||||||
|
<config>
|
||||||
|
<site>
|
||||||
|
<name>#{Keyword.get(instance, :name)}</name>
|
||||||
|
<site>#{Web.base_url()}</site>
|
||||||
|
<textlimit>#{Keyword.get(instance, :limit)}</textlimit>
|
||||||
|
<closed>#{!Keyword.get(instance, :registrations_open)}</closed>
|
||||||
|
</site>
|
||||||
|
</config>
|
||||||
|
"""
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.686b5876.css rel=stylesheet><link href=app.796ca6d4.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.b08eb412.js></script><script type=text/javascript src=static/js/chunk-elementUI.fba0efec.js></script><script type=text/javascript src=static/js/chunk-libs.b8c453ab.js></script><script type=text/javascript src=static/js/app.0146039c.js></script></body></html>
|
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.1abbc9b8.css rel=stylesheet><link href=chunk-libs.686b5876.css rel=stylesheet><link href=app.6684eb28.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.5bae86dc.js></script><script type=text/javascript src=static/js/chunk-elementUI.fba0efec.js></script><script type=text/javascript src=static/js/chunk-libs.b8c453ab.js></script><script type=text/javascript src=static/js/app.3fcec8f6.js></script></body></html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -16,7 +16,7 @@ defmodule Pleroma.Web.RuntimeStaticPlugTest do
|
||||||
|
|
||||||
test "overrides index" do
|
test "overrides index" do
|
||||||
bundled_index = get(build_conn(), "/")
|
bundled_index = get(build_conn(), "/")
|
||||||
assert html_response(bundled_index, 200) == File.read!("priv/static/index.html")
|
refute html_response(bundled_index, 200) == "hello world"
|
||||||
|
|
||||||
File.write!(@dir <> "/index.html", "hello world")
|
File.write!(@dir <> "/index.html", "hello world")
|
||||||
|
|
||||||
|
|
|
@ -6,23 +6,57 @@ defmodule Pleroma.Web.FallbackTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
import Pleroma.Factory
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
describe "neither preloaded data nor metadata attached to" do
|
||||||
test "GET /registration/:token", %{conn: conn} do
|
test "GET /registration/:token", %{conn: conn} do
|
||||||
assert conn
|
response = get(conn, "/registration/foo")
|
||||||
|> get("/registration/foo")
|
|
||||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
assert html_response(response, 200) =~ "<!--server-generated-meta-->"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "GET /*path", %{conn: conn} do
|
||||||
|
assert conn
|
||||||
|
|> get("/foo")
|
||||||
|
|> html_response(200) =~ "<!--server-generated-meta-->"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "preloaded data and metadata attached to" do
|
||||||
test "GET /:maybe_nickname_or_id", %{conn: conn} do
|
test "GET /:maybe_nickname_or_id", %{conn: conn} do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
user_missing = get(conn, "/foo")
|
||||||
|
user_present = get(conn, "/#{user.nickname}")
|
||||||
|
|
||||||
|
assert(html_response(user_missing, 200) =~ "<!--server-generated-meta-->")
|
||||||
|
refute html_response(user_present, 200) =~ "<!--server-generated-meta-->"
|
||||||
|
assert html_response(user_present, 200) =~ "initial-results"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "GET /*path", %{conn: conn} do
|
||||||
assert conn
|
assert conn
|
||||||
|> get("/foo")
|
|> get("/foo")
|
||||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
|> html_response(200) =~ "<!--server-generated-meta-->"
|
||||||
|
|
||||||
refute conn
|
refute conn
|
||||||
|> get("/" <> user.nickname)
|
|> get("/foo/bar")
|
||||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
|> html_response(200) =~ "<!--server-generated-meta-->"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "preloaded data is attached to" do
|
||||||
|
test "GET /main/public", %{conn: conn} do
|
||||||
|
public_page = get(conn, "/main/public")
|
||||||
|
|
||||||
|
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
|
||||||
|
assert html_response(public_page, 200) =~ "initial-results"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "GET /main/all", %{conn: conn} do
|
||||||
|
public_page = get(conn, "/main/all")
|
||||||
|
|
||||||
|
refute html_response(public_page, 200) =~ "<!--server-generated-meta-->"
|
||||||
|
assert html_response(public_page, 200) =~ "initial-results"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
test "GET /api*path", %{conn: conn} do
|
test "GET /api*path", %{conn: conn} do
|
||||||
assert conn
|
assert conn
|
||||||
|
@ -34,16 +68,6 @@ test "GET /pleroma/admin -> /pleroma/admin/", %{conn: conn} do
|
||||||
assert redirected_to(get(conn, "/pleroma/admin")) =~ "/pleroma/admin/"
|
assert redirected_to(get(conn, "/pleroma/admin")) =~ "/pleroma/admin/"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "GET /*path", %{conn: conn} do
|
|
||||||
assert conn
|
|
||||||
|> get("/foo")
|
|
||||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
|
||||||
|
|
||||||
assert conn
|
|
||||||
|> get("/foo/bar")
|
|
||||||
|> html_response(200) =~ "<!--server-generated-meta-->"
|
|
||||||
end
|
|
||||||
|
|
||||||
test "OPTIONS /*path", %{conn: conn} do
|
test "OPTIONS /*path", %{conn: conn} do
|
||||||
assert conn
|
assert conn
|
||||||
|> options("/foo")
|
|> options("/foo")
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.InstanceTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
alias Pleroma.Web.Preload.Providers.Instance
|
||||||
|
|
||||||
|
setup do: {:ok, Instance.generate_terms(nil)}
|
||||||
|
|
||||||
|
test "it renders the info", %{"/api/v1/instance": info} do
|
||||||
|
assert %{
|
||||||
|
description: description,
|
||||||
|
email: "admin@example.com",
|
||||||
|
registrations: true
|
||||||
|
} = info
|
||||||
|
|
||||||
|
assert String.equivalent?(description, "Pleroma: An efficient and flexible fediverse server")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it renders the panel", %{"/instance/panel.html": panel} do
|
||||||
|
assert String.contains?(
|
||||||
|
panel,
|
||||||
|
"<p>Welcome to <a href=\"https://pleroma.social\" target=\"_blank\">Pleroma!</a></p>"
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it renders the node_info", %{"/nodeinfo/2.0": nodeinfo} do
|
||||||
|
%{
|
||||||
|
metadata: metadata,
|
||||||
|
version: "2.0"
|
||||||
|
} = nodeinfo
|
||||||
|
|
||||||
|
assert metadata.private == false
|
||||||
|
assert metadata.suggestions == %{enabled: false}
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.StatusNetTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
alias Pleroma.Web.Preload.Providers.StatusNet
|
||||||
|
|
||||||
|
setup do: {:ok, StatusNet.generate_terms(nil)}
|
||||||
|
|
||||||
|
test "it renders the info", %{"/api/statusnet/config.json": info} do
|
||||||
|
assert info =~ "<name>Pleroma</name>"
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,74 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.TimelineTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
import Pleroma.Factory
|
||||||
|
|
||||||
|
alias Pleroma.Web.CommonAPI
|
||||||
|
alias Pleroma.Web.Preload.Providers.Timelines
|
||||||
|
|
||||||
|
@public_url :"/api/v1/timelines/public"
|
||||||
|
|
||||||
|
describe "unauthenticated timeliness when restricted" do
|
||||||
|
setup do
|
||||||
|
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
|
||||||
|
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{local: true, federated: true})
|
||||||
|
|
||||||
|
on_exit(fn ->
|
||||||
|
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
|
||||||
|
end)
|
||||||
|
|
||||||
|
:ok
|
||||||
|
end
|
||||||
|
|
||||||
|
test "return nothing" do
|
||||||
|
tl_data = Timelines.generate_terms(%{})
|
||||||
|
|
||||||
|
refute Map.has_key?(tl_data, "/api/v1/timelines/public")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "unauthenticated timeliness when unrestricted" do
|
||||||
|
setup do
|
||||||
|
svd_config = Pleroma.Config.get([:restrict_unauthenticated, :timelines])
|
||||||
|
|
||||||
|
Pleroma.Config.put([:restrict_unauthenticated, :timelines], %{
|
||||||
|
local: false,
|
||||||
|
federated: false
|
||||||
|
})
|
||||||
|
|
||||||
|
on_exit(fn ->
|
||||||
|
Pleroma.Config.put([:restrict_unauthenticated, :timelines], svd_config)
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:ok, user: insert(:user)}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns the timeline when not restricted" do
|
||||||
|
assert Timelines.generate_terms(%{})
|
||||||
|
|> Map.has_key?(@public_url)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "returns public items", %{user: user} do
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!"})
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!"})
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
|
||||||
|
|
||||||
|
assert Timelines.generate_terms(%{})
|
||||||
|
|> Map.fetch!(@public_url)
|
||||||
|
|> Enum.count() == 3
|
||||||
|
end
|
||||||
|
|
||||||
|
test "does not return non-public items", %{user: user} do
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 1!", visibility: "unlisted"})
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 2!", visibility: "direct"})
|
||||||
|
{:ok, _} = CommonAPI.post(user, %{status: "it's post 3!"})
|
||||||
|
|
||||||
|
assert Timelines.generate_terms(%{})
|
||||||
|
|> Map.fetch!(@public_url)
|
||||||
|
|> Enum.count() == 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Preload.Providers.UserTest do
|
||||||
|
use Pleroma.DataCase
|
||||||
|
import Pleroma.Factory
|
||||||
|
alias Pleroma.Web.Preload.Providers.User
|
||||||
|
|
||||||
|
describe "returns empty when user doesn't exist" do
|
||||||
|
test "nil user specified" do
|
||||||
|
refute User.generate_terms(%{user: nil})
|
||||||
|
|> Map.has_key?("/api/v1/accounts")
|
||||||
|
end
|
||||||
|
|
||||||
|
test "missing user specified" do
|
||||||
|
refute User.generate_terms(%{user: :not_a_user})
|
||||||
|
|> Map.has_key?("/api/v1/accounts")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "specified user exists" do
|
||||||
|
setup do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
{:ok, User.generate_terms(%{user: user})}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "account is rendered", %{"/api/v1/accounts": accounts} do
|
||||||
|
assert %{acct: user, username: user} = accounts
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue