Merge branch 'develop' into feature/keyword-policy

This commit is contained in:
rinpatch 2019-02-08 13:12:33 +03:00
commit 6c21f5aa16
46 changed files with 537 additions and 124 deletions

1
.gitignore vendored
View file

@ -25,6 +25,7 @@ erl_crash.dump
# secrets files as long as you replace their contents by environment # secrets files as long as you replace their contents by environment
# variables. # variables.
/config/*.secret.exs /config/*.secret.exs
/config/generated_config.exs
# Database setup file, some may forget to delete it # Database setup file, some may forget to delete it
/config/setup_db.psql /config/setup_db.psql

View file

@ -10,15 +10,14 @@ For clients it supports both the [GNU Social API with Qvitter extensions](https:
Client applications that are committed to supporting Pleroma: Client applications that are committed to supporting Pleroma:
* Mastalab (Android) * Mastalab (Android, Streaming Ready)
* Tusky (Android) * Tusky (Android, No Streaming)
* Twidere (Android) * Twidere (Android, No Streaming)
* Mast (iOS) * Mast (iOS)
* Amaroq (iOS) * Amaroq (iOS)
Client applications that are known to work well: Client applications that are known to work well:
* Pawoo (Android + iOS)
* Tootdon (Android + iOS) * Tootdon (Android + iOS)
* Tootle (iOS) * Tootle (iOS)
* Whalebird (Windows + Mac + Linux) * Whalebird (Windows + Mac + Linux)

View file

@ -115,7 +115,7 @@ config :logger, :console,
config :logger, :ex_syslogger, config :logger, :ex_syslogger,
level: :debug, level: :debug,
ident: "Pleroma", ident: "Pleroma",
format: "$date $time $metadata[$level] $message", format: "$metadata[$level] $message",
metadata: [:request_id] metadata: [:request_id]
config :mime, :types, %{ config :mime, :types, %{

View file

@ -100,6 +100,26 @@ config :pleroma, Pleroma.Mailer,
## :logger ## :logger
* `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog * `backends`: `:console` is used to send logs to stdout, `{ExSyslogger, :ex_syslogger}` to log to syslog
An example to enable ONLY ExSyslogger (f/ex in ``prod.secret.exs``) with info and debug suppressed:
```
config :logger,
backends: [{ExSyslogger, :ex_syslogger}]
config :logger, :ex_syslogger,
level: :warn
```
Another example, keeping console output and adding the pid to syslog output:
```
config :logger,
backends: [:console, {ExSyslogger, :ex_syslogger}]
config :logger, :ex_syslogger,
level: :warn,
option: [:pid, :ndelay]
```
See: [loggers documentation](https://hexdocs.pm/logger/Logger.html) and [ex_sysloggers documentation](https://hexdocs.pm/ex_syslogger/) See: [loggers documentation](https://hexdocs.pm/logger/Logger.html) and [ex_sysloggers documentation](https://hexdocs.pm/ex_syslogger/)

View file

@ -52,6 +52,14 @@ defmodule Mix.Tasks.Pleroma.User do
- `--locked`/`--no-locked` - whether the user's account is locked - `--locked`/`--no-locked` - whether the user's account is locked
- `--moderator`/`--no-moderator` - whether the user is a moderator - `--moderator`/`--no-moderator` - whether the user is a moderator
- `--admin`/`--no-admin` - whether the user is an admin - `--admin`/`--no-admin` - whether the user is an admin
## Add tags to a user.
mix pleroma.user tag NICKNAME TAGS
## Delete tags from a user.
mix pleroma.user untag NICKNAME TAGS
""" """
def run(["new", nickname, email | rest]) do def run(["new", nickname, email | rest]) do
{options, [], []} = {options, [], []} =
@ -249,6 +257,32 @@ defmodule Mix.Tasks.Pleroma.User do
end end
end end
def run(["tag", nickname | tags]) do
Common.start_pleroma()
with %User{} = user <- User.get_by_nickname(nickname) do
user = user |> User.tag(tags)
Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}")
else
_ ->
Mix.shell().error("Could not change user tags for #{nickname}")
end
end
def run(["untag", nickname | tags]) do
Common.start_pleroma()
with %User{} = user <- User.get_by_nickname(nickname) do
user = user |> User.untag(tags)
Mix.shell().info("Tags of #{user.nickname}: #{inspect(tags)}")
else
_ ->
Mix.shell().error("Could not change user tags for #{nickname}")
end
end
def run(["invite"]) do def run(["invite"]) do
Common.start_pleroma() Common.start_pleroma()

View file

@ -12,8 +12,10 @@ defmodule Pleroma.Config.DeprecationWarnings do
You are using the old configuration mechanism for the frontend. Please check config.md. You are using the old configuration mechanism for the frontend. Please check config.md.
""") """)
end end
end
if Pleroma.Config.get(:mrf_hellthread, :threshold) do def check_hellthread_threshold do
if Pleroma.Config.get([:mrf_hellthread, :threshold]) do
Logger.warn(""" Logger.warn("""
!!!DEPRECATION WARNING!!! !!!DEPRECATION WARNING!!!
You are using the old configuration mechanism for the hellthread filter. Please check config.md. You are using the old configuration mechanism for the hellthread filter. Please check config.md.
@ -23,5 +25,6 @@ defmodule Pleroma.Config.DeprecationWarnings do
def warn do def warn do
check_frontend_config_mechanism() check_frontend_config_mechanism()
check_hellthread_threshold()
end end
end end

View file

@ -59,6 +59,8 @@ defmodule Pleroma.HTML do
end) end)
end end
def extract_first_external_url(_, nil), do: {:error, "No content"}
def extract_first_external_url(object, content) do def extract_first_external_url(object, content) do
key = "URL|#{object.id}" key = "URL|#{object.id}"

View file

@ -23,6 +23,7 @@ defmodule Pleroma.User.Info do
field(:ap_enabled, :boolean, default: false) field(:ap_enabled, :boolean, default: false)
field(:is_moderator, :boolean, default: false) field(:is_moderator, :boolean, default: false)
field(:is_admin, :boolean, default: false) field(:is_admin, :boolean, default: false)
field(:show_role, :boolean, default: true)
field(:keys, :string, default: nil) field(:keys, :string, default: nil)
field(:settings, :map, default: nil) field(:settings, :map, default: nil)
field(:magic_key, :string, default: nil) field(:magic_key, :string, default: nil)
@ -30,7 +31,8 @@ defmodule Pleroma.User.Info do
field(:topic, :string, default: nil) field(:topic, :string, default: nil)
field(:hub, :string, default: nil) field(:hub, :string, default: nil)
field(:salmon, :string, default: nil) field(:salmon, :string, default: nil)
field(:hide_network, :boolean, default: false) field(:hide_followers, :boolean, default: false)
field(:hide_follows, :boolean, default: false)
field(:pinned_activities, {:array, :string}, default: []) field(:pinned_activities, {:array, :string}, default: [])
# Found in the wild # Found in the wild
@ -143,8 +145,10 @@ defmodule Pleroma.User.Info do
:no_rich_text, :no_rich_text,
:default_scope, :default_scope,
:banner, :banner,
:hide_network, :hide_follows,
:background :hide_followers,
:background,
:show_role
]) ])
end end
@ -194,7 +198,8 @@ defmodule Pleroma.User.Info do
info info
|> cast(params, [ |> cast(params, [
:is_moderator, :is_moderator,
:is_admin :is_admin,
:show_role
]) ])
end end

View file

@ -521,7 +521,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_actor(query, _), do: query defp restrict_actor(query, _), do: query
defp restrict_type(query, %{"type" => type}) when is_binary(type) do defp restrict_type(query, %{"type" => type}) when is_binary(type) do
restrict_type(query, %{"type" => [type]}) from(activity in query, where: fragment("?->>'type' = ?", activity.data, ^type))
end end
defp restrict_type(query, %{"type" => type}) do defp restrict_type(query, %{"type" => type}) do

View file

@ -198,6 +198,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
end end
end end
def whoami(%{assigns: %{user: %User{} = user}} = conn, _params) do
conn
|> put_resp_header("content-type", "application/activity+json")
|> json(UserView.render("user.json", %{user: user}))
end
def whoami(_conn, _params), do: {:error, :not_found}
def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do def read_inbox(%{assigns: %{user: user}} = conn, %{"nickname" => nickname} = params) do
if nickname == user.nickname do if nickname == user.nickname do
conn conn

View file

@ -0,0 +1,139 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2019 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ActivityPub.MRF.TagPolicy do
alias Pleroma.User
@behaviour Pleroma.Web.ActivityPub.MRF
defp get_tags(%User{tags: tags}) when is_list(tags), do: tags
defp get_tags(_), do: []
defp process_tag(
"mrf_tag:media-force-nsfw",
%{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
)
when length(child_attachment) > 0 do
tags = (object["tag"] || []) ++ ["nsfw"]
object =
object
|> Map.put("tags", tags)
|> Map.put("sensitive", true)
message = Map.put(message, "object", object)
{:ok, message}
end
defp process_tag(
"mrf_tag:media-strip",
%{"type" => "Create", "object" => %{"attachment" => child_attachment} = object} = message
)
when length(child_attachment) > 0 do
object = Map.delete(object, "attachment")
message = Map.put(message, "object", object)
{:ok, message}
end
defp process_tag(
"mrf_tag:force-unlisted",
%{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
) do
user = User.get_cached_by_ap_id(actor)
if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") do
to =
List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
cc =
List.delete(cc, user.follower_address) ++ ["https://www.w3.org/ns/activitystreams#Public"]
object =
message["object"]
|> Map.put("to", to)
|> Map.put("cc", cc)
message =
message
|> Map.put("to", to)
|> Map.put("cc", cc)
|> Map.put("object", object)
{:ok, message}
else
{:ok, message}
end
end
defp process_tag(
"mrf_tag:sandbox",
%{"type" => "Create", "to" => to, "cc" => cc, "actor" => actor} = message
) do
user = User.get_cached_by_ap_id(actor)
if Enum.member?(to, "https://www.w3.org/ns/activitystreams#Public") or
Enum.member?(cc, "https://www.w3.org/ns/activitystreams#Public") do
to =
List.delete(to, "https://www.w3.org/ns/activitystreams#Public") ++ [user.follower_address]
cc = List.delete(cc, "https://www.w3.org/ns/activitystreams#Public")
object =
message["object"]
|> Map.put("to", to)
|> Map.put("cc", cc)
message =
message
|> Map.put("to", to)
|> Map.put("cc", cc)
|> Map.put("object", object)
{:ok, message}
else
{:ok, message}
end
end
defp process_tag(
"mrf_tag:disable-remote-subscription",
%{"type" => "Follow", "actor" => actor} = message
) do
user = User.get_cached_by_ap_id(actor)
if user.local == true do
{:ok, message}
else
{:reject, nil}
end
end
defp process_tag("mrf_tag:disable-any-subscription", %{"type" => "Follow"}), do: {:reject, nil}
defp process_tag(_, message), do: {:ok, message}
def filter_message(actor, message) do
User.get_cached_by_ap_id(actor)
|> get_tags()
|> Enum.reduce({:ok, message}, fn
tag, {:ok, message} ->
process_tag(tag, message)
_, error ->
error
end)
end
@impl true
def filter(%{"object" => target_actor, "type" => "Follow"} = message),
do: filter_message(target_actor, message)
@impl true
def filter(%{"actor" => actor, "type" => "Create"} = message),
do: filter_message(actor, message)
@impl true
def filter(message), do: {:ok, message}
end

View file

@ -313,6 +313,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> Map.put("tag", combined) |> Map.put("tag", combined)
end end
def fix_tag(%{"tag" => %{} = tag} = object), do: Map.put(object, "tag", [tag])
def fix_tag(object), do: object def fix_tag(object), do: object
# content map usually only has one language so this will do for now. # content map usually only has one language so this will do for now.

View file

@ -86,7 +86,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
query = from(user in query, select: [:ap_id]) query = from(user in query, select: [:ap_id])
following = Repo.all(query) following = Repo.all(query)
collection(following, "#{user.ap_id}/following", page, !user.info.hide_network) collection(following, "#{user.ap_id}/following", page, !user.info.hide_follows)
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end
@ -99,7 +99,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"id" => "#{user.ap_id}/following", "id" => "#{user.ap_id}/following",
"type" => "OrderedCollection", "type" => "OrderedCollection",
"totalItems" => length(following), "totalItems" => length(following),
"first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_network) "first" => collection(following, "#{user.ap_id}/following", 1, !user.info.hide_follows)
} }
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end
@ -109,7 +109,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
query = from(user in query, select: [:ap_id]) query = from(user in query, select: [:ap_id])
followers = Repo.all(query) followers = Repo.all(query)
collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_network) collection(followers, "#{user.ap_id}/followers", page, !user.info.hide_followers)
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end
@ -122,7 +122,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"id" => "#{user.ap_id}/followers", "id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection", "type" => "OrderedCollection",
"totalItems" => length(followers), "totalItems" => length(followers),
"first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_network) "first" => collection(followers, "#{user.ap_id}/followers", 1, !user.info.hide_followers)
} }
|> Map.merge(Utils.make_json_ld_header()) |> Map.merge(Utils.make_json_ld_header())
end end
@ -239,6 +239,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do
if offset < total do if offset < total do
Map.put(map, "next", "#{iri}?page=#{page + 1}") Map.put(map, "next", "#{iri}?page=#{page + 1}")
else
map
end end
end end
end end

View file

@ -605,7 +605,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
followers = followers =
cond do cond do
for_user && user.id == for_user.id -> followers for_user && user.id == for_user.id -> followers
user.info.hide_network -> [] user.info.hide_followers -> []
true -> followers true -> followers
end end
@ -621,7 +621,7 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do
followers = followers =
cond do cond do
for_user && user.id == for_user.id -> followers for_user && user.id == for_user.id -> followers
user.info.hide_network -> [] user.info.hide_follows -> []
true -> followers true -> followers
end end

View file

@ -182,18 +182,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end end
def render("card.json", %{rich_media: rich_media, page_url: page_url}) do def render("card.json", %{rich_media: rich_media, page_url: page_url}) do
page_url_data = URI.parse(page_url)
page_url_data = page_url_data =
if rich_media[:url] != nil do if rich_media[:url] != nil do
URI.merge(URI.parse(page_url), URI.parse(rich_media[:url])) URI.merge(page_url_data, URI.parse(rich_media[:url]))
else else
page_url page_url_data
end end
page_url = page_url_data |> to_string page_url = page_url_data |> to_string
image_url = image_url =
URI.merge(page_url_data, URI.parse(rich_media[:image])) if rich_media[:image] != nil do
|> to_string URI.merge(page_url_data, URI.parse(rich_media[:image]))
|> to_string
else
nil
end
site_name = rich_media[:site_name] || page_url_data.host site_name = rich_media[:site_name] || page_url_data.host

View file

@ -54,22 +54,12 @@ defmodule Pleroma.Web.RichMedia.Parser do
{:error, "Found metadata was invalid or incomplete: #{inspect(data)}"} {:error, "Found metadata was invalid or incomplete: #{inspect(data)}"}
end end
defp string_is_valid_unicode(data) when is_binary(data) do
data
|> :unicode.characters_to_binary()
|> clean_string()
end
defp string_is_valid_unicode(data), do: {:ok, data}
defp clean_string({:error, _, _}), do: {:error, "Invalid data"}
defp clean_string(data), do: {:ok, data}
defp clean_parsed_data(data) do defp clean_parsed_data(data) do
data data
|> Enum.reject(fn {_, val} -> |> Enum.reject(fn {key, val} ->
case string_is_valid_unicode(val) do with {:ok, _} <- Jason.encode(%{key => val}) do
{:ok, _} -> false false
else
_ -> true _ -> true
end end
end) end)

View file

@ -454,6 +454,7 @@ defmodule Pleroma.Web.Router do
scope "/", Pleroma.Web.ActivityPub do scope "/", Pleroma.Web.ActivityPub do
pipe_through([:activitypub_client]) pipe_through([:activitypub_client])
get("/api/ap/whoami", ActivityPubController, :whoami)
get("/users/:nickname/inbox", ActivityPubController, :read_inbox) get("/users/:nickname/inbox", ActivityPubController, :read_inbox)
post("/users/:nickname/outbox", ActivityPubController, :update_outbox) post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
end end

View file

@ -24,7 +24,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
conn conn
|> put_view(UserView) |> put_view(UserView)
|> render("show.json", %{user: user, token: token}) |> render("show.json", %{user: user, token: token, for: user})
end end
def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do
@ -503,7 +503,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
followers = followers =
cond do cond do
for_user && user.id == for_user.id -> followers for_user && user.id == for_user.id -> followers
user.info.hide_network -> [] user.info.hide_followers -> []
true -> followers true -> followers
end end
@ -523,7 +523,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
friends = friends =
cond do cond do
for_user && user.id == for_user.id -> friends for_user && user.id == for_user.id -> friends
user.info.hide_network -> [] user.info.hide_follows -> []
true -> friends true -> friends
end end
@ -618,7 +618,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
defp build_info_cng(user, params) do defp build_info_cng(user, params) do
info_params = info_params =
["no_rich_text", "locked", "hide_network"] ["no_rich_text", "locked", "hide_followers", "hide_follows", "show_role"]
|> Enum.reduce(%{}, fn key, res -> |> Enum.reduce(%{}, fn key, res ->
if value = params[key] do if value = params[key] do
Map.put(res, key, value == "true") Map.put(res, key, value == "true")

View file

@ -108,7 +108,8 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"locked" => user.info.locked, "locked" => user.info.locked,
"default_scope" => user.info.default_scope, "default_scope" => user.info.default_scope,
"no_rich_text" => user.info.no_rich_text, "no_rich_text" => user.info.no_rich_text,
"hide_network" => user.info.hide_network, "hide_followers" => user.info.hide_followers,
"hide_follows" => user.info.hide_follows,
"fields" => fields, "fields" => fields,
# Pleroma extension # Pleroma extension
@ -118,6 +119,12 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
} }
} }
data =
if(user.info.is_admin || user.info.is_moderator,
do: maybe_with_role(data, user, for_user),
else: data
)
if assigns[:token] do if assigns[:token] do
Map.put(data, "token", token_string(assigns[:token])) Map.put(data, "token", token_string(assigns[:token]))
else else
@ -125,6 +132,20 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
end end
end end
defp maybe_with_role(data, %User{id: id} = user, %User{id: id}) do
Map.merge(data, %{"role" => role(user), "show_role" => user.info.show_role})
end
defp maybe_with_role(data, %User{info: %{show_role: true}} = user, _user) do
Map.merge(data, %{"role" => role(user)})
end
defp maybe_with_role(data, _, _), do: data
defp role(%User{info: %{:is_admin => true}}), do: "admin"
defp role(%User{info: %{:is_moderator => true}}), do: "moderator"
defp role(_), do: "member"
defp image_url(%{"url" => [%{"href" => href} | _]}), do: href defp image_url(%{"url" => [%{"href" => href} | _]}), do: href
defp image_url(_), do: nil defp image_url(_), do: nil

View file

@ -0,0 +1,12 @@
defmodule Pleroma.Repo.Migrations.SplitHideNetwork do
use Ecto.Migration
def up do
execute("UPDATE users SET info = jsonb_set(info, '{hide_network}'::text[], 'false'::jsonb) WHERE NOT(info::jsonb ? 'hide_network')")
execute("UPDATE users SET info = jsonb_set(info, '{hide_followings}'::text[], info->'hide_network')")
execute("UPDATE users SET info = jsonb_set(info, '{hide_followers}'::text[], info->'hide_network')")
end
def down do
end
end

View file

@ -0,0 +1,30 @@
defmodule Pleroma.Repo.Migrations.AddCorrectDMIndex do
use Ecto.Migration
@disable_ddl_transaction true
def up do
drop_if_exists(
index(:activities, ["activity_visibility(actor, recipients, data)"],
name: :activities_visibility_index
)
)
create(
index(:activities, ["activity_visibility(actor, recipients, data)", "id DESC NULLS LAST"],
name: :activities_visibility_index,
concurrently: true,
where: "data->>'type' = 'Create'"
)
)
end
def down do
drop(
index(:activities, ["activity_visibility(actor, recipients, data)", "id DESC"],
name: :activities_visibility_index,
concurrently: true,
where: "data->>'type' = 'Create'"
)
)
end
end

View file

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.6aa5664a1a2c0832ce7b.js></script><script type=text/javascript src=/static/js/vendor.56a115a1d7339d6811a0.js></script><script type=text/javascript src=/static/js/app.59ebcfb47f86a7a5ba3f.js></script></body></html> <!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.d75cda10f04aeefec7b657f8244070e9.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.f00ab54db04706aab2c9.js></script><script type=text/javascript src=/static/js/vendor.5173dfeead1ded3d1f46.js></script><script type=text/javascript src=/static/js/app.0e4952ec8d775da840f1.js></script></body></html>

View file

@ -19,8 +19,5 @@
"loginMethod": "password", "loginMethod": "password",
"webPushNotifications": false, "webPushNotifications": false,
"noAttachmentLinks": false, "noAttachmentLinks": false,
"nsfwCensorImage": "", "nsfwCensorImage": ""
"useOneClickNsfw": true,
"playVideosInline": false,
"useContainFit": false
} }

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

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

View file

@ -1,2 +0,0 @@
!function(e){function t(a){if(r[a])return r[a].exports;var n=r[a]={exports:{},id:a,loaded:!1};return e[a].call(n.exports,n,n.exports,t),n.loaded=!0,n.exports}var a=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],n[l]&&i.push.apply(i,n[l]),n[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(a&&a(o,p);i.length;)i.shift().call(null,t);if(p[0])return r[0]=0,t(0)};var r={},n={0:0};t.e=function(e,a){if(0===n[e])return a.call(null,t);if(void 0!==n[e])n[e].push(a);else{n[e]=[a];var r=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"56a115a1d7339d6811a0",2:"59ebcfb47f86a7a5ba3f"}[e]+".js",r.appendChild(o)}},t.m=e,t.c=r,t.p="/"}([]);
//# sourceMappingURL=manifest.6aa5664a1a2c0832ce7b.js.map

View file

@ -0,0 +1,2 @@
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,d=[];s<o.length;s++)l=o[s],a[l]&&d.push.apply(d,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);d.length;)d.shift().call(null,t);if(p[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"5173dfeead1ded3d1f46",2:"0e4952ec8d775da840f1"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
//# sourceMappingURL=manifest.f00ab54db04706aab2c9.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
var serviceWorkerOption = {"assets":["/static/img/nsfw.74818f9.png","/static/js/manifest.6aa5664a1a2c0832ce7b.js","/static/js/vendor.56a115a1d7339d6811a0.js","/static/js/app.59ebcfb47f86a7a5ba3f.js","/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css"]}; var serviceWorkerOption = {"assets":["/static/img/nsfw.74818f9.png","/static/js/manifest.f00ab54db04706aab2c9.js","/static/js/vendor.5173dfeead1ded3d1f46.js","/static/js/app.0e4952ec8d775da840f1.js","/static/css/app.d75cda10f04aeefec7b657f8244070e9.css"]};
!function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var t={};return n.m=e,n.c=t,n.p="/",n(0)}([function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return u.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications})}function i(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){var n=e.type;return"window"===n})})}var a=t(1),u=r(a);self.addEventListener("push",function(e){e.data&&e.waitUntil(o().then(function(n){return n&&i().then(function(n){var t=e.data.json();if(0===n.length)return self.registration.showNotification(t.title,t)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(i().then(function(e){for(var n=0;n<e.length;n++){var t=e[n];if("/"===t.url&&"focus"in t)return t.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,n){/*! !function(e){function n(r){if(t[r])return t[r].exports;var o=t[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,n),o.loaded=!0,o.exports}var t={};return n.m=e,n.c=t,n.p="/",n(0)}([function(e,n,t){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return u.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications})}function i(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){var n=e.type;return"window"===n})})}var a=t(1),u=r(a);self.addEventListener("push",function(e){e.data&&e.waitUntil(o().then(function(n){return n&&i().then(function(n){var t=e.data.json();if(0===n.length)return self.registration.showNotification(t.title,t)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(i().then(function(e){for(var n=0;n<e.length;n++){var t=e[n];if("/"===t.url&&"focus"in t)return t.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,n){/*!
localForage -- Offline Storage, Improved localForage -- Offline Storage, Improved

File diff suppressed because one or more lines are too long

1
priv/static/sw.js.map Normal file

File diff suppressed because one or more lines are too long

View file

@ -386,9 +386,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["first"]["orderedItems"] == [user.ap_id] assert result["first"]["orderedItems"] == [user.ap_id]
end end
test "it returns returns empty if the user has 'hide_network' set", %{conn: conn} do test "it returns returns empty if the user has 'hide_followers' set", %{conn: conn} do
user = insert(:user) user = insert(:user)
user_two = insert(:user, %{info: %{hide_network: true}}) user_two = insert(:user, %{info: %{hide_followers: true}})
User.follow(user, user_two) User.follow(user, user_two)
result = result =
@ -441,8 +441,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["first"]["orderedItems"] == [user_two.ap_id] assert result["first"]["orderedItems"] == [user_two.ap_id]
end end
test "it returns returns empty if the user has 'hide_network' set", %{conn: conn} do test "it returns returns empty if the user has 'hide_follows' set", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}}) user = insert(:user, %{info: %{hide_follows: true}})
user_two = insert(:user) user_two = insert(:user)
User.follow(user, user_two) User.follow(user, user_two)

View file

@ -1101,9 +1101,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(user.id) assert id == to_string(user.id)
end end
test "getting followers, hide_network", %{conn: conn} do test "getting followers, hide_followers", %{conn: conn} do
user = insert(:user) user = insert(:user)
other_user = insert(:user, %{info: %{hide_network: true}}) other_user = insert(:user, %{info: %{hide_followers: true}})
{:ok, _user} = User.follow(user, other_user) {:ok, _user} = User.follow(user, other_user)
conn = conn =
@ -1113,9 +1113,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [] == json_response(conn, 200) assert [] == json_response(conn, 200)
end end
test "getting followers, hide_network, same user requesting", %{conn: conn} do test "getting followers, hide_followers, same user requesting", %{conn: conn} do
user = insert(:user) user = insert(:user)
other_user = insert(:user, %{info: %{hide_network: true}}) other_user = insert(:user, %{info: %{hide_followers: true}})
{:ok, _user} = User.follow(user, other_user) {:ok, _user} = User.follow(user, other_user)
conn = conn =
@ -1139,8 +1139,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(other_user.id) assert id == to_string(other_user.id)
end end
test "getting following, hide_network", %{conn: conn} do test "getting following, hide_follows", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}}) user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user) other_user = insert(:user)
{:ok, user} = User.follow(user, other_user) {:ok, user} = User.follow(user, other_user)
@ -1151,8 +1151,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [] == json_response(conn, 200) assert [] == json_response(conn, 200)
end end
test "getting following, hide_network, same user requesting", %{conn: conn} do test "getting following, hide_follows, same user requesting", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}}) user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user) other_user = insert(:user)
{:ok, user} = User.follow(user, other_user) {:ok, user} = User.follow(user, other_user)

View file

@ -235,4 +235,59 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
] ]
end end
end end
describe "rich media cards" do
test "a rich media card without a site name renders correctly" do
page_url = "http://example.com"
card = %{
url: page_url,
image: page_url <> "/example.jpg",
title: "Example website"
}
%{provider_name: "example.com"} =
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
end
test "a rich media card without a site name or image renders correctly" do
page_url = "http://example.com"
card = %{
url: page_url,
title: "Example website"
}
%{provider_name: "example.com"} =
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
end
test "a rich media card without an image renders correctly" do
page_url = "http://example.com"
card = %{
url: page_url,
site_name: "Example site name",
title: "Example website"
}
%{provider_name: "Example site name"} =
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
end
test "a rich media card with all relevant data renders correctly" do
page_url = "http://example.com"
card = %{
url: page_url,
site_name: "Example site name",
title: "Example website",
image: page_url <> "/example.jpg",
description: "Example description"
}
%{provider_name: "Example site name"} =
StatusView.render("card.json", %{page_url: page_url, rich_media: card})
end
end
end end

View file

@ -62,7 +62,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> post("/api/account/verify_credentials.json") |> post("/api/account/verify_credentials.json")
|> json_response(200) |> json_response(200)
assert response == UserView.render("show.json", %{user: user, token: response["token"]}) assert response ==
UserView.render("show.json", %{user: user, token: response["token"], for: user})
end end
end end
@ -107,7 +108,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> post(request_path, %{status: "Nice meme.", visibility: "private"}) |> post(request_path, %{status: "Nice meme.", visibility: "private"})
assert json_response(conn, 200) == assert json_response(conn, 200) ==
ActivityRepresenter.to_map(Repo.one(Activity), %{user: user}) ActivityRepresenter.to_map(Repo.one(Activity), %{user: user, for: user})
end end
end end
@ -418,6 +419,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert Enum.at(response, 0) == assert Enum.at(response, 0) ==
ActivityRepresenter.to_map(activity, %{ ActivityRepresenter.to_map(activity, %{
user: current_user, user: current_user,
for: current_user,
mentioned: [current_user] mentioned: [current_user]
}) })
end end
@ -547,7 +549,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200) response = json_response(conn, 200)
assert length(response) == 1 assert length(response) == 1
assert Enum.at(response, 0) == ActivityRepresenter.to_map(activity, %{user: current_user})
assert Enum.at(response, 0) ==
ActivityRepresenter.to_map(activity, %{user: current_user, for: current_user})
end end
test "with credentials with user_id", %{conn: conn, user: current_user} do test "with credentials with user_id", %{conn: conn, user: current_user} do
@ -1132,8 +1136,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
) )
end end
test "it returns empty for a hidden network", %{conn: conn} do test "it returns empty when hide_followers is set to true", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}}) user = insert(:user, %{info: %{hide_followers: true}})
follower_one = insert(:user) follower_one = insert(:user)
follower_two = insert(:user) follower_two = insert(:user)
not_follower = insert(:user) not_follower = insert(:user)
@ -1150,10 +1154,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert [] == response assert [] == response
end end
test "it returns the followers for a hidden network if requested by the user themselves", %{ test "it returns the followers when hide_followers is set to true if requested by the user themselves",
conn: conn %{
} do conn: conn
user = insert(:user, %{info: %{hide_network: true}}) } do
user = insert(:user, %{info: %{hide_followers: true}})
follower_one = insert(:user) follower_one = insert(:user)
follower_two = insert(:user) follower_two = insert(:user)
_not_follower = insert(:user) _not_follower = insert(:user)
@ -1256,8 +1261,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
) )
end end
test "it returns empty for a hidden network", %{conn: conn} do test "it returns empty when hide_follows is set to true", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}}) user = insert(:user, %{info: %{hide_follows: true}})
followed_one = insert(:user) followed_one = insert(:user)
followed_two = insert(:user) followed_two = insert(:user)
not_followed = insert(:user) not_followed = insert(:user)
@ -1273,10 +1278,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert [] == json_response(conn, 200) assert [] == json_response(conn, 200)
end end
test "it returns friends for a hidden network if the user themselves request it", %{ test "it returns friends when hide_follows is set to true if the user themselves request it",
conn: conn %{
} do conn: conn
user = insert(:user, %{info: %{hide_network: true}}) } do
user = insert(:user, %{info: %{hide_follows: true}})
followed_one = insert(:user) followed_one = insert(:user)
followed_two = insert(:user) followed_two = insert(:user)
_not_followed = insert(:user) _not_followed = insert(:user)
@ -1364,27 +1370,75 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end end
test "it sets and un-sets hide_network", %{conn: conn} do test "it sets and un-sets hide_follows", %{conn: conn} do
user = insert(:user) user = insert(:user)
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post("/api/account/update_profile.json", %{ |> post("/api/account/update_profile.json", %{
"hide_network" => "true" "hide_follows" => "true"
}) })
user = Repo.get!(User, user.id) user = Repo.get!(User, user.id)
assert user.info.hide_network == true assert user.info.hide_follows == true
conn = conn =
conn conn
|> assign(:user, user) |> assign(:user, user)
|> post("/api/account/update_profile.json", %{ |> post("/api/account/update_profile.json", %{
"hide_network" => "false" "hide_follows" => "false"
}) })
user = Repo.get!(User, user.id) user = Repo.get!(User, user.id)
assert user.info.hide_network == false assert user.info.hide_follows == false
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end
test "it sets and un-sets hide_followers", %{conn: conn} do
user = insert(:user)
conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"hide_followers" => "true"
})
user = Repo.get!(User, user.id)
assert user.info.hide_followers == true
conn =
conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"hide_followers" => "false"
})
user = Repo.get!(User, user.id)
assert user.info.hide_followers == false
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end
test "it sets and un-sets show_role", %{conn: conn} do
user = insert(:user)
conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"show_role" => "true"
})
user = Repo.get!(User, user.id)
assert user.info.show_role == true
conn =
conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"show_role" => "false"
})
user = Repo.get!(User, user.id)
assert user.info.show_role == false
assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user}) assert json_response(conn, 200) == UserView.render("user.json", %{user: user, for: user})
end end
@ -1788,7 +1842,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
user = refresh_record(user) user = refresh_record(user)
assert json_response(response, 200) == ActivityRepresenter.to_map(activity, %{user: user}) assert json_response(response, 200) ==
ActivityRepresenter.to_map(activity, %{user: user, for: user})
end end
end end
@ -1817,7 +1872,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
user = refresh_record(user) user = refresh_record(user)
assert json_response(response, 200) == ActivityRepresenter.to_map(activity, %{user: user}) assert json_response(response, 200) ==
ActivityRepresenter.to_map(activity, %{user: user, for: user})
end end
end end
end end

View file

@ -36,6 +36,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
describe "GET /api/statusnet/config.json" do describe "GET /api/statusnet/config.json" do
test "it returns the managed config", %{conn: conn} do test "it returns the managed config", %{conn: conn} do
Pleroma.Config.put([:instance, :managed_config], false) Pleroma.Config.put([:instance, :managed_config], false)
Pleroma.Config.put([:fe], theme: "rei-ayanami-towel")
response = response =
conn conn

View file

@ -100,7 +100,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false, "locked" => false,
"default_scope" => "public", "default_scope" => "public",
"no_rich_text" => false, "no_rich_text" => false,
"hide_network" => false, "hide_follows" => false,
"hide_followers" => false,
"fields" => [], "fields" => [],
"pleroma" => %{ "pleroma" => %{
"confirmation_pending" => false, "confirmation_pending" => false,
@ -147,7 +148,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false, "locked" => false,
"default_scope" => "public", "default_scope" => "public",
"no_rich_text" => false, "no_rich_text" => false,
"hide_network" => false, "hide_follows" => false,
"hide_followers" => false,
"fields" => [], "fields" => [],
"pleroma" => %{ "pleroma" => %{
"confirmation_pending" => false, "confirmation_pending" => false,
@ -195,7 +197,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false, "locked" => false,
"default_scope" => "public", "default_scope" => "public",
"no_rich_text" => false, "no_rich_text" => false,
"hide_network" => false, "hide_follows" => false,
"hide_followers" => false,
"fields" => [], "fields" => [],
"pleroma" => %{ "pleroma" => %{
"confirmation_pending" => false, "confirmation_pending" => false,
@ -211,6 +214,7 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
represented = UserView.render("show.json", %{user: user, for: user}) represented = UserView.render("show.json", %{user: user, for: user})
assert represented["rights"]["delete_others_notice"] assert represented["rights"]["delete_others_notice"]
assert represented["role"] == "moderator"
end end
test "a user that is a admin" do test "a user that is a admin" do
@ -218,6 +222,21 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
represented = UserView.render("show.json", %{user: user, for: user}) represented = UserView.render("show.json", %{user: user, for: user})
assert represented["rights"]["admin"] assert represented["rights"]["admin"]
assert represented["role"] == "admin"
end
test "A moderator with hidden role for another user", %{user: user} do
admin = insert(:user, %{info: %{is_moderator: true, show_role: false}})
represented = UserView.render("show.json", %{user: admin, for: user})
assert represented["role"] == nil
end
test "An admin with hidden role for another user", %{user: user} do
admin = insert(:user, %{info: %{is_admin: true, show_role: false}})
represented = UserView.render("show.json", %{user: admin, for: user})
assert represented["role"] == nil
end end
test "A blocked user for the blocker" do test "A blocked user for the blocker" do
@ -257,7 +276,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false, "locked" => false,
"default_scope" => "public", "default_scope" => "public",
"no_rich_text" => false, "no_rich_text" => false,
"hide_network" => false, "hide_follows" => false,
"hide_followers" => false,
"fields" => [], "fields" => [],
"pleroma" => %{ "pleroma" => %{
"confirmation_pending" => false, "confirmation_pending" => false,