Merge branch 'release/2.0.5' into 'stable'
Release/2.0.5 See merge request pleroma/secteam/pleroma!4
This commit is contained in:
commit
a5ccb5b0b1
38 changed files with 297 additions and 315 deletions
15
CHANGELOG.md
15
CHANGELOG.md
|
@ -3,6 +3,21 @@ All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
|
## [2.0.5] - 2020-05-13
|
||||||
|
|
||||||
|
### Security
|
||||||
|
- Fix possible private status leaks in Mastodon Streaming API
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- Crashes when trying to block a user if block federation is disabled
|
||||||
|
- Not being able to start the instance without `erlang-eldap` installed
|
||||||
|
- Users with bios over the limit getting rejected
|
||||||
|
- Follower counters not being updated on incoming follow accepts
|
||||||
|
|
||||||
|
### Upgrade notes
|
||||||
|
|
||||||
|
1. Restart Pleroma
|
||||||
|
|
||||||
## [2.0.4] - 2020-05-10
|
## [2.0.4] - 2020-05-10
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
|
@ -501,7 +501,15 @@ defmodule Pleroma.User do
|
||||||
|
|
||||||
params = Map.put(params, :last_refreshed_at, NaiveDateTime.utc_now())
|
params = Map.put(params, :last_refreshed_at, NaiveDateTime.utc_now())
|
||||||
|
|
||||||
params = if remote?, do: truncate_fields_param(params), else: params
|
params =
|
||||||
|
if remote? do
|
||||||
|
params
|
||||||
|
|> truncate_fields_param()
|
||||||
|
|> truncate_if_exists(:name, name_limit)
|
||||||
|
|> truncate_if_exists(:bio, bio_limit)
|
||||||
|
else
|
||||||
|
params
|
||||||
|
end
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> cast(
|
|> cast(
|
||||||
|
|
|
@ -604,7 +604,6 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_block(blocker, blocked, activity_id, local) do
|
defp do_block(blocker, blocked, activity_id, local) do
|
||||||
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
|
||||||
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
unfollow_blocked = Config.get([:activitypub, :unfollow_blocked])
|
||||||
|
|
||||||
if unfollow_blocked do
|
if unfollow_blocked do
|
||||||
|
@ -612,8 +611,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
|
||||||
if follow_activity, do: unfollow(blocker, blocked, nil, local)
|
if follow_activity, do: unfollow(blocker, blocked, nil, local)
|
||||||
end
|
end
|
||||||
|
|
||||||
with true <- outgoing_blocks,
|
with block_data <- make_block_data(blocker, blocked, activity_id),
|
||||||
block_data <- make_block_data(blocker, blocked, activity_id),
|
|
||||||
{:ok, activity} <- insert(block_data, local),
|
{:ok, activity} <- insert(block_data, local),
|
||||||
:ok <- maybe_federate(activity) do
|
:ok <- maybe_federate(activity) do
|
||||||
{:ok, activity}
|
{:ok, activity}
|
||||||
|
|
|
@ -544,6 +544,9 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
|
{:ok, follow_activity} <- Utils.update_follow_state_for_all(follow_activity, "accept"),
|
||||||
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
|
%User{local: true} = follower <- User.get_cached_by_ap_id(follow_activity.data["actor"]),
|
||||||
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
|
{:ok, _relationship} <- FollowingRelationship.update(follower, followed, :follow_accept) do
|
||||||
|
User.update_follower_count(followed)
|
||||||
|
User.update_following_count(follower)
|
||||||
|
|
||||||
ActivityPub.accept(%{
|
ActivityPub.accept(%{
|
||||||
to: follow_activity.data["to"],
|
to: follow_activity.data["to"],
|
||||||
type: "Accept",
|
type: "Accept",
|
||||||
|
@ -553,7 +556,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|
||||||
activity_id: id
|
activity_id: id
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
_e -> :error
|
_e ->
|
||||||
|
:error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
||||||
alias Ecto.Changeset
|
alias Ecto.Changeset
|
||||||
alias Ecto.UUID
|
alias Ecto.UUID
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
|
alias Pleroma.Config
|
||||||
alias Pleroma.Notification
|
alias Pleroma.Notification
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Repo
|
alias Pleroma.Repo
|
||||||
|
@ -169,8 +170,11 @@ defmodule Pleroma.Web.ActivityPub.Utils do
|
||||||
Enqueues an activity for federation if it's local
|
Enqueues an activity for federation if it's local
|
||||||
"""
|
"""
|
||||||
@spec maybe_federate(any()) :: :ok
|
@spec maybe_federate(any()) :: :ok
|
||||||
def maybe_federate(%Activity{local: true} = activity) do
|
def maybe_federate(%Activity{local: true, data: %{"type" => type}} = activity) do
|
||||||
if Pleroma.Config.get!([:instance, :federating]) do
|
outgoing_blocks = Config.get([:activitypub, :outgoing_blocks])
|
||||||
|
|
||||||
|
with true <- Config.get!([:instance, :federating]),
|
||||||
|
true <- type != "Block" || outgoing_blocks do
|
||||||
Pleroma.Web.Federator.publish(activity)
|
Pleroma.Web.Federator.publish(activity)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -12,29 +12,15 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
||||||
|
|
||||||
@behaviour :cowboy_websocket
|
@behaviour :cowboy_websocket
|
||||||
|
|
||||||
@streams [
|
|
||||||
"public",
|
|
||||||
"public:local",
|
|
||||||
"public:media",
|
|
||||||
"public:local:media",
|
|
||||||
"user",
|
|
||||||
"user:notification",
|
|
||||||
"direct",
|
|
||||||
"list",
|
|
||||||
"hashtag"
|
|
||||||
]
|
|
||||||
@anonymous_streams ["public", "public:local", "hashtag"]
|
|
||||||
|
|
||||||
# Handled by periodic keepalive in Pleroma.Web.Streamer.Ping.
|
# Handled by periodic keepalive in Pleroma.Web.Streamer.Ping.
|
||||||
@timeout :infinity
|
@timeout :infinity
|
||||||
|
|
||||||
def init(%{qs: qs} = req, state) do
|
def init(%{qs: qs} = req, state) do
|
||||||
with params <- :cow_qs.parse_qs(qs),
|
with params <- Enum.into(:cow_qs.parse_qs(qs), %{}),
|
||||||
sec_websocket <- :cowboy_req.header("sec-websocket-protocol", req, nil),
|
sec_websocket <- :cowboy_req.header("sec-websocket-protocol", req, nil),
|
||||||
access_token <- List.keyfind(params, "access_token", 0),
|
access_token <- Map.get(params, "access_token"),
|
||||||
{_, stream} <- List.keyfind(params, "stream", 0),
|
{:ok, user} <- authenticate_request(access_token, sec_websocket),
|
||||||
{:ok, user} <- allow_request(stream, [access_token, sec_websocket]),
|
{:ok, topic} <- Streamer.get_topic(Map.get(params, "stream"), user, params) do
|
||||||
topic when is_binary(topic) <- expand_topic(stream, params) do
|
|
||||||
req =
|
req =
|
||||||
if sec_websocket do
|
if sec_websocket do
|
||||||
:cowboy_req.set_resp_header("sec-websocket-protocol", sec_websocket, req)
|
:cowboy_req.set_resp_header("sec-websocket-protocol", sec_websocket, req)
|
||||||
|
@ -44,14 +30,14 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
||||||
|
|
||||||
{:cowboy_websocket, req, %{user: user, topic: topic}, %{idle_timeout: @timeout}}
|
{:cowboy_websocket, req, %{user: user, topic: topic}, %{idle_timeout: @timeout}}
|
||||||
else
|
else
|
||||||
{:error, code} ->
|
{:error, :bad_topic} ->
|
||||||
Logger.debug("#{__MODULE__} denied connection: #{inspect(code)} - #{inspect(req)}")
|
Logger.debug("#{__MODULE__} bad topic #{inspect(req)}")
|
||||||
{:ok, req} = :cowboy_req.reply(code, req)
|
{:ok, req} = :cowboy_req.reply(404, req)
|
||||||
{:ok, req, state}
|
{:ok, req, state}
|
||||||
|
|
||||||
error ->
|
{:error, :unauthorized} ->
|
||||||
Logger.debug("#{__MODULE__} denied connection: #{inspect(error)} - #{inspect(req)}")
|
Logger.debug("#{__MODULE__} authentication error: #{inspect(req)}")
|
||||||
{:ok, req} = :cowboy_req.reply(400, req)
|
{:ok, req} = :cowboy_req.reply(401, req)
|
||||||
{:ok, req, state}
|
{:ok, req, state}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -93,50 +79,23 @@ defmodule Pleroma.Web.MastodonAPI.WebsocketHandler do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Public streams without authentication.
|
# Public streams without authentication.
|
||||||
defp allow_request(stream, [nil, nil]) when stream in @anonymous_streams do
|
defp authenticate_request(nil, nil) do
|
||||||
{:ok, nil}
|
{:ok, nil}
|
||||||
end
|
end
|
||||||
|
|
||||||
# Authenticated streams.
|
# Authenticated streams.
|
||||||
defp allow_request(stream, [access_token, sec_websocket]) when stream in @streams do
|
defp authenticate_request(access_token, sec_websocket) do
|
||||||
token =
|
token = access_token || sec_websocket
|
||||||
with {"access_token", token} <- access_token do
|
|
||||||
token
|
|
||||||
else
|
|
||||||
_ -> sec_websocket
|
|
||||||
end
|
|
||||||
|
|
||||||
with true <- is_bitstring(token),
|
with true <- is_bitstring(token),
|
||||||
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
|
%Token{user_id: user_id} <- Repo.get_by(Token, token: token),
|
||||||
user = %User{} <- User.get_cached_by_id(user_id) do
|
user = %User{} <- User.get_cached_by_id(user_id) do
|
||||||
{:ok, user}
|
{:ok, user}
|
||||||
else
|
else
|
||||||
_ -> {:error, 403}
|
_ -> {:error, :unauthorized}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Not authenticated.
|
|
||||||
defp allow_request(stream, _) when stream in @streams, do: {:error, 403}
|
|
||||||
|
|
||||||
# No matching stream.
|
|
||||||
defp allow_request(_, _), do: {:error, 404}
|
|
||||||
|
|
||||||
defp expand_topic("hashtag", params) do
|
|
||||||
case List.keyfind(params, "tag", 0) do
|
|
||||||
{_, tag} -> "hashtag:#{tag}"
|
|
||||||
_ -> nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp expand_topic("list", params) do
|
|
||||||
case List.keyfind(params, "list", 0) do
|
|
||||||
{_, list} -> "list:#{list}"
|
|
||||||
_ -> nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
defp expand_topic(topic, _), do: topic
|
|
||||||
|
|
||||||
defp streamer_socket(state) do
|
defp streamer_socket(state) do
|
||||||
%{transport_pid: self(), assigns: state}
|
%{transport_pid: self(), assigns: state}
|
||||||
end
|
end
|
||||||
|
|
|
@ -36,30 +36,28 @@ defmodule Pleroma.Web.Streamer.State do
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call({:add, topic, socket}, _from, %{sockets: sockets} = state) do
|
def handle_call({:add, topic, socket}, _from, %{sockets: sockets} = state) do
|
||||||
internal_topic = internal_topic(topic, socket)
|
|
||||||
stream_socket = StreamerSocket.from_socket(socket)
|
stream_socket = StreamerSocket.from_socket(socket)
|
||||||
|
|
||||||
sockets_for_topic =
|
sockets_for_topic =
|
||||||
sockets
|
sockets
|
||||||
|> Map.get(internal_topic, [])
|
|> Map.get(topic, [])
|
||||||
|> List.insert_at(0, stream_socket)
|
|> List.insert_at(0, stream_socket)
|
||||||
|> Enum.uniq()
|
|> Enum.uniq()
|
||||||
|
|
||||||
state = put_in(state, [:sockets, internal_topic], sockets_for_topic)
|
state = put_in(state, [:sockets, topic], sockets_for_topic)
|
||||||
Logger.debug("Got new conn for #{topic}")
|
Logger.debug("Got new conn for #{topic}")
|
||||||
{:reply, state, state}
|
{:reply, state, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
def handle_call({:remove, topic, socket}, _from, %{sockets: sockets} = state) do
|
def handle_call({:remove, topic, socket}, _from, %{sockets: sockets} = state) do
|
||||||
internal_topic = internal_topic(topic, socket)
|
|
||||||
stream_socket = StreamerSocket.from_socket(socket)
|
stream_socket = StreamerSocket.from_socket(socket)
|
||||||
|
|
||||||
sockets_for_topic =
|
sockets_for_topic =
|
||||||
sockets
|
sockets
|
||||||
|> Map.get(internal_topic, [])
|
|> Map.get(topic, [])
|
||||||
|> List.delete(stream_socket)
|
|> List.delete(stream_socket)
|
||||||
|
|
||||||
state = Kernel.put_in(state, [:sockets, internal_topic], sockets_for_topic)
|
state = Kernel.put_in(state, [:sockets, topic], sockets_for_topic)
|
||||||
{:reply, state, state}
|
{:reply, state, state}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -70,13 +68,4 @@ defmodule Pleroma.Web.Streamer.State do
|
||||||
defp do_remove_socket(_env, topic, socket) do
|
defp do_remove_socket(_env, topic, socket) do
|
||||||
GenServer.call(__MODULE__, {:remove, topic, socket})
|
GenServer.call(__MODULE__, {:remove, topic, socket})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp internal_topic(topic, socket)
|
|
||||||
when topic in ~w[user user:notification direct] do
|
|
||||||
"#{topic}:#{socket.assigns[:user].id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
defp internal_topic(topic, _) do
|
|
||||||
topic
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,12 +3,77 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Web.Streamer do
|
defmodule Pleroma.Web.Streamer do
|
||||||
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.Streamer.State
|
alias Pleroma.Web.Streamer.State
|
||||||
alias Pleroma.Web.Streamer.Worker
|
alias Pleroma.Web.Streamer.Worker
|
||||||
|
|
||||||
@timeout 60_000
|
@timeout 60_000
|
||||||
@mix_env Mix.env()
|
@mix_env Mix.env()
|
||||||
|
|
||||||
|
@public_streams ["public", "public:local", "public:media", "public:local:media"]
|
||||||
|
@user_streams ["user", "user:notification", "direct"]
|
||||||
|
|
||||||
|
@doc "Expands and authorizes a stream, and registers the process for streaming."
|
||||||
|
@spec get_topic_and_add_socket(stream :: String.t(), State.t(), Map.t() | nil) ::
|
||||||
|
{:ok, topic :: String.t()} | {:error, :bad_topic} | {:error, :unauthorized}
|
||||||
|
def get_topic_and_add_socket(stream, socket, params \\ %{}) do
|
||||||
|
user =
|
||||||
|
case socket do
|
||||||
|
%{assigns: %{user: user}} -> user
|
||||||
|
_ -> nil
|
||||||
|
end
|
||||||
|
|
||||||
|
case get_topic(stream, user, params) do
|
||||||
|
{:ok, topic} ->
|
||||||
|
add_socket(topic, socket)
|
||||||
|
{:ok, topic}
|
||||||
|
|
||||||
|
error ->
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc "Expand and authorizes a stream"
|
||||||
|
@spec get_topic(stream :: String.t(), User.t() | nil, Map.t()) ::
|
||||||
|
{:ok, topic :: String.t()} | {:error, :bad_topic}
|
||||||
|
def get_topic(stream, user, params \\ %{})
|
||||||
|
|
||||||
|
# Allow all public steams.
|
||||||
|
def get_topic(stream, _, _) when stream in @public_streams do
|
||||||
|
{:ok, stream}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Allow all hashtags streams.
|
||||||
|
def get_topic("hashtag", _, %{"tag" => tag}) do
|
||||||
|
{:ok, "hashtag:" <> tag}
|
||||||
|
end
|
||||||
|
|
||||||
|
# Expand user streams.
|
||||||
|
def get_topic(stream, %User{} = user, _) when stream in @user_streams do
|
||||||
|
{:ok, stream <> ":" <> to_string(user.id)}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_topic(stream, _, _) when stream in @user_streams do
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
|
|
||||||
|
# List streams.
|
||||||
|
def get_topic("list", %User{} = user, %{"list" => id}) do
|
||||||
|
if Pleroma.List.get(id, user) do
|
||||||
|
{:ok, "list:" <> to_string(id)}
|
||||||
|
else
|
||||||
|
{:error, :bad_topic}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_topic("list", _, _) do
|
||||||
|
{:error, :unauthorized}
|
||||||
|
end
|
||||||
|
|
||||||
|
def get_topic(_, _, _) do
|
||||||
|
{:error, :bad_topic}
|
||||||
|
end
|
||||||
|
|
||||||
def add_socket(topic, socket) do
|
def add_socket(topic, socket) do
|
||||||
State.add_socket(topic, socket)
|
State.add_socket(topic, socket)
|
||||||
end
|
end
|
||||||
|
|
7
mix.exs
7
mix.exs
|
@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
|
||||||
def project do
|
def project do
|
||||||
[
|
[
|
||||||
app: :pleroma,
|
app: :pleroma,
|
||||||
version: version("2.0.4"),
|
version: version("2.0.5"),
|
||||||
elixir: "~> 1.8",
|
elixir: "~> 1.8",
|
||||||
elixirc_paths: elixirc_paths(Mix.env()),
|
elixirc_paths: elixirc_paths(Mix.env()),
|
||||||
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
compilers: [:phoenix, :gettext] ++ Mix.compilers(),
|
||||||
|
@ -36,7 +36,7 @@ defmodule Pleroma.Mixfile do
|
||||||
releases: [
|
releases: [
|
||||||
pleroma: [
|
pleroma: [
|
||||||
include_executables_for: [:unix],
|
include_executables_for: [:unix],
|
||||||
applications: [ex_syslogger: :load, syslog: :load],
|
applications: [ex_syslogger: :load, syslog: :load, eldap: :transient],
|
||||||
steps: [:assemble, ©_files/1, ©_nginx_config/1]
|
steps: [:assemble, ©_files/1, ©_nginx_config/1]
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
@ -69,8 +69,7 @@ defmodule Pleroma.Mixfile do
|
||||||
:comeonin,
|
:comeonin,
|
||||||
:quack,
|
:quack,
|
||||||
:fast_sanitize,
|
:fast_sanitize,
|
||||||
:ssl,
|
:ssl
|
||||||
:eldap
|
|
||||||
],
|
],
|
||||||
included_applications: [:ex_syslogger]
|
included_applications: [:ex_syslogger]
|
||||||
]
|
]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.1055039ce3f2fe4dd110.css rel=stylesheet><link href=/static/fontello.1588431888583.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.c67e1a363ece7f1f7152.js></script><script type=text/javascript src=/static/js/app.57951e6e5e198d1a1266.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.b2603a50868c68a1c192.css rel=stylesheet><link href=/static/css/app.1055039ce3f2fe4dd110.css rel=stylesheet><link href=/static/fontello.1589314090288.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.a516afd698489b59a809.js></script><script type=text/javascript src=/static/js/app.82334f8362acc4bbcb6f.js></script></body></html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -114,6 +114,8 @@
|
||||||
|
|
||||||
<glyph glyph-name="thumbs-up-alt" unicode="" d="M143 107q0 15-11 25t-25 11q-15 0-25-11t-11-25q0-15 11-25t25-11q15 0 25 11t11 25z m89 286v-357q0-15-10-25t-26-11h-160q-15 0-25 11t-11 25v357q0 14 11 25t25 10h160q15 0 26-10t10-25z m661 0q0-48-31-83 9-25 9-43 1-42-24-76 9-31 0-66-9-31-31-52 5-62-27-101-36-43-110-44h-72q-37 0-80 9t-68 16-67 22q-69 24-88 25-15 0-25 11t-11 25v357q0 14 10 25t24 11q13 1 42 33t57 67q38 49 56 67 10 10 17 27t10 27 8 34q4 22 7 34t11 29 19 28q10 11 25 11 25 0 46-6t33-15 22-22 14-25 7-28 2-25 1-22q0-21-6-43t-10-33-16-31q-1-4-5-10t-6-13-5-13h155q43 0 75-32t32-75z" horiz-adv-x="928.6" />
|
<glyph glyph-name="thumbs-up-alt" unicode="" d="M143 107q0 15-11 25t-25 11q-15 0-25-11t-11-25q0-15 11-25t25-11q15 0 25 11t11 25z m89 286v-357q0-15-10-25t-26-11h-160q-15 0-25 11t-11 25v357q0 14 11 25t25 10h160q15 0 26-10t10-25z m661 0q0-48-31-83 9-25 9-43 1-42-24-76 9-31 0-66-9-31-31-52 5-62-27-101-36-43-110-44h-72q-37 0-80 9t-68 16-67 22q-69 24-88 25-15 0-25 11t-11 25v357q0 14 10 25t24 11q13 1 42 33t57 67q38 49 56 67 10 10 17 27t10 27 8 34q4 22 7 34t11 29 19 28q10 11 25 11 25 0 46-6t33-15 22-22 14-25 7-28 2-25 1-22q0-21-6-43t-10-33-16-31q-1-4-5-10t-6-13-5-13h155q43 0 75-32t32-75z" horiz-adv-x="928.6" />
|
||||||
|
|
||||||
|
<glyph glyph-name="share" unicode="" d="M679 286q74 0 126-53t52-126-52-126-126-53-127 53-52 126q0 7 1 19l-201 100q-51-48-121-48-75 0-127 53t-52 126 52 126 127 53q70 0 121-48l201 100q-1 12-1 19 0 74 52 126t127 53 126-53 52-126-52-126-126-53q-71 0-122 48l-201-100q1-12 1-19t-1-19l201-100q51 48 122 48z" horiz-adv-x="857.1" />
|
||||||
|
|
||||||
<glyph glyph-name="binoculars" unicode="" d="M393 678v-428q0-15-11-25t-25-11v-321q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v285l139 488q4 12 17 12h237z m178 0v-392h-142v392h142z m429-500v-285q0-15-11-25t-25-11h-285q-15 0-25 11t-11 25v321q-15 0-25 11t-11 25v428h237q13 0 17-12z m-589 661v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z m375 0v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
<glyph glyph-name="binoculars" unicode="" d="M393 678v-428q0-15-11-25t-25-11v-321q0-15-10-25t-26-11h-285q-15 0-25 11t-11 25v285l139 488q4 12 17 12h237z m178 0v-392h-142v392h142z m429-500v-285q0-15-11-25t-25-11h-285q-15 0-25 11t-11 25v321q-15 0-25 11t-11 25v428h237q13 0 17-12z m-589 661v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z m375 0v-125h-197v125q0 8 5 13t13 5h161q8 0 13-5t5-13z" horiz-adv-x="1000" />
|
||||||
|
|
||||||
<glyph glyph-name="user-plus" unicode="" d="M393 357q-89 0-152 63t-62 151 62 152 152 63 151-63 63-152-63-151-151-63z m536-71h196q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-196v-197q0-7-6-12t-12-6h-107q-8 0-13 6t-5 12v197h-197q-7 0-12 5t-6 13v107q0 7 6 12t12 6h197v196q0 7 5 13t13 5h107q7 0 12-5t6-13v-196z m-411-125q0-29 21-51t50-21h143v-133q-38-28-95-28h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q11 0 22-10 44-34 86-51t92-17 92 17 86 51q11 10 22 10 73 0 121-54h-125q-29 0-50-21t-21-50v-107z" horiz-adv-x="1142.9" />
|
<glyph glyph-name="user-plus" unicode="" d="M393 357q-89 0-152 63t-62 151 62 152 152 63 151-63 63-152-63-151-151-63z m536-71h196q7 0 13-6t5-12v-107q0-8-5-13t-13-5h-196v-197q0-7-6-12t-12-6h-107q-8 0-13 6t-5 12v197h-197q-7 0-12 5t-6 13v107q0 7 6 12t12 6h197v196q0 7 5 13t13 5h107q7 0 12-5t6-13v-196z m-411-125q0-29 21-51t50-21h143v-133q-38-28-95-28h-488q-67 0-108 39t-41 106q0 30 2 58t8 61 15 60 24 55 34 45 48 30 62 11q11 0 22-10 44-34 86-51t92-17 92 17 86 51q11 10 22 10 73 0 121-54h-125q-29 0-50-21t-21-50v-107z" horiz-adv-x="1142.9" />
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
Binary file not shown.
BIN
priv/static/static/font/fontello.1589314090288.woff
Normal file
BIN
priv/static/static/font/fontello.1589314090288.woff
Normal file
Binary file not shown.
BIN
priv/static/static/font/fontello.1589314090288.woff2
Normal file
BIN
priv/static/static/font/fontello.1589314090288.woff2
Normal file
Binary file not shown.
|
@ -1,11 +1,11 @@
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Icons";
|
font-family: "Icons";
|
||||||
src: url("./font/fontello.1588431888583.eot");
|
src: url("./font/fontello.1589314090288.eot");
|
||||||
src: url("./font/fontello.1588431888583.eot") format("embedded-opentype"),
|
src: url("./font/fontello.1589314090288.eot") format("embedded-opentype"),
|
||||||
url("./font/fontello.1588431888583.woff2") format("woff2"),
|
url("./font/fontello.1589314090288.woff2") format("woff2"),
|
||||||
url("./font/fontello.1588431888583.woff") format("woff"),
|
url("./font/fontello.1589314090288.woff") format("woff"),
|
||||||
url("./font/fontello.1588431888583.ttf") format("truetype"),
|
url("./font/fontello.1589314090288.ttf") format("truetype"),
|
||||||
url("./font/fontello.1588431888583.svg") format("svg");
|
url("./font/fontello.1589314090288.svg") format("svg");
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +137,8 @@
|
||||||
|
|
||||||
.icon-link::before { content: "\e823"; }
|
.icon-link::before { content: "\e823"; }
|
||||||
|
|
||||||
|
.icon-share::before { content: "\f1e0"; }
|
||||||
|
|
||||||
.icon-user::before { content: "\e824"; }
|
.icon-user::before { content: "\e824"; }
|
||||||
|
|
||||||
.icon-ok::before { content: "\e827"; }
|
.icon-ok::before { content: "\e827"; }
|
|
@ -346,6 +346,12 @@
|
||||||
"code": 59427,
|
"code": 59427,
|
||||||
"src": "fontawesome"
|
"src": "fontawesome"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"uid": "4aad6bb50b02c18508aae9cbe14e784e",
|
||||||
|
"css": "share",
|
||||||
|
"code": 61920,
|
||||||
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"uid": "8b80d36d4ef43889db10bc1f0dc9a862",
|
"uid": "8b80d36d4ef43889db10bc1f0dc9a862",
|
||||||
"css": "user",
|
"css": "user",
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{580:function(t,e,i){var c=i(581);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(4).default)("cc6cdea4",c,!0,{})},581:function(t,e,i){(t.exports=i(3)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},582:function(t,e,i){"use strict";i.r(e);var c=i(90),a={components:{TabSwitcher:i(52).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,a=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var n=new File([t],e,{mimetype:"image/png"}),s=new FormData;s.append("file",n),c.a.uploadMedia({store:a,formData:s}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}},n=i(0);var s=function(t){i(580)},r=Object(n.a)(a,function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])}),0)}),0)],1)},[],!1,s,null,null);e.default=r.exports}}]);
|
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{582:function(t,e,i){var c=i(583);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(3).default)("cc6cdea4",c,!0,{})},583:function(t,e,i){(t.exports=i(2)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},584:function(t,e,i){"use strict";i.r(e);var c=i(90),a={components:{TabSwitcher:i(52).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,a=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var n=new File([t],e,{mimetype:"image/png"}),s=new FormData;s.append("file",n),c.a.uploadMedia({store:a,formData:s}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}},n=i(0);var s=function(t){i(582)},r=Object(n.a)(a,function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])}),0)}),0)],1)},[],!1,s,null,null);e.default=r.exports}}]);
|
||||||
//# sourceMappingURL=2.93c984e8c993f92c77a1.js.map
|
//# sourceMappingURL=2.f9a5c4aba770b3f9f9e0.js.map
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
2
priv/static/static/js/app.82334f8362acc4bbcb6f.js
Normal file
2
priv/static/static/js/app.82334f8362acc4bbcb6f.js
Normal file
File diff suppressed because one or more lines are too long
1
priv/static/static/js/app.82334f8362acc4bbcb6f.js.map
Normal file
1
priv/static/static/js/app.82334f8362acc4bbcb6f.js.map
Normal file
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,176 +0,0 @@
|
||||||
body {
|
|
||||||
background-color: #282c37;
|
|
||||||
font-family: sans-serif;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
margin: 50px auto;
|
|
||||||
max-width: 960px;
|
|
||||||
padding: 40px;
|
|
||||||
background-color: #313543;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
margin: 50px auto;
|
|
||||||
max-width: 960px;
|
|
||||||
padding: 40px;
|
|
||||||
background-color: #313543;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity {
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 1em;
|
|
||||||
padding-bottom: 2em;
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar img {
|
|
||||||
float: left;
|
|
||||||
border-radius: 4px;
|
|
||||||
margin-right: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.activity-content img, video, audio {
|
|
||||||
padding: 1em;
|
|
||||||
max-width: 800px;
|
|
||||||
max-height: 800px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#selected {
|
|
||||||
background-color: #1b2735;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counts dt, .counts dd {
|
|
||||||
float: left;
|
|
||||||
margin-left: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
a {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.h-card {
|
|
||||||
min-height: 48px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
|
|
||||||
header a, .h-card a {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
header a:hover, .h-card a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.display-name {
|
|
||||||
padding-top: 4px;
|
|
||||||
display: block;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* keep emoji from being hilariously huge */
|
|
||||||
.display-name img {
|
|
||||||
max-height: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.display-name .nickname {
|
|
||||||
padding-top: 4px;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nickname:hover {
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.pull-right {
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
.collapse {
|
|
||||||
margin: 0;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h2 {
|
|
||||||
color: #9baec8;
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 20px;
|
|
||||||
margin-bottom: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
form {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
background-color: rgba(0,0,0,.1);
|
|
||||||
color: white;
|
|
||||||
border: 0;
|
|
||||||
border-bottom: 2px solid #9baec8;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus {
|
|
||||||
border-bottom: 2px solid #4b8ed8;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type="checkbox"] {
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
color: white;
|
|
||||||
background-color: #419bdd;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 30px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-danger {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
color: #D8000C;
|
|
||||||
background-color: #FFD2D2;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.alert-info {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
color: #00529B;
|
|
||||||
background-color: #BDE5F8;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: none;
|
|
||||||
padding: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
var serviceWorkerOption = {"assets":["/static/fontello.1588431888583.css","/static/font/fontello.1588431888583.eot","/static/font/fontello.1588431888583.svg","/static/font/fontello.1588431888583.ttf","/static/font/fontello.1588431888583.woff","/static/font/fontello.1588431888583.woff2","/static/img/nsfw.74818f9.png","/static/css/app.1055039ce3f2fe4dd110.css","/static/js/app.57951e6e5e198d1a1266.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.c67e1a363ece7f1f7152.js","/static/js/2.93c984e8c993f92c77a1.js"]};
|
var serviceWorkerOption = {"assets":["/static/fontello.1589314090288.css","/static/font/fontello.1589314090288.eot","/static/font/fontello.1589314090288.svg","/static/font/fontello.1589314090288.ttf","/static/font/fontello.1589314090288.woff","/static/font/fontello.1589314090288.woff2","/static/img/nsfw.74818f9.png","/static/css/app.1055039ce3f2fe4dd110.css","/static/js/app.82334f8362acc4bbcb6f.js","/static/css/vendors~app.b2603a50868c68a1c192.css","/static/js/vendors~app.a516afd698489b59a809.js","/static/js/2.f9a5c4aba770b3f9f9e0.js"]};
|
||||||
|
|
||||||
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){
|
!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return r},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="/",t(t.s=1)}([function(e,n){
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -35,7 +35,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||||
|
|
||||||
test "refuses invalid requests" do
|
test "refuses invalid requests" do
|
||||||
capture_log(fn ->
|
capture_log(fn ->
|
||||||
assert {:error, {400, _}} = start_socket()
|
assert {:error, {404, _}} = start_socket()
|
||||||
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
assert {:error, {404, _}} = start_socket("?stream=ncjdk")
|
||||||
Process.sleep(30)
|
Process.sleep(30)
|
||||||
end)
|
end)
|
||||||
|
@ -43,8 +43,8 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||||
|
|
||||||
test "requires authentication and a valid token for protected streams" do
|
test "requires authentication and a valid token for protected streams" do
|
||||||
capture_log(fn ->
|
capture_log(fn ->
|
||||||
assert {:error, {403, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
assert {:error, {401, _}} = start_socket("?stream=user&access_token=aaaaaaaaaaaa")
|
||||||
assert {:error, {403, _}} = start_socket("?stream=user")
|
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||||
Process.sleep(30)
|
Process.sleep(30)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
@ -103,7 +103,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||||
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
assert {:ok, _} = start_socket("?stream=user&access_token=#{token.token}")
|
||||||
|
|
||||||
assert capture_log(fn ->
|
assert capture_log(fn ->
|
||||||
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user")
|
assert {:error, {401, _}} = start_socket("?stream=user")
|
||||||
Process.sleep(30)
|
Process.sleep(30)
|
||||||
end) =~ ":badarg"
|
end) =~ ":badarg"
|
||||||
end
|
end
|
||||||
|
@ -112,7 +112,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||||
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
assert {:ok, _} = start_socket("?stream=user:notification&access_token=#{token.token}")
|
||||||
|
|
||||||
assert capture_log(fn ->
|
assert capture_log(fn ->
|
||||||
assert {:error, {403, "Forbidden"}} = start_socket("?stream=user:notification")
|
assert {:error, {401, _}} = start_socket("?stream=user:notification")
|
||||||
Process.sleep(30)
|
Process.sleep(30)
|
||||||
end) =~ ":badarg"
|
end) =~ ":badarg"
|
||||||
end
|
end
|
||||||
|
@ -121,7 +121,7 @@ defmodule Pleroma.Integration.MastodonWebsocketTest do
|
||||||
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
|
assert {:ok, _} = start_socket("?stream=user", [{"Sec-WebSocket-Protocol", token.token}])
|
||||||
|
|
||||||
assert capture_log(fn ->
|
assert capture_log(fn ->
|
||||||
assert {:error, {403, "Forbidden"}} =
|
assert {:error, {401, _}} =
|
||||||
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
|
start_socket("?stream=user", [{"Sec-WebSocket-Protocol", "I am a friend"}])
|
||||||
|
|
||||||
Process.sleep(30)
|
Process.sleep(30)
|
||||||
|
|
|
@ -164,12 +164,13 @@ defmodule Pleroma.NotificationTest do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
task = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
||||||
task_user_notification = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
task_user_notification = Task.async(fn -> assert_receive {:text, _}, 4_000 end)
|
||||||
Streamer.add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})
|
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket("user", %{transport_pid: task.pid, assigns: %{user: user}})
|
||||||
"user:notification",
|
|
||||||
%{transport_pid: task_user_notification.pid, assigns: %{user: user}}
|
Streamer.get_topic_and_add_socket("user:notification", %{
|
||||||
)
|
transport_pid: task_user_notification.pid,
|
||||||
|
assigns: %{user: user}
|
||||||
|
})
|
||||||
|
|
||||||
activity = insert(:note_activity)
|
activity = insert(:note_activity)
|
||||||
|
|
||||||
|
|
|
@ -570,7 +570,10 @@ defmodule Pleroma.UserTest do
|
||||||
assert fetched_user == "not found nonexistant"
|
assert fetched_user == "not found nonexistant"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
clear_config([:instance, :user_bio_length])
|
||||||
|
|
||||||
test "updates an existing user, if stale" do
|
test "updates an existing user, if stale" do
|
||||||
|
Pleroma.Config.put([:instance, :user_bio_length], 1)
|
||||||
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
|
a_week_ago = NaiveDateTime.add(NaiveDateTime.utc_now(), -604_800)
|
||||||
|
|
||||||
orig_user =
|
orig_user =
|
||||||
|
|
|
@ -310,7 +310,11 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "/inbox" do
|
describe "/inbox" do
|
||||||
|
clear_config([:instance, :user_bio_length])
|
||||||
|
|
||||||
test "it inserts an incoming activity into the database", %{conn: conn} do
|
test "it inserts an incoming activity into the database", %{conn: conn} do
|
||||||
|
Pleroma.Config.put([:instance, :user_bio_length], 1)
|
||||||
|
|
||||||
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
data = File.read!("test/fixtures/mastodon-post-activity.json") |> Poison.decode!()
|
||||||
|
|
||||||
conn =
|
conn =
|
||||||
|
|
|
@ -1351,15 +1351,44 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
|
||||||
assert Repo.aggregate(Object, :count, :id) == 0
|
assert Repo.aggregate(Object, :count, :id) == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
|
clear_config([:instance, :federating])
|
||||||
|
|
||||||
test "creates a block activity" do
|
test "creates a block activity" do
|
||||||
|
Config.put([:instance, :federating], true)
|
||||||
blocker = insert(:user)
|
blocker = insert(:user)
|
||||||
blocked = insert(:user)
|
blocked = insert(:user)
|
||||||
|
|
||||||
|
with_mock Pleroma.Web.Federator,
|
||||||
|
publish: fn _ -> nil end do
|
||||||
{:ok, activity} = ActivityPub.block(blocker, blocked)
|
{:ok, activity} = ActivityPub.block(blocker, blocked)
|
||||||
|
|
||||||
assert activity.data["type"] == "Block"
|
assert activity.data["type"] == "Block"
|
||||||
assert activity.data["actor"] == blocker.ap_id
|
assert activity.data["actor"] == blocker.ap_id
|
||||||
assert activity.data["object"] == blocked.ap_id
|
assert activity.data["object"] == blocked.ap_id
|
||||||
|
|
||||||
|
assert called(Pleroma.Web.Federator.publish(activity))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
clear_config([:instance, :federating])
|
||||||
|
clear_config([:activitypub, :outgoing_blocks])
|
||||||
|
|
||||||
|
test "works with outgoing blocks disabled, but doesn't federate" do
|
||||||
|
Config.put([:instance, :federating], true)
|
||||||
|
Config.put([:activitypub, :outgoing_blocks], false)
|
||||||
|
blocker = insert(:user)
|
||||||
|
blocked = insert(:user)
|
||||||
|
|
||||||
|
with_mock Pleroma.Web.Federator,
|
||||||
|
publish: fn _ -> nil end do
|
||||||
|
{:ok, activity} = ActivityPub.block(blocker, blocked)
|
||||||
|
|
||||||
|
assert activity.data["type"] == "Block"
|
||||||
|
assert activity.data["actor"] == blocker.ap_id
|
||||||
|
assert activity.data["object"] == blocked.ap_id
|
||||||
|
|
||||||
|
refute called(Pleroma.Web.Federator.publish(:_))
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "reverts unblock activity on error" do
|
test "reverts unblock activity on error" do
|
||||||
|
|
|
@ -1120,6 +1120,12 @@ defmodule Pleroma.Web.ActivityPub.TransmogrifierTest do
|
||||||
follower = User.get_cached_by_id(follower.id)
|
follower = User.get_cached_by_id(follower.id)
|
||||||
|
|
||||||
assert User.following?(follower, followed) == true
|
assert User.following?(follower, followed) == true
|
||||||
|
|
||||||
|
follower = User.get_by_id(follower.id)
|
||||||
|
assert follower.following_count == 1
|
||||||
|
|
||||||
|
followed = User.get_by_id(followed.id)
|
||||||
|
assert followed.follower_count == 1
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it fails for incoming accepts which cannot be correlated" do
|
test "it fails for incoming accepts which cannot be correlated" do
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
|
defmodule Pleroma.Web.MastodonAPI.SuggestionControllerTest do
|
||||||
use Pleroma.Web.ConnCase
|
use Pleroma.Web.ConnCase
|
||||||
|
|
||||||
alias Pleroma.Config
|
|
||||||
|
|
||||||
setup do: oauth_access(["read"])
|
setup do: oauth_access(["read"])
|
||||||
|
|
||||||
test "returns empty result", %{conn: conn} do
|
test "returns empty result", %{conn: conn} do
|
||||||
|
|
|
@ -17,11 +17,81 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
@moduletag needs_streamer: true, capture_log: true
|
@moduletag needs_streamer: true, capture_log: true
|
||||||
|
|
||||||
@streamer_timeout 150
|
@streamer_timeout 300
|
||||||
@streamer_start_wait 10
|
@streamer_start_wait 10
|
||||||
|
|
||||||
clear_config([:instance, :skip_thread_containment])
|
clear_config([:instance, :skip_thread_containment])
|
||||||
|
|
||||||
|
describe "get_topic without an user" do
|
||||||
|
test "allows public" do
|
||||||
|
assert {:ok, "public"} = Streamer.get_topic("public", nil)
|
||||||
|
assert {:ok, "public:local"} = Streamer.get_topic("public:local", nil)
|
||||||
|
assert {:ok, "public:media"} = Streamer.get_topic("public:media", nil)
|
||||||
|
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "allows hashtag streams" do
|
||||||
|
assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", nil, %{"tag" => "cofe"})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disallows user streams" do
|
||||||
|
assert {:error, _} = Streamer.get_topic("user", nil)
|
||||||
|
assert {:error, _} = Streamer.get_topic("user:notification", nil)
|
||||||
|
assert {:error, _} = Streamer.get_topic("direct", nil)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disallows list streams" do
|
||||||
|
assert {:error, _} = Streamer.get_topic("list", nil, %{"list" => 42})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "get_topic with an user" do
|
||||||
|
setup do
|
||||||
|
user = insert(:user)
|
||||||
|
{:ok, %{user: user}}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "allows public streams", %{user: user} do
|
||||||
|
assert {:ok, "public"} = Streamer.get_topic("public", user)
|
||||||
|
assert {:ok, "public:local"} = Streamer.get_topic("public:local", user)
|
||||||
|
assert {:ok, "public:media"} = Streamer.get_topic("public:media", user)
|
||||||
|
assert {:ok, "public:local:media"} = Streamer.get_topic("public:local:media", user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "allows user streams", %{user: user} do
|
||||||
|
expected_user_topic = "user:#{user.id}"
|
||||||
|
expected_notif_topic = "user:notification:#{user.id}"
|
||||||
|
expected_direct_topic = "direct:#{user.id}"
|
||||||
|
assert {:ok, ^expected_user_topic} = Streamer.get_topic("user", user)
|
||||||
|
assert {:ok, ^expected_notif_topic} = Streamer.get_topic("user:notification", user)
|
||||||
|
assert {:ok, ^expected_direct_topic} = Streamer.get_topic("direct", user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "allows hashtag streams", %{user: user} do
|
||||||
|
assert {:ok, "hashtag:cofe"} = Streamer.get_topic("hashtag", user, %{"tag" => "cofe"})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disallows registering to an user stream", %{user: user} do
|
||||||
|
another_user = insert(:user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("user:#{another_user.id}", user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("user:notification:#{another_user.id}", user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("direct:#{another_user.id}", user)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "allows list stream that are owned by the user", %{user: user} do
|
||||||
|
{:ok, list} = List.create("Test", user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
|
||||||
|
assert {:ok, _} = Streamer.get_topic("list", user, %{"list" => list.id})
|
||||||
|
end
|
||||||
|
|
||||||
|
test "disallows list stream that are not owned by the user", %{user: user} do
|
||||||
|
another_user = insert(:user)
|
||||||
|
{:ok, list} = List.create("Test", another_user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("list:#{list.id}", user)
|
||||||
|
assert {:error, _} = Streamer.get_topic("list", user, %{"list" => list.id})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "user streams" do
|
describe "user streams" do
|
||||||
setup do
|
setup do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -35,7 +105,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
assert_receive {:text, _}, @streamer_timeout
|
assert_receive {:text, _}, @streamer_timeout
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user",
|
"user",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -50,7 +120,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
assert_receive {:text, _}, @streamer_timeout
|
assert_receive {:text, _}, @streamer_timeout
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user:notification",
|
"user:notification",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -70,7 +140,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user:notification",
|
"user:notification",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -90,7 +160,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user:notification",
|
"user:notification",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -110,7 +180,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user:notification",
|
"user:notification",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -127,7 +197,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
Process.sleep(@streamer_start_wait)
|
Process.sleep(@streamer_start_wait)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user:notification",
|
"user:notification",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -415,14 +485,10 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
assert_receive {:text, _}, 1_000
|
assert_receive {:text, _}, 1_000
|
||||||
end)
|
end)
|
||||||
|
|
||||||
fake_socket = %StreamerSocket{
|
Streamer.get_topic_and_add_socket(
|
||||||
transport_pid: task.pid,
|
"list",
|
||||||
user: user_a
|
%{transport_pid: task.pid, assigns: %{user: user_a}},
|
||||||
}
|
%{"list" => list.id}
|
||||||
|
|
||||||
Streamer.add_socket(
|
|
||||||
"list:#{list.id}",
|
|
||||||
fake_socket
|
|
||||||
)
|
)
|
||||||
|
|
||||||
Worker.handle_call({:stream, "list", activity}, self(), %{})
|
Worker.handle_call({:stream, "list", activity}, self(), %{})
|
||||||
|
@ -497,7 +563,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
task = Task.async(fn -> refute_receive {:text, _}, @streamer_timeout end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"user",
|
"user",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user2}}
|
%{transport_pid: task.pid, assigns: %{user: user2}}
|
||||||
)
|
)
|
||||||
|
@ -527,7 +593,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
assert last_status["pleroma"]["direct_conversation_id"] == participation.id
|
assert last_status["pleroma"]["direct_conversation_id"] == participation.id
|
||||||
end)
|
end)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"direct",
|
"direct",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -561,7 +627,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
Process.sleep(@streamer_start_wait)
|
Process.sleep(@streamer_start_wait)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"direct",
|
"direct",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
@ -604,7 +670,7 @@ defmodule Pleroma.Web.StreamerTest do
|
||||||
|
|
||||||
Process.sleep(@streamer_start_wait)
|
Process.sleep(@streamer_start_wait)
|
||||||
|
|
||||||
Streamer.add_socket(
|
Streamer.get_topic_and_add_socket(
|
||||||
"direct",
|
"direct",
|
||||||
%{transport_pid: task.pid, assigns: %{user: user}}
|
%{transport_pid: task.pid, assigns: %{user: user}}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in a new issue