Browse Source

Merge branch 'develop' into feature/keyword-policy

tags/v1.1.4
rinpatch 5 years ago
parent
commit
6c21f5aa16
46 changed files with 537 additions and 124 deletions
  1. +1
    -0
      .gitignore
  2. +3
    -4
      README.md
  3. +1
    -1
      config/config.exs
  4. +20
    -0
      docs/config.md
  5. +34
    -0
      lib/mix/tasks/pleroma/user.ex
  6. +4
    -1
      lib/pleroma/config/deprecation_warnings.ex
  7. +2
    -0
      lib/pleroma/html.ex
  8. +9
    -4
      lib/pleroma/user/info.ex
  9. +1
    -1
      lib/pleroma/web/activity_pub/activity_pub.ex
  10. +8
    -0
      lib/pleroma/web/activity_pub/activity_pub_controller.ex
  11. +139
    -0
      lib/pleroma/web/activity_pub/mrf/tag_policy.ex
  12. +2
    -0
      lib/pleroma/web/activity_pub/transmogrifier.ex
  13. +6
    -4
      lib/pleroma/web/activity_pub/views/user_view.ex
  14. +2
    -2
      lib/pleroma/web/mastodon_api/mastodon_api_controller.ex
  15. +10
    -4
      lib/pleroma/web/mastodon_api/views/status_view.ex
  16. +4
    -14
      lib/pleroma/web/rich_media/parser.ex
  17. +1
    -0
      lib/pleroma/web/router.ex
  18. +4
    -4
      lib/pleroma/web/twitter_api/twitter_api_controller.ex
  19. +22
    -1
      lib/pleroma/web/twitter_api/views/user_view.ex
  20. +12
    -0
      priv/repo/migrations/20190203185340_split_hide_network.exs
  21. +30
    -0
      priv/repo/migrations/20190204200237_add_correct_dm_index.exs
  22. +1
    -1
      priv/static/index.html
  23. +1
    -4
      priv/static/static/config.json
  24. +0
    -2
      priv/static/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css
  25. +0
    -1
      priv/static/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css.map
  26. +2
    -0
      priv/static/static/css/app.d75cda10f04aeefec7b657f8244070e9.css
  27. +1
    -0
      priv/static/static/css/app.d75cda10f04aeefec7b657f8244070e9.css.map
  28. +16
    -0
      priv/static/static/js/app.0e4952ec8d775da840f1.js
  29. +1
    -0
      priv/static/static/js/app.0e4952ec8d775da840f1.js.map
  30. +0
    -15
      priv/static/static/js/app.59ebcfb47f86a7a5ba3f.js
  31. +0
    -1
      priv/static/static/js/app.59ebcfb47f86a7a5ba3f.js.map
  32. +0
    -2
      priv/static/static/js/manifest.6aa5664a1a2c0832ce7b.js
  33. +2
    -0
      priv/static/static/js/manifest.f00ab54db04706aab2c9.js
  34. +1
    -1
      priv/static/static/js/manifest.f00ab54db04706aab2c9.js.map
  35. +14
    -14
      priv/static/static/js/vendor.5173dfeead1ded3d1f46.js
  36. +1
    -0
      priv/static/static/js/vendor.5173dfeead1ded3d1f46.js.map
  37. +0
    -1
      priv/static/static/js/vendor.56a115a1d7339d6811a0.js.map
  38. +1
    -1
      priv/static/sw-pleroma.js
  39. +10
    -3
      priv/static/sw.js
  40. +1
    -0
      priv/static/sw.js.map
  41. +4
    -4
      test/web/activity_pub/activity_pub_controller_test.exs
  42. +8
    -8
      test/web/mastodon_api/mastodon_api_controller_test.exs
  43. +55
    -0
      test/web/mastodon_api/status_view_test.exs
  44. +78
    -22
      test/web/twitter_api/twitter_api_controller_test.exs
  45. +1
    -0
      test/web/twitter_api/util_controller_test.exs
  46. +24
    -4
      test/web/twitter_api/views/user_view_test.exs

+ 1
- 0
.gitignore View File

@@ -25,6 +25,7 @@ erl_crash.dump
# secrets files as long as you replace their contents by environment
# variables.
/config/*.secret.exs
/config/generated_config.exs

# Database setup file, some may forget to delete it
/config/setup_db.psql


+ 3
- 4
README.md 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:

* Mastalab (Android)
* Tusky (Android)
* Twidere (Android)
* Mastalab (Android, Streaming Ready)
* Tusky (Android, No Streaming)
* Twidere (Android, No Streaming)
* Mast (iOS)
* Amaroq (iOS)

Client applications that are known to work well:

* Pawoo (Android + iOS)
* Tootdon (Android + iOS)
* Tootle (iOS)
* Whalebird (Windows + Mac + Linux)


+ 1
- 1
config/config.exs View File

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

config :mime, :types, %{


+ 20
- 0
docs/config.md View File

@@ -100,6 +100,26 @@ config :pleroma, Pleroma.Mailer,

## :logger
* `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: [logger’s documentation](https://hexdocs.pm/logger/Logger.html) and [ex_syslogger’s documentation](https://hexdocs.pm/ex_syslogger/)




+ 34
- 0
lib/mix/tasks/pleroma/user.ex View File

@@ -52,6 +52,14 @@ defmodule Mix.Tasks.Pleroma.User do
- `--locked`/`--no-locked` - whether the user's account is locked
- `--moderator`/`--no-moderator` - whether the user is a moderator
- `--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
{options, [], []} =
@@ -249,6 +257,32 @@ defmodule Mix.Tasks.Pleroma.User do
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
Common.start_pleroma()



+ 4
- 1
lib/pleroma/config/deprecation_warnings.ex 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.
""")
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("""
!!!DEPRECATION WARNING!!!
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
check_frontend_config_mechanism()
check_hellthread_threshold()
end
end

+ 2
- 0
lib/pleroma/html.ex View File

@@ -59,6 +59,8 @@ defmodule Pleroma.HTML do
end)
end

def extract_first_external_url(_, nil), do: {:error, "No content"}

def extract_first_external_url(object, content) do
key = "URL|#{object.id}"



+ 9
- 4
lib/pleroma/user/info.ex View File

@@ -23,6 +23,7 @@ defmodule Pleroma.User.Info do
field(:ap_enabled, :boolean, default: false)
field(:is_moderator, :boolean, default: false)
field(:is_admin, :boolean, default: false)
field(:show_role, :boolean, default: true)
field(:keys, :string, default: nil)
field(:settings, :map, default: nil)
field(:magic_key, :string, default: nil)
@@ -30,7 +31,8 @@ defmodule Pleroma.User.Info do
field(:topic, :string, default: nil)
field(:hub, :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: [])

# Found in the wild
@@ -143,8 +145,10 @@ defmodule Pleroma.User.Info do
:no_rich_text,
:default_scope,
:banner,
:hide_network,
:background
:hide_follows,
:hide_followers,
:background,
:show_role
])
end

@@ -194,7 +198,8 @@ defmodule Pleroma.User.Info do
info
|> cast(params, [
:is_moderator,
:is_admin
:is_admin,
:show_role
])
end



+ 1
- 1
lib/pleroma/web/activity_pub/activity_pub.ex View File

@@ -521,7 +521,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
defp restrict_actor(query, _), do: query

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

defp restrict_type(query, %{"type" => type}) do


+ 8
- 0
lib/pleroma/web/activity_pub/activity_pub_controller.ex View File

@@ -198,6 +198,14 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubController do
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
if nickname == user.nickname do
conn


+ 139
- 0
lib/pleroma/web/activity_pub/mrf/tag_policy.ex 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

+ 2
- 0
lib/pleroma/web/activity_pub/transmogrifier.ex View File

@@ -313,6 +313,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do
|> Map.put("tag", combined)
end

def fix_tag(%{"tag" => %{} = tag} = object), do: Map.put(object, "tag", [tag])

def fix_tag(object), do: object

# content map usually only has one language so this will do for now.


+ 6
- 4
lib/pleroma/web/activity_pub/views/user_view.ex View File

@@ -86,7 +86,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
query = from(user in query, select: [:ap_id])
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())
end

@@ -99,7 +99,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"id" => "#{user.ap_id}/following",
"type" => "OrderedCollection",
"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())
end
@@ -109,7 +109,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
query = from(user in query, select: [:ap_id])
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())
end

@@ -122,7 +122,7 @@ defmodule Pleroma.Web.ActivityPub.UserView do
"id" => "#{user.ap_id}/followers",
"type" => "OrderedCollection",
"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())
end
@@ -239,6 +239,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do

if offset < total do
Map.put(map, "next", "#{iri}?page=#{page + 1}")
else
map
end
end
end

+ 2
- 2
lib/pleroma/web/mastodon_api/mastodon_api_controller.ex View File

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

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



+ 10
- 4
lib/pleroma/web/mastodon_api/views/status_view.ex View File

@@ -182,18 +182,24 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
end

def render("card.json", %{rich_media: rich_media, page_url: page_url}) do
page_url_data = URI.parse(page_url)

page_url_data =
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
page_url
page_url_data
end

page_url = page_url_data |> to_string

image_url =
URI.merge(page_url_data, URI.parse(rich_media[:image]))
|> to_string
if rich_media[:image] != nil do
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



+ 4
- 14
lib/pleroma/web/rich_media/parser.ex View File

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


+ 1
- 0
lib/pleroma/web/router.ex View File

@@ -454,6 +454,7 @@ defmodule Pleroma.Web.Router do
scope "/", Pleroma.Web.ActivityPub do
pipe_through([:activitypub_client])

get("/api/ap/whoami", ActivityPubController, :whoami)
get("/users/:nickname/inbox", ActivityPubController, :read_inbox)
post("/users/:nickname/outbox", ActivityPubController, :update_outbox)
end


+ 4
- 4
lib/pleroma/web/twitter_api/twitter_api_controller.ex View File

@@ -24,7 +24,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do

conn
|> put_view(UserView)
|> render("show.json", %{user: user, token: token})
|> render("show.json", %{user: user, token: token, for: user})
end

def status_update(%{assigns: %{user: user}} = conn, %{"status" => _} = status_data) do
@@ -503,7 +503,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
followers =
cond do
for_user && user.id == for_user.id -> followers
user.info.hide_network -> []
user.info.hide_followers -> []
true -> followers
end

@@ -523,7 +523,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do
friends =
cond do
for_user && user.id == for_user.id -> friends
user.info.hide_network -> []
user.info.hide_follows -> []
true -> friends
end

@@ -618,7 +618,7 @@ defmodule Pleroma.Web.TwitterAPI.Controller do

defp build_info_cng(user, params) do
info_params =
["no_rich_text", "locked", "hide_network"]
["no_rich_text", "locked", "hide_followers", "hide_follows", "show_role"]
|> Enum.reduce(%{}, fn key, res ->
if value = params[key] do
Map.put(res, key, value == "true")


+ 22
- 1
lib/pleroma/web/twitter_api/views/user_view.ex View File

@@ -108,7 +108,8 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
"locked" => user.info.locked,
"default_scope" => user.info.default_scope,
"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,

# 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
Map.put(data, "token", token_string(assigns[:token]))
else
@@ -125,6 +132,20 @@ defmodule Pleroma.Web.TwitterAPI.UserView do
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(_), do: nil



+ 12
- 0
priv/repo/migrations/20190203185340_split_hide_network.exs 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

+ 30
- 0
priv/repo/migrations/20190204200237_add_correct_dm_index.exs 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

+ 1
- 1
priv/static/index.html 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>

+ 1
- 4
priv/static/static/config.json View File

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

+ 0
- 2
priv/static/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/static/css/app.42c43da15d7ab16ad8e42d21fcfc5a43.css.map
File diff suppressed because it is too large
View File


+ 2
- 0
priv/static/static/css/app.d75cda10f04aeefec7b657f8244070e9.css
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/static/css/app.d75cda10f04aeefec7b657f8244070e9.css.map
File diff suppressed because it is too large
View File


+ 16
- 0
priv/static/static/js/app.0e4952ec8d775da840f1.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/static/js/app.0e4952ec8d775da840f1.js.map
File diff suppressed because it is too large
View File


+ 0
- 15
priv/static/static/js/app.59ebcfb47f86a7a5ba3f.js
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/static/js/app.59ebcfb47f86a7a5ba3f.js.map
File diff suppressed because it is too large
View File


+ 0
- 2
priv/static/static/js/manifest.6aa5664a1a2c0832ce7b.js 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

+ 2
- 0
priv/static/static/js/manifest.f00ab54db04706aab2c9.js 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

priv/static/static/js/manifest.f00ab54db04706aab2c9.js.map
File diff suppressed because it is too large
View File


priv/static/static/js/vendor.5173dfeead1ded3d1f46.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/static/js/vendor.5173dfeead1ded3d1f46.js.map
File diff suppressed because it is too large
View File


+ 0
- 1
priv/static/static/js/vendor.56a115a1d7339d6811a0.js.map
File diff suppressed because it is too large
View File


+ 1
- 1
priv/static/sw-pleroma.js 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){/*!
localForage -- Offline Storage, Improved


+ 10
- 3
priv/static/sw.js
File diff suppressed because it is too large
View File


+ 1
- 0
priv/static/sw.js.map
File diff suppressed because it is too large
View File


+ 4
- 4
test/web/activity_pub/activity_pub_controller_test.exs View File

@@ -386,9 +386,9 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["first"]["orderedItems"] == [user.ap_id]
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_two = insert(:user, %{info: %{hide_network: true}})
user_two = insert(:user, %{info: %{hide_followers: true}})
User.follow(user, user_two)

result =
@@ -441,8 +441,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubControllerTest do
assert result["first"]["orderedItems"] == [user_two.ap_id]
end

test "it returns returns empty if the user has 'hide_network' set", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}})
test "it returns returns empty if the user has 'hide_follows' set", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
user_two = insert(:user)
User.follow(user, user_two)



+ 8
- 8
test/web/mastodon_api/mastodon_api_controller_test.exs View File

@@ -1101,9 +1101,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(user.id)
end

test "getting followers, hide_network", %{conn: conn} do
test "getting followers, hide_followers", %{conn: conn} do
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)

conn =
@@ -1113,9 +1113,9 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [] == json_response(conn, 200)
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)
other_user = insert(:user, %{info: %{hide_network: true}})
other_user = insert(:user, %{info: %{hide_followers: true}})
{:ok, _user} = User.follow(user, other_user)

conn =
@@ -1139,8 +1139,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert id == to_string(other_user.id)
end

test "getting following, hide_network", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}})
test "getting following, hide_follows", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)

@@ -1151,8 +1151,8 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIControllerTest do
assert [] == json_response(conn, 200)
end

test "getting following, hide_network, same user requesting", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}})
test "getting following, hide_follows, same user requesting", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
other_user = insert(:user)
{:ok, user} = User.follow(user, other_user)



+ 55
- 0
test/web/mastodon_api/status_view_test.exs View File

@@ -235,4 +235,59 @@ defmodule Pleroma.Web.MastodonAPI.StatusViewTest do
]
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

+ 78
- 22
test/web/twitter_api/twitter_api_controller_test.exs View File

@@ -62,7 +62,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> post("/api/account/verify_credentials.json")
|> 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

@@ -107,7 +108,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
|> post(request_path, %{status: "Nice meme.", visibility: "private"})

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

@@ -418,6 +419,7 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert Enum.at(response, 0) ==
ActivityRepresenter.to_map(activity, %{
user: current_user,
for: current_user,
mentioned: [current_user]
})
end
@@ -547,7 +549,9 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
response = json_response(conn, 200)

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

test "with credentials with user_id", %{conn: conn, user: current_user} do
@@ -1132,8 +1136,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
)
end

test "it returns empty for a hidden network", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}})
test "it returns empty when hide_followers is set to true", %{conn: conn} do
user = insert(:user, %{info: %{hide_followers: true}})
follower_one = insert(:user)
follower_two = insert(:user)
not_follower = insert(:user)
@@ -1150,10 +1154,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert [] == response
end

test "it returns the followers for a hidden network if requested by the user themselves", %{
conn: conn
} do
user = insert(:user, %{info: %{hide_network: true}})
test "it returns the followers when hide_followers is set to true if requested by the user themselves",
%{
conn: conn
} do
user = insert(:user, %{info: %{hide_followers: true}})
follower_one = insert(:user)
follower_two = insert(:user)
_not_follower = insert(:user)
@@ -1256,8 +1261,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
)
end

test "it returns empty for a hidden network", %{conn: conn} do
user = insert(:user, %{info: %{hide_network: true}})
test "it returns empty when hide_follows is set to true", %{conn: conn} do
user = insert(:user, %{info: %{hide_follows: true}})
followed_one = insert(:user)
followed_two = insert(:user)
not_followed = insert(:user)
@@ -1273,10 +1278,11 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do
assert [] == json_response(conn, 200)
end

test "it returns friends for a hidden network if the user themselves request it", %{
conn: conn
} do
user = insert(:user, %{info: %{hide_network: true}})
test "it returns friends when hide_follows is set to true if the user themselves request it",
%{
conn: conn
} do
user = insert(:user, %{info: %{hide_follows: true}})
followed_one = insert(:user)
followed_two = 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})
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)

conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"hide_network" => "true"
"hide_follows" => "true"
})

user = Repo.get!(User, user.id)
assert user.info.hide_network == true
assert user.info.hide_follows == true

conn =
conn
|> assign(:user, user)
|> post("/api/account/update_profile.json", %{
"hide_network" => "false"
"hide_follows" => "false"
})

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})
end

@@ -1788,7 +1842,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do

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

@@ -1817,7 +1872,8 @@ defmodule Pleroma.Web.TwitterAPI.ControllerTest do

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

+ 1
- 0
test/web/twitter_api/util_controller_test.exs View File

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

response =
conn


+ 24
- 4
test/web/twitter_api/views/user_view_test.exs View File

@@ -100,7 +100,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false,
"default_scope" => "public",
"no_rich_text" => false,
"hide_network" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
@@ -147,7 +148,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false,
"default_scope" => "public",
"no_rich_text" => false,
"hide_network" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
@@ -195,7 +197,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false,
"default_scope" => "public",
"no_rich_text" => false,
"hide_network" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,
@@ -211,6 +214,7 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
represented = UserView.render("show.json", %{user: user, for: user})

assert represented["rights"]["delete_others_notice"]
assert represented["role"] == "moderator"
end

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})

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

test "A blocked user for the blocker" do
@@ -257,7 +276,8 @@ defmodule Pleroma.Web.TwitterAPI.UserViewTest do
"locked" => false,
"default_scope" => "public",
"no_rich_text" => false,
"hide_network" => false,
"hide_follows" => false,
"hide_followers" => false,
"fields" => [],
"pleroma" => %{
"confirmation_pending" => false,


Loading…
Cancel
Save