Merge branch 'features/remove-user-source_data' into 'develop'
User: remove source_data Closes #820 See merge request pleroma/pleroma!2339
This commit is contained in:
commit
0ddee13c83
|
@ -38,22 +38,14 @@ def demojify(text) do
|
||||||
|
|
||||||
def demojify(text, nil), do: text
|
def demojify(text, nil), do: text
|
||||||
|
|
||||||
@doc "Outputs a list of the emoji-shortcodes in a text"
|
|
||||||
def get_emoji(text) when is_binary(text) do
|
|
||||||
Enum.filter(Emoji.get_all(), fn {emoji, %Emoji{}} ->
|
|
||||||
String.contains?(text, ":#{emoji}:")
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
def get_emoji(_), do: []
|
|
||||||
|
|
||||||
@doc "Outputs a list of the emoji-Maps in a text"
|
@doc "Outputs a list of the emoji-Maps in a text"
|
||||||
def get_emoji_map(text) when is_binary(text) do
|
def get_emoji_map(text) when is_binary(text) do
|
||||||
get_emoji(text)
|
Emoji.get_all()
|
||||||
|
|> Enum.filter(fn {emoji, %Emoji{}} -> String.contains?(text, ":#{emoji}:") end)
|
||||||
|> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
|
|> Enum.reduce(%{}, fn {name, %Emoji{file: file}}, acc ->
|
||||||
Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}")
|
Map.put(acc, name, "#{Pleroma.Web.Endpoint.static_url()}#{file}")
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_emoji_map(_), do: []
|
def get_emoji_map(_), do: %{}
|
||||||
end
|
end
|
||||||
|
|
|
@ -31,7 +31,7 @@ def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do
|
||||||
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
||||||
case User.get_cached_by_nickname(nickname) do
|
case User.get_cached_by_nickname(nickname) do
|
||||||
%User{id: id} = user ->
|
%User{id: id} = user ->
|
||||||
ap_id = get_ap_id(user)
|
user_url = user.uri || user.ap_id
|
||||||
nickname_text = get_nickname_text(nickname, opts)
|
nickname_text = get_nickname_text(nickname, opts)
|
||||||
|
|
||||||
link =
|
link =
|
||||||
|
@ -42,7 +42,7 @@ def mention_handler("@" <> nickname, buffer, opts, acc) do
|
||||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||||
"data-user": id,
|
"data-user": id,
|
||||||
class: "u-url mention",
|
class: "u-url mention",
|
||||||
href: ap_id,
|
href: user_url,
|
||||||
rel: "ugc"
|
rel: "ugc"
|
||||||
),
|
),
|
||||||
class: "h-card"
|
class: "h-card"
|
||||||
|
@ -146,9 +146,6 @@ def truncate(text, max_length \\ 200, omission \\ "...") do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
defp get_ap_id(%User{source_data: %{"url" => url}}) when is_binary(url), do: url
|
|
||||||
defp get_ap_id(%User{ap_id: ap_id}), do: ap_id
|
|
||||||
|
|
||||||
defp get_nickname_text(nickname, %{mentions_format: :full}), do: User.full_nickname(nickname)
|
defp get_nickname_text(nickname, %{mentions_format: :full}), do: User.full_nickname(nickname)
|
||||||
defp get_nickname_text(nickname, _), do: User.local_nickname(nickname)
|
defp get_nickname_text(nickname, _), do: User.local_nickname(nickname)
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,7 @@ defmodule Pleroma.User do
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Conversation.Participation
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Delivery
|
alias Pleroma.Delivery
|
||||||
|
alias Pleroma.Emoji
|
||||||
alias Pleroma.FollowingRelationship
|
alias Pleroma.FollowingRelationship
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.HTML
|
alias Pleroma.HTML
|
||||||
|
@ -28,6 +29,7 @@ defmodule Pleroma.User do
|
||||||
alias Pleroma.UserRelationship
|
alias Pleroma.UserRelationship
|
||||||
alias Pleroma.Web
|
alias Pleroma.Web
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
|
alias Pleroma.Web.ActivityPub.ObjectValidators.Types
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
|
alias Pleroma.Web.CommonAPI.Utils, as: CommonUtils
|
||||||
|
@ -82,6 +84,7 @@ defmodule Pleroma.User do
|
||||||
field(:password, :string, virtual: true)
|
field(:password, :string, virtual: true)
|
||||||
field(:password_confirmation, :string, virtual: true)
|
field(:password_confirmation, :string, virtual: true)
|
||||||
field(:keys, :string)
|
field(:keys, :string)
|
||||||
|
field(:public_key, :string)
|
||||||
field(:ap_id, :string)
|
field(:ap_id, :string)
|
||||||
field(:avatar, :map)
|
field(:avatar, :map)
|
||||||
field(:local, :boolean, default: true)
|
field(:local, :boolean, default: true)
|
||||||
|
@ -94,7 +97,6 @@ defmodule Pleroma.User do
|
||||||
field(:last_digest_emailed_at, :naive_datetime)
|
field(:last_digest_emailed_at, :naive_datetime)
|
||||||
field(:banner, :map, default: %{})
|
field(:banner, :map, default: %{})
|
||||||
field(:background, :map, default: %{})
|
field(:background, :map, default: %{})
|
||||||
field(:source_data, :map, default: %{})
|
|
||||||
field(:note_count, :integer, default: 0)
|
field(:note_count, :integer, default: 0)
|
||||||
field(:follower_count, :integer, default: 0)
|
field(:follower_count, :integer, default: 0)
|
||||||
field(:following_count, :integer, default: 0)
|
field(:following_count, :integer, default: 0)
|
||||||
|
@ -112,7 +114,7 @@ defmodule Pleroma.User do
|
||||||
field(:show_role, :boolean, default: true)
|
field(:show_role, :boolean, default: true)
|
||||||
field(:settings, :map, default: nil)
|
field(:settings, :map, default: nil)
|
||||||
field(:magic_key, :string, default: nil)
|
field(:magic_key, :string, default: nil)
|
||||||
field(:uri, :string, default: nil)
|
field(:uri, Types.Uri, default: nil)
|
||||||
field(:hide_followers_count, :boolean, default: false)
|
field(:hide_followers_count, :boolean, default: false)
|
||||||
field(:hide_follows_count, :boolean, default: false)
|
field(:hide_follows_count, :boolean, default: false)
|
||||||
field(:hide_followers, :boolean, default: false)
|
field(:hide_followers, :boolean, default: false)
|
||||||
|
@ -122,7 +124,7 @@ defmodule Pleroma.User do
|
||||||
field(:pinned_activities, {:array, :string}, default: [])
|
field(:pinned_activities, {:array, :string}, default: [])
|
||||||
field(:email_notifications, :map, default: %{"digest" => false})
|
field(:email_notifications, :map, default: %{"digest" => false})
|
||||||
field(:mascot, :map, default: nil)
|
field(:mascot, :map, default: nil)
|
||||||
field(:emoji, {:array, :map}, default: [])
|
field(:emoji, :map, default: %{})
|
||||||
field(:pleroma_settings_store, :map, default: %{})
|
field(:pleroma_settings_store, :map, default: %{})
|
||||||
field(:fields, {:array, :map}, default: [])
|
field(:fields, {:array, :map}, default: [])
|
||||||
field(:raw_fields, {:array, :map}, default: [])
|
field(:raw_fields, {:array, :map}, default: [])
|
||||||
|
@ -132,6 +134,8 @@ defmodule Pleroma.User do
|
||||||
field(:skip_thread_containment, :boolean, default: false)
|
field(:skip_thread_containment, :boolean, default: false)
|
||||||
field(:actor_type, :string, default: "Person")
|
field(:actor_type, :string, default: "Person")
|
||||||
field(:also_known_as, {:array, :string}, default: [])
|
field(:also_known_as, {:array, :string}, default: [])
|
||||||
|
field(:inbox, :string)
|
||||||
|
field(:shared_inbox, :string)
|
||||||
|
|
||||||
embeds_one(
|
embeds_one(
|
||||||
:notification_settings,
|
:notification_settings,
|
||||||
|
@ -306,6 +310,7 @@ def banner_url(user, options \\ []) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Should probably be renamed or removed
|
||||||
def ap_id(%User{nickname: nickname}), do: "#{Web.base_url()}/users/#{nickname}"
|
def ap_id(%User{nickname: nickname}), do: "#{Web.base_url()}/users/#{nickname}"
|
||||||
|
|
||||||
def ap_followers(%User{follower_address: fa}) when is_binary(fa), do: fa
|
def ap_followers(%User{follower_address: fa}) when is_binary(fa), do: fa
|
||||||
|
@ -339,6 +344,13 @@ defp truncate_if_exists(params, key, max_length) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp fix_follower_address(%{follower_address: _, following_address: _} = params), do: params
|
||||||
|
|
||||||
|
defp fix_follower_address(%{nickname: nickname} = params),
|
||||||
|
do: Map.put(params, :follower_address, ap_followers(%User{nickname: nickname}))
|
||||||
|
|
||||||
|
defp fix_follower_address(params), do: params
|
||||||
|
|
||||||
def remote_user_changeset(struct \\ %User{local: false}, params) do
|
def remote_user_changeset(struct \\ %User{local: false}, params) do
|
||||||
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
|
bio_limit = Pleroma.Config.get([:instance, :user_bio_length], 5000)
|
||||||
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
|
name_limit = Pleroma.Config.get([:instance, :user_name_length], 100)
|
||||||
|
@ -356,54 +368,48 @@ def remote_user_changeset(struct \\ %User{local: false}, params) do
|
||||||
|> truncate_if_exists(:name, name_limit)
|
|> truncate_if_exists(:name, name_limit)
|
||||||
|> truncate_if_exists(:bio, bio_limit)
|
|> truncate_if_exists(:bio, bio_limit)
|
||||||
|> truncate_fields_param()
|
|> truncate_fields_param()
|
||||||
|
|> fix_follower_address()
|
||||||
|
|
||||||
changeset =
|
struct
|
||||||
struct
|
|> cast(
|
||||||
|> cast(
|
params,
|
||||||
params,
|
[
|
||||||
[
|
:bio,
|
||||||
:bio,
|
:name,
|
||||||
:name,
|
:emoji,
|
||||||
:ap_id,
|
:ap_id,
|
||||||
:nickname,
|
:inbox,
|
||||||
:avatar,
|
:shared_inbox,
|
||||||
:ap_enabled,
|
:nickname,
|
||||||
:source_data,
|
:public_key,
|
||||||
:banner,
|
:avatar,
|
||||||
:locked,
|
:ap_enabled,
|
||||||
:magic_key,
|
:banner,
|
||||||
:uri,
|
:locked,
|
||||||
:hide_followers,
|
:last_refreshed_at,
|
||||||
:hide_follows,
|
:magic_key,
|
||||||
:hide_followers_count,
|
:uri,
|
||||||
:hide_follows_count,
|
:follower_address,
|
||||||
:follower_count,
|
:following_address,
|
||||||
:fields,
|
:hide_followers,
|
||||||
:following_count,
|
:hide_follows,
|
||||||
:discoverable,
|
:hide_followers_count,
|
||||||
:invisible,
|
:hide_follows_count,
|
||||||
:actor_type,
|
:follower_count,
|
||||||
:also_known_as,
|
:fields,
|
||||||
:last_refreshed_at
|
:following_count,
|
||||||
]
|
:discoverable,
|
||||||
)
|
:invisible,
|
||||||
|> validate_required([:name, :ap_id])
|
:actor_type,
|
||||||
|> unique_constraint(:nickname)
|
:also_known_as
|
||||||
|> validate_format(:nickname, @email_regex)
|
]
|
||||||
|> validate_length(:bio, max: bio_limit)
|
)
|
||||||
|> validate_length(:name, max: name_limit)
|
|> validate_required([:name, :ap_id])
|
||||||
|> validate_fields(true)
|
|> unique_constraint(:nickname)
|
||||||
|
|> validate_format(:nickname, @email_regex)
|
||||||
case params[:source_data] do
|
|> validate_length(:bio, max: bio_limit)
|
||||||
%{"followers" => followers, "following" => following} ->
|
|> validate_length(:name, max: name_limit)
|
||||||
changeset
|
|> validate_fields(true)
|
||||||
|> put_change(:follower_address, followers)
|
|
||||||
|> put_change(:following_address, following)
|
|
||||||
|
|
||||||
_ ->
|
|
||||||
followers = ap_followers(%User{nickname: get_field(changeset, :nickname)})
|
|
||||||
put_change(changeset, :follower_address, followers)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_changeset(struct, params \\ %{}) do
|
def update_changeset(struct, params \\ %{}) do
|
||||||
|
@ -416,7 +422,11 @@ def update_changeset(struct, params \\ %{}) do
|
||||||
[
|
[
|
||||||
:bio,
|
:bio,
|
||||||
:name,
|
:name,
|
||||||
|
:emoji,
|
||||||
:avatar,
|
:avatar,
|
||||||
|
:public_key,
|
||||||
|
:inbox,
|
||||||
|
:shared_inbox,
|
||||||
:locked,
|
:locked,
|
||||||
:no_rich_text,
|
:no_rich_text,
|
||||||
:default_scope,
|
:default_scope,
|
||||||
|
@ -443,6 +453,7 @@ def update_changeset(struct, params \\ %{}) do
|
||||||
|> validate_length(:bio, max: bio_limit)
|
|> validate_length(:bio, max: bio_limit)
|
||||||
|> validate_length(:name, min: 1, max: name_limit)
|
|> validate_length(:name, min: 1, max: name_limit)
|
||||||
|> put_fields()
|
|> put_fields()
|
||||||
|
|> put_emoji()
|
||||||
|> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)})
|
|> put_change_if_present(:bio, &{:ok, parse_bio(&1, struct)})
|
||||||
|> put_change_if_present(:avatar, &put_upload(&1, :avatar))
|
|> put_change_if_present(:avatar, &put_upload(&1, :avatar))
|
||||||
|> put_change_if_present(:banner, &put_upload(&1, :banner))
|
|> put_change_if_present(:banner, &put_upload(&1, :banner))
|
||||||
|
@ -478,6 +489,18 @@ defp parse_fields(value) do
|
||||||
|> elem(0)
|
|> elem(0)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp put_emoji(changeset) do
|
||||||
|
bio = get_change(changeset, :bio)
|
||||||
|
name = get_change(changeset, :name)
|
||||||
|
|
||||||
|
if bio || name do
|
||||||
|
emoji = Map.merge(Emoji.Formatter.get_emoji_map(bio), Emoji.Formatter.get_emoji_map(name))
|
||||||
|
put_change(changeset, :emoji, emoji)
|
||||||
|
else
|
||||||
|
changeset
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
defp put_change_if_present(changeset, map_field, value_function) do
|
defp put_change_if_present(changeset, map_field, value_function) do
|
||||||
if value = get_change(changeset, map_field) do
|
if value = get_change(changeset, map_field) do
|
||||||
with {:ok, new_value} <- value_function.(value) do
|
with {:ok, new_value} <- value_function.(value) do
|
||||||
|
@ -572,7 +595,7 @@ def register_changeset(struct, params \\ %{}, opts \\ []) do
|
||||||
|
|
||||||
struct
|
struct
|
||||||
|> confirmation_changeset(need_confirmation: need_confirmation?)
|
|> confirmation_changeset(need_confirmation: need_confirmation?)
|
||||||
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation])
|
|> cast(params, [:bio, :email, :name, :nickname, :password, :password_confirmation, :emoji])
|
||||||
|> validate_required([:name, :nickname, :password, :password_confirmation])
|
|> validate_required([:name, :nickname, :password, :password_confirmation])
|
||||||
|> validate_confirmation(:password)
|
|> validate_confirmation(:password)
|
||||||
|> unique_constraint(:email)
|
|> unique_constraint(:email)
|
||||||
|
@ -1587,8 +1610,7 @@ defp create_service_actor(uri, nickname) do
|
||||||
|> set_cache()
|
|> set_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
# AP style
|
def public_key(%{public_key: public_key_pem}) when is_binary(public_key_pem) do
|
||||||
def public_key(%{source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pem}}}) do
|
|
||||||
key =
|
key =
|
||||||
public_key_pem
|
public_key_pem
|
||||||
|> :public_key.pem_decode()
|
|> :public_key.pem_decode()
|
||||||
|
@ -1598,7 +1620,7 @@ def public_key(%{source_data: %{"publicKey" => %{"publicKeyPem" => public_key_pe
|
||||||
{:ok, key}
|
{:ok, key}
|
||||||
end
|
end
|
||||||
|
|
||||||
def public_key(_), do: {:error, "not found key"}
|
def public_key(_), do: {:error, "key not found"}
|
||||||
|
|
||||||
def get_public_key_for_ap_id(ap_id) do
|
def get_public_key_for_ap_id(ap_id) do
|
||||||
with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id),
|
with {:ok, %User{} = user} <- get_or_fetch_by_ap_id(ap_id),
|
||||||
|
@ -1917,12 +1939,6 @@ def update_background(user, background) do
|
||||||
|> update_and_set_cache()
|
|> update_and_set_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_source_data(user, source_data) do
|
|
||||||
user
|
|
||||||
|> cast(%{source_data: source_data}, [:source_data])
|
|
||||||
|> update_and_set_cache()
|
|
||||||
end
|
|
||||||
|
|
||||||
def roles(%{is_moderator: is_moderator, is_admin: is_admin}) do
|
def roles(%{is_moderator: is_moderator, is_admin: is_admin}) do
|
||||||
%{
|
%{
|
||||||
admin: is_admin,
|
admin: is_admin,
|
||||||
|
@ -1930,21 +1946,6 @@ def roles(%{is_moderator: is_moderator, is_admin: is_admin}) do
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
# ``fields`` is an array of mastodon profile field, containing ``{"name": "…", "value": "…"}``.
|
|
||||||
# For example: [{"name": "Pronoun", "value": "she/her"}, …]
|
|
||||||
def fields(%{fields: nil, source_data: %{"attachment" => attachment}}) do
|
|
||||||
limit = Pleroma.Config.get([:instance, :max_remote_account_fields], 0)
|
|
||||||
|
|
||||||
attachment
|
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
|
||||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
|
||||||
|> Enum.take(limit)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fields(%{fields: nil}), do: []
|
|
||||||
|
|
||||||
def fields(%{fields: fields}), do: fields
|
|
||||||
|
|
||||||
def validate_fields(changeset, remote? \\ false) do
|
def validate_fields(changeset, remote? \\ false) do
|
||||||
limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields
|
limit_name = if remote?, do: :max_remote_account_fields, else: :max_account_fields
|
||||||
limit = Pleroma.Config.get([:instance, limit_name], 0)
|
limit = Pleroma.Config.get([:instance, limit_name], 0)
|
||||||
|
@ -2132,9 +2133,7 @@ def sanitize_html(%User{} = user) do
|
||||||
# - display name
|
# - display name
|
||||||
def sanitize_html(%User{} = user, filter) do
|
def sanitize_html(%User{} = user, filter) do
|
||||||
fields =
|
fields =
|
||||||
user
|
Enum.map(user.fields, fn %{"name" => name, "value" => value} ->
|
||||||
|> User.fields()
|
|
||||||
|> Enum.map(fn %{"name" => name, "value" => value} ->
|
|
||||||
%{
|
%{
|
||||||
"name" => name,
|
"name" => name,
|
||||||
"value" => HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly)
|
"value" => HTML.filter_tags(value, Pleroma.HTML.Scrubber.LinksOnly)
|
||||||
|
|
|
@ -1427,19 +1427,41 @@ defp object_to_user_data(data) do
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
||||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
||||||
|
|
||||||
|
emojis =
|
||||||
|
data
|
||||||
|
|> Map.get("tag", [])
|
||||||
|
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
||||||
|
|> Enum.reduce(%{}, fn %{"icon" => %{"url" => url}, "name" => name}, acc ->
|
||||||
|
Map.put(acc, String.trim(name, ":"), url)
|
||||||
|
end)
|
||||||
|
|
||||||
locked = data["manuallyApprovesFollowers"] || false
|
locked = data["manuallyApprovesFollowers"] || false
|
||||||
data = Transmogrifier.maybe_fix_user_object(data)
|
data = Transmogrifier.maybe_fix_user_object(data)
|
||||||
discoverable = data["discoverable"] || false
|
discoverable = data["discoverable"] || false
|
||||||
invisible = data["invisible"] || false
|
invisible = data["invisible"] || false
|
||||||
actor_type = data["type"] || "Person"
|
actor_type = data["type"] || "Person"
|
||||||
|
|
||||||
|
public_key =
|
||||||
|
if is_map(data["publicKey"]) && is_binary(data["publicKey"]["publicKeyPem"]) do
|
||||||
|
data["publicKey"]["publicKeyPem"]
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_inbox =
|
||||||
|
if is_map(data["endpoints"]) && is_binary(data["endpoints"]["sharedInbox"]) do
|
||||||
|
data["endpoints"]["sharedInbox"]
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
|
||||||
user_data = %{
|
user_data = %{
|
||||||
ap_id: data["id"],
|
ap_id: data["id"],
|
||||||
uri: get_actor_url(data["url"]),
|
uri: get_actor_url(data["url"]),
|
||||||
ap_enabled: true,
|
ap_enabled: true,
|
||||||
source_data: data,
|
|
||||||
banner: banner,
|
banner: banner,
|
||||||
fields: fields,
|
fields: fields,
|
||||||
|
emoji: emojis,
|
||||||
locked: locked,
|
locked: locked,
|
||||||
discoverable: discoverable,
|
discoverable: discoverable,
|
||||||
invisible: invisible,
|
invisible: invisible,
|
||||||
|
@ -1449,7 +1471,10 @@ defp object_to_user_data(data) do
|
||||||
following_address: data["following"],
|
following_address: data["following"],
|
||||||
bio: data["summary"],
|
bio: data["summary"],
|
||||||
actor_type: actor_type,
|
actor_type: actor_type,
|
||||||
also_known_as: Map.get(data, "alsoKnownAs", [])
|
also_known_as: Map.get(data, "alsoKnownAs", []),
|
||||||
|
public_key: public_key,
|
||||||
|
inbox: data["inbox"],
|
||||||
|
shared_inbox: shared_inbox
|
||||||
}
|
}
|
||||||
|
|
||||||
# nickname can be nil because of virtual actors
|
# nickname can be nil because of virtual actors
|
||||||
|
|
|
@ -35,6 +35,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.NoteValidator do
|
||||||
field(:like_count, :integer, default: 0)
|
field(:like_count, :integer, default: 0)
|
||||||
field(:announcement_count, :integer, default: 0)
|
field(:announcement_count, :integer, default: 0)
|
||||||
field(:inRepyTo, :string)
|
field(:inRepyTo, :string)
|
||||||
|
field(:uri, Types.Uri)
|
||||||
|
|
||||||
field(:likes, {:array, :string}, default: [])
|
field(:likes, {:array, :string}, default: [])
|
||||||
field(:announcements, {:array, :string}, default: [])
|
field(:announcements, {:array, :string}, default: [])
|
||||||
|
|
|
@ -15,15 +15,9 @@ def cast(object) when is_binary(object) do
|
||||||
|
|
||||||
def cast(%{"id" => object}), do: cast(object)
|
def cast(%{"id" => object}), do: cast(object)
|
||||||
|
|
||||||
def cast(_) do
|
def cast(_), do: :error
|
||||||
:error
|
|
||||||
end
|
|
||||||
|
|
||||||
def dump(data) do
|
def dump(data), do: {:ok, data}
|
||||||
{:ok, data}
|
|
||||||
end
|
|
||||||
|
|
||||||
def load(data) do
|
def load(data), do: {:ok, data}
|
||||||
{:ok, data}
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
20
lib/pleroma/web/activity_pub/object_validators/types/uri.ex
Normal file
20
lib/pleroma/web/activity_pub/object_validators/types/uri.ex
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
defmodule Pleroma.Web.ActivityPub.ObjectValidators.Types.Uri do
|
||||||
|
use Ecto.Type
|
||||||
|
|
||||||
|
def type, do: :string
|
||||||
|
|
||||||
|
def cast(uri) when is_binary(uri) do
|
||||||
|
case URI.parse(uri) do
|
||||||
|
%URI{host: nil} -> :error
|
||||||
|
%URI{host: ""} -> :error
|
||||||
|
%URI{scheme: scheme} when scheme in ["https", "http"] -> {:ok, uri}
|
||||||
|
_ -> :error
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cast(_), do: :error
|
||||||
|
|
||||||
|
def dump(data), do: {:ok, data}
|
||||||
|
|
||||||
|
def load(data), do: {:ok, data}
|
||||||
|
end
|
|
@ -141,8 +141,8 @@ defp get_cc_ap_ids(ap_id, recipients) do
|
||||||
|> Enum.map(& &1.ap_id)
|
|> Enum.map(& &1.ap_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_use_sharedinbox(%User{source_data: data}),
|
defp maybe_use_sharedinbox(%User{shared_inbox: nil, inbox: inbox}), do: inbox
|
||||||
do: (is_map(data["endpoints"]) && Map.get(data["endpoints"], "sharedInbox")) || data["inbox"]
|
defp maybe_use_sharedinbox(%User{shared_inbox: shared_inbox}), do: shared_inbox
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Determine a user inbox to use based on heuristics. These heuristics
|
Determine a user inbox to use based on heuristics. These heuristics
|
||||||
|
@ -157,7 +157,7 @@ defp maybe_use_sharedinbox(%User{source_data: data}),
|
||||||
"""
|
"""
|
||||||
def determine_inbox(
|
def determine_inbox(
|
||||||
%Activity{data: activity_data},
|
%Activity{data: activity_data},
|
||||||
%User{source_data: data} = user
|
%User{inbox: inbox} = user
|
||||||
) do
|
) do
|
||||||
to = activity_data["to"] || []
|
to = activity_data["to"] || []
|
||||||
cc = activity_data["cc"] || []
|
cc = activity_data["cc"] || []
|
||||||
|
@ -174,7 +174,7 @@ def determine_inbox(
|
||||||
maybe_use_sharedinbox(user)
|
maybe_use_sharedinbox(user)
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
data["inbox"]
|
inbox
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -192,14 +192,13 @@ def publish(%User{} = actor, %{data: %{"bcc" => bcc}} = activity)
|
||||||
inboxes =
|
inboxes =
|
||||||
recipients
|
recipients
|
||||||
|> Enum.filter(&User.ap_enabled?/1)
|
|> Enum.filter(&User.ap_enabled?/1)
|
||||||
|> Enum.map(fn %{source_data: data} -> data["inbox"] end)
|
|> Enum.map(fn actor -> actor.inbox end)
|
||||||
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
|> Enum.filter(fn inbox -> should_federate?(inbox, public) end)
|
||||||
|> Instances.filter_reachable()
|
|> Instances.filter_reachable()
|
||||||
|
|
||||||
Repo.checkout(fn ->
|
Repo.checkout(fn ->
|
||||||
Enum.each(inboxes, fn {inbox, unreachable_since} ->
|
Enum.each(inboxes, fn {inbox, unreachable_since} ->
|
||||||
%User{ap_id: ap_id} =
|
%User{ap_id: ap_id} = Enum.find(recipients, fn actor -> actor.inbox == inbox end)
|
||||||
Enum.find(recipients, fn %{source_data: data} -> data["inbox"] == inbox end)
|
|
||||||
|
|
||||||
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
# Get all the recipients on the same host and add them to cc. Otherwise, a remote
|
||||||
# instance would only accept a first message for the first recipient and ignore the rest.
|
# instance would only accept a first message for the first recipient and ignore the rest.
|
||||||
|
|
|
@ -1160,7 +1160,7 @@ defp build_mention_tag(%{ap_id: ap_id, nickname: nickname} = _) do
|
||||||
|
|
||||||
def take_emoji_tags(%User{emoji: emoji}) do
|
def take_emoji_tags(%User{emoji: emoji}) do
|
||||||
emoji
|
emoji
|
||||||
|> Enum.flat_map(&Map.to_list/1)
|
|> Map.to_list()
|
||||||
|> Enum.map(&build_emoji_tag/1)
|
|> Enum.map(&build_emoji_tag/1)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -79,10 +79,7 @@ def render("user.json", %{user: user}) do
|
||||||
|
|
||||||
emoji_tags = Transmogrifier.take_emoji_tags(user)
|
emoji_tags = Transmogrifier.take_emoji_tags(user)
|
||||||
|
|
||||||
fields =
|
fields = Enum.map(user.fields, &Map.put(&1, "type", "PropertyValue"))
|
||||||
user
|
|
||||||
|> User.fields()
|
|
||||||
|> Enum.map(&Map.put(&1, "type", "PropertyValue"))
|
|
||||||
|
|
||||||
%{
|
%{
|
||||||
"id" => user.ap_id,
|
"id" => user.ap_id,
|
||||||
|
@ -103,7 +100,7 @@ def render("user.json", %{user: user}) do
|
||||||
},
|
},
|
||||||
"endpoints" => endpoints,
|
"endpoints" => endpoints,
|
||||||
"attachment" => fields,
|
"attachment" => fields,
|
||||||
"tag" => (user.source_data["tag"] || []) ++ emoji_tags,
|
"tag" => emoji_tags,
|
||||||
"discoverable" => user.discoverable
|
"discoverable" => user.discoverable
|
||||||
}
|
}
|
||||||
|> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
|
|> Map.merge(maybe_make_image(&User.avatar_url/2, "icon", user))
|
||||||
|
|
|
@ -332,26 +332,6 @@ defp maybe_create_activity_expiration({:ok, activity}, %NaiveDateTime{} = expire
|
||||||
|
|
||||||
defp maybe_create_activity_expiration(result, _), do: result
|
defp maybe_create_activity_expiration(result, _), do: result
|
||||||
|
|
||||||
# Updates the emojis for a user based on their profile
|
|
||||||
def update(user) do
|
|
||||||
emoji = emoji_from_profile(user)
|
|
||||||
source_data = Map.put(user.source_data, "tag", emoji)
|
|
||||||
|
|
||||||
user =
|
|
||||||
case User.update_source_data(user, source_data) do
|
|
||||||
{:ok, user} -> user
|
|
||||||
_ -> user
|
|
||||||
end
|
|
||||||
|
|
||||||
ActivityPub.update(%{
|
|
||||||
local: true,
|
|
||||||
to: [Pleroma.Constants.as_public(), user.follower_address],
|
|
||||||
cc: [],
|
|
||||||
actor: user.ap_id,
|
|
||||||
object: Pleroma.Web.ActivityPub.UserView.render("user.json", %{user: user})
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
def pin(id_or_ap_id, %{ap_id: user_ap_id} = user) do
|
def pin(id_or_ap_id, %{ap_id: user_ap_id} = user) do
|
||||||
with %Activity{
|
with %Activity{
|
||||||
actor: ^user_ap_id,
|
actor: ^user_ap_id,
|
||||||
|
|
|
@ -10,7 +10,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
||||||
alias Pleroma.Activity
|
alias Pleroma.Activity
|
||||||
alias Pleroma.Config
|
alias Pleroma.Config
|
||||||
alias Pleroma.Conversation.Participation
|
alias Pleroma.Conversation.Participation
|
||||||
alias Pleroma.Emoji
|
|
||||||
alias Pleroma.Formatter
|
alias Pleroma.Formatter
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Plugs.AuthenticationPlug
|
alias Pleroma.Plugs.AuthenticationPlug
|
||||||
|
@ -18,7 +17,6 @@ defmodule Pleroma.Web.CommonAPI.Utils do
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.Utils
|
alias Pleroma.Web.ActivityPub.Utils
|
||||||
alias Pleroma.Web.ActivityPub.Visibility
|
alias Pleroma.Web.ActivityPub.Visibility
|
||||||
alias Pleroma.Web.Endpoint
|
|
||||||
alias Pleroma.Web.MediaProxy
|
alias Pleroma.Web.MediaProxy
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
@ -175,7 +173,7 @@ def make_poll_data(%{"poll" => %{"options" => options, "expires_in" => expires_i
|
||||||
"replies" => %{"type" => "Collection", "totalItems" => 0}
|
"replies" => %{"type" => "Collection", "totalItems" => 0}
|
||||||
}
|
}
|
||||||
|
|
||||||
{note, Map.merge(emoji, Emoji.Formatter.get_emoji_map(option))}
|
{note, Map.merge(emoji, Pleroma.Emoji.Formatter.get_emoji_map(option))}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
end_time =
|
end_time =
|
||||||
|
@ -431,19 +429,6 @@ def confirm_current_password(user, password) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def emoji_from_profile(%User{bio: bio, name: name}) do
|
|
||||||
[bio, name]
|
|
||||||
|> Enum.map(&Emoji.Formatter.get_emoji/1)
|
|
||||||
|> Enum.concat()
|
|
||||||
|> Enum.map(fn {shortcode, %Emoji{file: path}} ->
|
|
||||||
%{
|
|
||||||
"type" => "Emoji",
|
|
||||||
"icon" => %{"type" => "Image", "url" => "#{Endpoint.url()}#{path}"},
|
|
||||||
"name" => ":#{shortcode}:"
|
|
||||||
}
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
def maybe_notify_to_recipients(
|
def maybe_notify_to_recipients(
|
||||||
recipients,
|
recipients,
|
||||||
%Activity{data: %{"to" => to, "type" => _type}} = _activity
|
%Activity{data: %{"to" => to, "type" => _type}} = _activity
|
||||||
|
|
|
@ -146,9 +146,7 @@ def verify_credentials(%{assigns: %{user: user}} = conn, _) do
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "PATCH /api/v1/accounts/update_credentials"
|
@doc "PATCH /api/v1/accounts/update_credentials"
|
||||||
def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
user = original_user
|
|
||||||
|
|
||||||
user_params =
|
user_params =
|
||||||
[
|
[
|
||||||
:no_rich_text,
|
:no_rich_text,
|
||||||
|
@ -184,8 +182,6 @@ def update_credentials(%{assigns: %{user: original_user}} = conn, params) do
|
||||||
changeset = User.update_changeset(user, user_params)
|
changeset = User.update_changeset(user, user_params)
|
||||||
|
|
||||||
with {:ok, user} <- User.update_and_set_cache(changeset) do
|
with {:ok, user} <- User.update_and_set_cache(changeset) do
|
||||||
if original_user != user, do: CommonAPI.update(user)
|
|
||||||
|
|
||||||
render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
|
render(conn, "show.json", user: user, for: user, with_pleroma_settings: true)
|
||||||
else
|
else
|
||||||
_e -> render_error(conn, :forbidden, "Invalid request")
|
_e -> render_error(conn, :forbidden, "Invalid request")
|
||||||
|
|
|
@ -181,13 +181,11 @@ defp do_render("show.json", %{user: user} = opts) do
|
||||||
bot = user.actor_type in ["Application", "Service"]
|
bot = user.actor_type in ["Application", "Service"]
|
||||||
|
|
||||||
emojis =
|
emojis =
|
||||||
(user.source_data["tag"] || [])
|
Enum.map(user.emoji, fn {shortcode, url} ->
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
|
||||||
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
|
||||||
%{
|
%{
|
||||||
"shortcode" => String.trim(name, ":"),
|
"shortcode" => shortcode,
|
||||||
"url" => MediaProxy.url(url),
|
"url" => url,
|
||||||
"static_url" => MediaProxy.url(url),
|
"static_url" => url,
|
||||||
"visible_in_picker" => false
|
"visible_in_picker" => false
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -13,7 +13,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do
|
||||||
alias Pleroma.Plugs.RateLimiter
|
alias Pleroma.Plugs.RateLimiter
|
||||||
alias Pleroma.User
|
alias Pleroma.User
|
||||||
alias Pleroma.Web.ActivityPub.ActivityPub
|
alias Pleroma.Web.ActivityPub.ActivityPub
|
||||||
alias Pleroma.Web.CommonAPI
|
|
||||||
alias Pleroma.Web.MastodonAPI.StatusView
|
alias Pleroma.Web.MastodonAPI.StatusView
|
||||||
|
|
||||||
require Pleroma.Constants
|
require Pleroma.Constants
|
||||||
|
@ -58,38 +57,32 @@ def confirmation_resend(conn, params) do
|
||||||
|
|
||||||
@doc "PATCH /api/v1/pleroma/accounts/update_avatar"
|
@doc "PATCH /api/v1/pleroma/accounts/update_avatar"
|
||||||
def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
|
def update_avatar(%{assigns: %{user: user}} = conn, %{"img" => ""}) do
|
||||||
{:ok, user} =
|
{:ok, _user} =
|
||||||
user
|
user
|
||||||
|> Changeset.change(%{avatar: nil})
|
|> Changeset.change(%{avatar: nil})
|
||||||
|> User.update_and_set_cache()
|
|> User.update_and_set_cache()
|
||||||
|
|
||||||
CommonAPI.update(user)
|
|
||||||
|
|
||||||
json(conn, %{url: nil})
|
json(conn, %{url: nil})
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
def update_avatar(%{assigns: %{user: user}} = conn, params) do
|
||||||
{:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
|
{:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar)
|
||||||
{:ok, user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
|
{:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache()
|
||||||
%{"url" => [%{"href" => href} | _]} = data
|
%{"url" => [%{"href" => href} | _]} = data
|
||||||
|
|
||||||
CommonAPI.update(user)
|
|
||||||
|
|
||||||
json(conn, %{url: href})
|
json(conn, %{url: href})
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc "PATCH /api/v1/pleroma/accounts/update_banner"
|
@doc "PATCH /api/v1/pleroma/accounts/update_banner"
|
||||||
def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
|
def update_banner(%{assigns: %{user: user}} = conn, %{"banner" => ""}) do
|
||||||
with {:ok, user} <- User.update_banner(user, %{}) do
|
with {:ok, _user} <- User.update_banner(user, %{}) do
|
||||||
CommonAPI.update(user)
|
|
||||||
json(conn, %{url: nil})
|
json(conn, %{url: nil})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
def update_banner(%{assigns: %{user: user}} = conn, params) do
|
||||||
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
|
with {:ok, object} <- ActivityPub.upload(%{"img" => params["banner"]}, type: :banner),
|
||||||
{:ok, user} <- User.update_banner(user, object.data) do
|
{:ok, _user} <- User.update_banner(user, object.data) do
|
||||||
CommonAPI.update(user)
|
|
||||||
%{"url" => [%{"href" => href} | _]} = object.data
|
%{"url" => [%{"href" => href} | _]} = object.data
|
||||||
|
|
||||||
json(conn, %{url: href})
|
json(conn, %{url: href})
|
||||||
|
|
|
@ -18,15 +18,6 @@ defmodule Pleroma.Web.StaticFE.StaticFEView do
|
||||||
|
|
||||||
@media_types ["image", "audio", "video"]
|
@media_types ["image", "audio", "video"]
|
||||||
|
|
||||||
def emoji_for_user(%User{} = user) do
|
|
||||||
user.source_data
|
|
||||||
|> Map.get("tag", [])
|
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
|
||||||
|> Enum.map(fn %{"icon" => %{"url" => url}, "name" => name} ->
|
|
||||||
{String.trim(name, ":"), url}
|
|
||||||
end)
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_media_type(%{"mediaType" => mediaType}) do
|
def fetch_media_type(%{"mediaType" => mediaType}) do
|
||||||
Utils.fetch_media_type(@media_types, mediaType)
|
Utils.fetch_media_type(@media_types, mediaType)
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
<img src="<%= User.avatar_url(@user) |> MediaProxy.url %>" width="48" height="48" alt="">
|
<img src="<%= User.avatar_url(@user) |> MediaProxy.url %>" width="48" height="48" alt="">
|
||||||
</div>
|
</div>
|
||||||
<span class="display-name">
|
<span class="display-name">
|
||||||
<bdi><%= raw (@user.name |> Formatter.emojify(emoji_for_user(@user))) %></bdi>
|
<bdi><%= raw Formatter.emojify(@user.name, @user.emoji) %></bdi>
|
||||||
<span class="nickname"><%= @user.nickname %></span>
|
<span class="nickname"><%= @user.nickname %></span>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<input type="hidden" name="profile" value="">
|
<input type="hidden" name="profile" value="">
|
||||||
<button type="submit" class="collapse">Remote follow</button>
|
<button type="submit" class="collapse">Remote follow</button>
|
||||||
</form>
|
</form>
|
||||||
<%= raw Formatter.emojify(@user.name, emoji_for_user(@user)) %> |
|
<%= raw Formatter.emojify(@user.name, @user.emoji) %> |
|
||||||
<%= link "@#{@user.nickname}@#{Endpoint.host()}", to: (@user.uri || @user.ap_id) %>
|
<%= link "@#{@user.nickname}@#{Endpoint.host()}", to: (@user.uri || @user.ap_id) %>
|
||||||
</h3>
|
</h3>
|
||||||
<p><%= raw @user.bio %></p>
|
<p><%= raw @user.bio %></p>
|
||||||
|
|
17
priv/repo/migrations/20200401030751_users_add_public_key.exs
Normal file
17
priv/repo/migrations/20200401030751_users_add_public_key.exs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.UsersAddPublicKey do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:users) do
|
||||||
|
add_if_not_exists(:public_key, :text)
|
||||||
|
end
|
||||||
|
|
||||||
|
execute("UPDATE users SET public_key = source_data->'publicKey'->>'publicKeyPem'")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:users) do
|
||||||
|
remove_if_exists(:public_key, :text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
20
priv/repo/migrations/20200401072456_users_add_inboxes.exs
Normal file
20
priv/repo/migrations/20200401072456_users_add_inboxes.exs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.UsersAddInboxes do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:users) do
|
||||||
|
add_if_not_exists(:inbox, :text)
|
||||||
|
add_if_not_exists(:shared_inbox, :text)
|
||||||
|
end
|
||||||
|
|
||||||
|
execute("UPDATE users SET inbox = source_data->>'inbox'")
|
||||||
|
execute("UPDATE users SET shared_inbox = source_data->'endpoints'->>'sharedInbox'")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:users) do
|
||||||
|
remove_if_exists(:inbox, :text)
|
||||||
|
remove_if_exists(:shared_inbox, :text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
35
priv/repo/migrations/20200406100225_users_add_emoji.exs
Normal file
35
priv/repo/migrations/20200406100225_users_add_emoji.exs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.UsersPopulateEmoji do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
import Ecto.Query
|
||||||
|
|
||||||
|
alias Pleroma.User
|
||||||
|
alias Pleroma.Repo
|
||||||
|
|
||||||
|
def up do
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN emoji SET DEFAULT '{}'::jsonb")
|
||||||
|
execute("UPDATE users SET emoji = DEFAULT WHERE emoji = '[]'::jsonb")
|
||||||
|
|
||||||
|
from(u in User)
|
||||||
|
|> select([u], struct(u, [:id, :ap_id, :source_data]))
|
||||||
|
|> Repo.stream()
|
||||||
|
|> Enum.each(fn user ->
|
||||||
|
emoji =
|
||||||
|
user.source_data
|
||||||
|
|> Map.get("tag", [])
|
||||||
|
|> Enum.filter(fn %{"type" => t} -> t == "Emoji" end)
|
||||||
|
|> Enum.reduce(%{}, fn %{"icon" => %{"url" => url}, "name" => name}, acc ->
|
||||||
|
Map.put(acc, String.trim(name, ":"), url)
|
||||||
|
end)
|
||||||
|
|
||||||
|
user
|
||||||
|
|> Ecto.Changeset.cast(%{emoji: emoji}, [:emoji])
|
||||||
|
|> Repo.update()
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN emoji SET DEFAULT '[]'::jsonb")
|
||||||
|
execute("UPDATE users SET emoji = DEFAULT WHERE emoji = '{}'::jsonb")
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,15 @@
|
||||||
|
defmodule Pleroma.Repo.Migrations.UsersRemoveSourceData do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
alter table(:users) do
|
||||||
|
remove_if_exists(:source_data, :map)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
alter table(:users) do
|
||||||
|
add_if_not_exists(:source_data, :map, default: %{})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -3,7 +3,6 @@
|
||||||
# SPDX-License-Identifier: AGPL-3.0-only
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
defmodule Pleroma.Emoji.FormatterTest do
|
defmodule Pleroma.Emoji.FormatterTest do
|
||||||
alias Pleroma.Emoji
|
|
||||||
alias Pleroma.Emoji.Formatter
|
alias Pleroma.Emoji.Formatter
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
|
|
||||||
|
@ -32,30 +31,19 @@ test "it does not add XSS emoji" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "get_emoji" do
|
describe "get_emoji_map" do
|
||||||
test "it returns the emoji used in the text" do
|
test "it returns the emoji used in the text" do
|
||||||
text = "I love :firefox:"
|
assert Formatter.get_emoji_map("I love :firefox:") == %{
|
||||||
|
"firefox" => "http://localhost:4001/emoji/Firefox.gif"
|
||||||
assert Formatter.get_emoji(text) == [
|
}
|
||||||
{"firefox",
|
|
||||||
%Emoji{
|
|
||||||
code: "firefox",
|
|
||||||
file: "/emoji/Firefox.gif",
|
|
||||||
tags: ["Gif", "Fun"],
|
|
||||||
safe_code: "firefox",
|
|
||||||
safe_file: "/emoji/Firefox.gif"
|
|
||||||
}}
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns a nice empty result when no emojis are present" do
|
test "it returns a nice empty result when no emojis are present" do
|
||||||
text = "I love moominamma"
|
assert Formatter.get_emoji_map("I love moominamma") == %{}
|
||||||
assert Formatter.get_emoji(text) == []
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it doesn't die when text is absent" do
|
test "it doesn't die when text is absent" do
|
||||||
text = nil
|
assert Formatter.get_emoji_map(nil) == %{}
|
||||||
assert Formatter.get_emoji(text) == []
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -140,7 +140,7 @@ test "gives a replacement for user links, using local nicknames in user links te
|
||||||
archaeme =
|
archaeme =
|
||||||
insert(:user,
|
insert(:user,
|
||||||
nickname: "archa_eme_",
|
nickname: "archa_eme_",
|
||||||
source_data: %{"url" => "https://archeme/@archa_eme_"}
|
uri: "https://archeme/@archa_eme_"
|
||||||
)
|
)
|
||||||
|
|
||||||
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
|
archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"})
|
||||||
|
|
|
@ -19,12 +19,7 @@ defmodule Pleroma.SignatureTest do
|
||||||
|
|
||||||
@private_key "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA48qb4v6kqigZutO9Ot0wkp27GIF2LiVaADgxQORZozZR63jH\nTaoOrS3Xhngbgc8SSOhfXET3omzeCLqaLNfXnZ8OXmuhJfJSU6mPUvmZ9QdT332j\nfN/g3iWGhYMf/M9ftCKh96nvFVO/tMruzS9xx7tkrfJjehdxh/3LlJMMImPtwcD7\nkFXwyt1qZTAU6Si4oQAJxRDQXHp1ttLl3Ob829VM7IKkrVmY8TD+JSlV0jtVJPj6\n1J19ytKTx/7UaucYvb9HIiBpkuiy5n/irDqKLVf5QEdZoNCdojOZlKJmTLqHhzKP\n3E9TxsUjhrf4/EqegNc/j982RvOxeu4i40zMQwIDAQABAoIBAQDH5DXjfh21i7b4\ncXJuw0cqget617CDUhemdakTDs9yH+rHPZd3mbGDWuT0hVVuFe4vuGpmJ8c+61X0\nRvugOlBlavxK8xvYlsqTzAmPgKUPljyNtEzQ+gz0I+3mH2jkin2rL3D+SksZZgKm\nfiYMPIQWB2WUF04gB46DDb2mRVuymGHyBOQjIx3WC0KW2mzfoFUFRlZEF+Nt8Ilw\nT+g/u0aZ1IWoszbsVFOEdghgZET0HEarum0B2Je/ozcPYtwmU10iBANGMKdLqaP/\nj954BPunrUf6gmlnLZKIKklJj0advx0NA+cL79+zeVB3zexRYSA5o9q0WPhiuTwR\n/aedWHnBAoGBAP0sDWBAM1Y4TRAf8ZI9PcztwLyHPzfEIqzbObJJnx1icUMt7BWi\n+/RMOnhrlPGE1kMhOqSxvXYN3u+eSmWTqai2sSH5Hdw2EqnrISSTnwNUPINX7fHH\njEkgmXQ6ixE48SuBZnb4w1EjdB/BA6/sjL+FNhggOc87tizLTkMXmMtTAoGBAOZV\n+wPuAMBDBXmbmxCuDIjoVmgSlgeRunB1SA8RCPAFAiUo3+/zEgzW2Oz8kgI+xVwM\n33XkLKrWG1Orhpp6Hm57MjIc5MG+zF4/YRDpE/KNG9qU1tiz0UD5hOpIU9pP4bR/\ngxgPxZzvbk4h5BfHWLpjlk8UUpgk6uxqfti48c1RAoGBALBOKDZ6HwYRCSGMjUcg\n3NPEUi84JD8qmFc2B7Tv7h2he2ykIz9iFAGpwCIyETQsJKX1Ewi0OlNnD3RhEEAy\nl7jFGQ+mkzPSeCbadmcpYlgIJmf1KN/x7fDTAepeBpCEzfZVE80QKbxsaybd3Dp8\nCfwpwWUFtBxr4c7J+gNhAGe/AoGAPn8ZyqkrPv9wXtyfqFjxQbx4pWhVmNwrkBPi\nZ2Qh3q4dNOPwTvTO8vjghvzIyR8rAZzkjOJKVFgftgYWUZfM5gE7T2mTkBYq8W+U\n8LetF+S9qAM2gDnaDx0kuUTCq7t87DKk6URuQ/SbI0wCzYjjRD99KxvChVGPBHKo\n1DjqMuECgYEAgJGNm7/lJCS2wk81whfy/ttKGsEIkyhPFYQmdGzSYC5aDc2gp1R3\nxtOkYEvdjfaLfDGEa4UX8CHHF+w3t9u8hBtcdhMH6GYb9iv6z0VBTt4A/11HUR49\n3Z7TQ18Iyh3jAUCzFV9IJlLIExq5Y7P4B3ojWFBN607sDCt8BMPbDYs=\n-----END RSA PRIVATE KEY-----"
|
@private_key "-----BEGIN RSA PRIVATE KEY-----\nMIIEpQIBAAKCAQEA48qb4v6kqigZutO9Ot0wkp27GIF2LiVaADgxQORZozZR63jH\nTaoOrS3Xhngbgc8SSOhfXET3omzeCLqaLNfXnZ8OXmuhJfJSU6mPUvmZ9QdT332j\nfN/g3iWGhYMf/M9ftCKh96nvFVO/tMruzS9xx7tkrfJjehdxh/3LlJMMImPtwcD7\nkFXwyt1qZTAU6Si4oQAJxRDQXHp1ttLl3Ob829VM7IKkrVmY8TD+JSlV0jtVJPj6\n1J19ytKTx/7UaucYvb9HIiBpkuiy5n/irDqKLVf5QEdZoNCdojOZlKJmTLqHhzKP\n3E9TxsUjhrf4/EqegNc/j982RvOxeu4i40zMQwIDAQABAoIBAQDH5DXjfh21i7b4\ncXJuw0cqget617CDUhemdakTDs9yH+rHPZd3mbGDWuT0hVVuFe4vuGpmJ8c+61X0\nRvugOlBlavxK8xvYlsqTzAmPgKUPljyNtEzQ+gz0I+3mH2jkin2rL3D+SksZZgKm\nfiYMPIQWB2WUF04gB46DDb2mRVuymGHyBOQjIx3WC0KW2mzfoFUFRlZEF+Nt8Ilw\nT+g/u0aZ1IWoszbsVFOEdghgZET0HEarum0B2Je/ozcPYtwmU10iBANGMKdLqaP/\nj954BPunrUf6gmlnLZKIKklJj0advx0NA+cL79+zeVB3zexRYSA5o9q0WPhiuTwR\n/aedWHnBAoGBAP0sDWBAM1Y4TRAf8ZI9PcztwLyHPzfEIqzbObJJnx1icUMt7BWi\n+/RMOnhrlPGE1kMhOqSxvXYN3u+eSmWTqai2sSH5Hdw2EqnrISSTnwNUPINX7fHH\njEkgmXQ6ixE48SuBZnb4w1EjdB/BA6/sjL+FNhggOc87tizLTkMXmMtTAoGBAOZV\n+wPuAMBDBXmbmxCuDIjoVmgSlgeRunB1SA8RCPAFAiUo3+/zEgzW2Oz8kgI+xVwM\n33XkLKrWG1Orhpp6Hm57MjIc5MG+zF4/YRDpE/KNG9qU1tiz0UD5hOpIU9pP4bR/\ngxgPxZzvbk4h5BfHWLpjlk8UUpgk6uxqfti48c1RAoGBALBOKDZ6HwYRCSGMjUcg\n3NPEUi84JD8qmFc2B7Tv7h2he2ykIz9iFAGpwCIyETQsJKX1Ewi0OlNnD3RhEEAy\nl7jFGQ+mkzPSeCbadmcpYlgIJmf1KN/x7fDTAepeBpCEzfZVE80QKbxsaybd3Dp8\nCfwpwWUFtBxr4c7J+gNhAGe/AoGAPn8ZyqkrPv9wXtyfqFjxQbx4pWhVmNwrkBPi\nZ2Qh3q4dNOPwTvTO8vjghvzIyR8rAZzkjOJKVFgftgYWUZfM5gE7T2mTkBYq8W+U\n8LetF+S9qAM2gDnaDx0kuUTCq7t87DKk6URuQ/SbI0wCzYjjRD99KxvChVGPBHKo\n1DjqMuECgYEAgJGNm7/lJCS2wk81whfy/ttKGsEIkyhPFYQmdGzSYC5aDc2gp1R3\nxtOkYEvdjfaLfDGEa4UX8CHHF+w3t9u8hBtcdhMH6GYb9iv6z0VBTt4A/11HUR49\n3Z7TQ18Iyh3jAUCzFV9IJlLIExq5Y7P4B3ojWFBN607sDCt8BMPbDYs=\n-----END RSA PRIVATE KEY-----"
|
||||||
|
|
||||||
@public_key %{
|
@public_key "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0P/Tq4gb4G/QVuMGbJo\nC/AfMNcv+m7NfrlOwkVzcU47jgESuYI4UtJayissCdBycHUnfVUd9qol+eznSODz\nCJhfJloqEIC+aSnuEPGA0POtWad6DU0E6/Ho5zQn5WAWUwbRQqowbrsm/GHo2+3v\neR5jGenwA6sYhINg/c3QQbksyV0uJ20Umyx88w8+TJuv53twOfmyDWuYNoQ3y5cc\nHKOZcLHxYOhvwg3PFaGfFHMFiNmF40dTXt9K96r7sbzc44iLD+VphbMPJEjkMuf8\nPGEFOBzy8pm3wJZw2v32RNW2VESwMYyqDzwHXGSq1a73cS7hEnc79gXlELsK04L9\nQQIDAQAB\n-----END PUBLIC KEY-----\n"
|
||||||
"id" => "https://mastodon.social/users/lambadalambda#main-key",
|
|
||||||
"owner" => "https://mastodon.social/users/lambadalambda",
|
|
||||||
"publicKeyPem" =>
|
|
||||||
"-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAw0P/Tq4gb4G/QVuMGbJo\nC/AfMNcv+m7NfrlOwkVzcU47jgESuYI4UtJayissCdBycHUnfVUd9qol+eznSODz\nCJhfJloqEIC+aSnuEPGA0POtWad6DU0E6/Ho5zQn5WAWUwbRQqowbrsm/GHo2+3v\neR5jGenwA6sYhINg/c3QQbksyV0uJ20Umyx88w8+TJuv53twOfmyDWuYNoQ3y5cc\nHKOZcLHxYOhvwg3PFaGfFHMFiNmF40dTXt9K96r7sbzc44iLD+VphbMPJEjkMuf8\nPGEFOBzy8pm3wJZw2v32RNW2VESwMYyqDzwHXGSq1a73cS7hEnc79gXlELsK04L9\nQQIDAQAB\n-----END PUBLIC KEY-----\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
@rsa_public_key {
|
@rsa_public_key {
|
||||||
:RSAPublicKey,
|
:RSAPublicKey,
|
||||||
|
@ -42,7 +37,7 @@ defp make_fake_conn(key_id),
|
||||||
test "it returns key" do
|
test "it returns key" do
|
||||||
expected_result = {:ok, @rsa_public_key}
|
expected_result = {:ok, @rsa_public_key}
|
||||||
|
|
||||||
user = insert(:user, source_data: %{"publicKey" => @public_key})
|
user = insert(:user, public_key: @public_key)
|
||||||
|
|
||||||
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == expected_result
|
||||||
end
|
end
|
||||||
|
@ -53,8 +48,8 @@ test "it returns error when not found user" do
|
||||||
end) =~ "[error] Could not decode user"
|
end) =~ "[error] Could not decode user"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns error if public key is empty" do
|
test "it returns error if public key is nil" do
|
||||||
user = insert(:user, source_data: %{"publicKey" => %{}})
|
user = insert(:user, public_key: nil)
|
||||||
|
|
||||||
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == {:error, :error}
|
assert Signature.fetch_public_key(make_fake_conn(user.ap_id)) == {:error, :error}
|
||||||
end
|
end
|
||||||
|
|
|
@ -582,7 +582,7 @@ test "updates an existing user, if stale" do
|
||||||
|
|
||||||
{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
{:ok, user} = User.get_or_fetch_by_ap_id("http://mastodon.example.org/users/admin")
|
||||||
|
|
||||||
assert user.source_data["endpoints"]
|
assert user.inbox
|
||||||
|
|
||||||
refute user.last_refreshed_at == orig_user.last_refreshed_at
|
refute user.last_refreshed_at == orig_user.last_refreshed_at
|
||||||
end
|
end
|
||||||
|
|
|
@ -180,7 +180,6 @@ test "it returns a user" do
|
||||||
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
{:ok, user} = ActivityPub.make_user_from_ap_id(user_id)
|
||||||
assert user.ap_id == user_id
|
assert user.ap_id == user_id
|
||||||
assert user.nickname == "admin@mastodon.example.org"
|
assert user.nickname == "admin@mastodon.example.org"
|
||||||
assert user.source_data
|
|
||||||
assert user.ap_enabled
|
assert user.ap_enabled
|
||||||
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
|
assert user.follower_address == "http://mastodon.example.org/users/admin/followers"
|
||||||
end
|
end
|
||||||
|
|
|
@ -48,10 +48,7 @@ test "it returns links" do
|
||||||
|
|
||||||
describe "determine_inbox/2" do
|
describe "determine_inbox/2" do
|
||||||
test "it returns sharedInbox for messages involving as:Public in to" do
|
test "it returns sharedInbox for messages involving as:Public in to" do
|
||||||
user =
|
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||||
insert(:user, %{
|
|
||||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
|
||||||
})
|
|
||||||
|
|
||||||
activity = %Activity{
|
activity = %Activity{
|
||||||
data: %{"to" => [@as_public], "cc" => [user.follower_address]}
|
data: %{"to" => [@as_public], "cc" => [user.follower_address]}
|
||||||
|
@ -61,10 +58,7 @@ test "it returns sharedInbox for messages involving as:Public in to" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns sharedInbox for messages involving as:Public in cc" do
|
test "it returns sharedInbox for messages involving as:Public in cc" do
|
||||||
user =
|
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||||
insert(:user, %{
|
|
||||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
|
||||||
})
|
|
||||||
|
|
||||||
activity = %Activity{
|
activity = %Activity{
|
||||||
data: %{"cc" => [@as_public], "to" => [user.follower_address]}
|
data: %{"cc" => [@as_public], "to" => [user.follower_address]}
|
||||||
|
@ -74,11 +68,7 @@ test "it returns sharedInbox for messages involving as:Public in cc" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns sharedInbox for messages involving multiple recipients in to" do
|
test "it returns sharedInbox for messages involving multiple recipients in to" do
|
||||||
user =
|
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||||
insert(:user, %{
|
|
||||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
|
||||||
})
|
|
||||||
|
|
||||||
user_two = insert(:user)
|
user_two = insert(:user)
|
||||||
user_three = insert(:user)
|
user_three = insert(:user)
|
||||||
|
|
||||||
|
@ -90,11 +80,7 @@ test "it returns sharedInbox for messages involving multiple recipients in to" d
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it returns sharedInbox for messages involving multiple recipients in cc" do
|
test "it returns sharedInbox for messages involving multiple recipients in cc" do
|
||||||
user =
|
user = insert(:user, %{shared_inbox: "http://example.com/inbox"})
|
||||||
insert(:user, %{
|
|
||||||
source_data: %{"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}}
|
|
||||||
})
|
|
||||||
|
|
||||||
user_two = insert(:user)
|
user_two = insert(:user)
|
||||||
user_three = insert(:user)
|
user_three = insert(:user)
|
||||||
|
|
||||||
|
@ -107,12 +93,10 @@ test "it returns sharedInbox for messages involving multiple recipients in cc" d
|
||||||
|
|
||||||
test "it returns sharedInbox for messages involving multiple recipients in total" do
|
test "it returns sharedInbox for messages involving multiple recipients in total" do
|
||||||
user =
|
user =
|
||||||
insert(:user,
|
insert(:user, %{
|
||||||
source_data: %{
|
shared_inbox: "http://example.com/inbox",
|
||||||
"inbox" => "http://example.com/personal-inbox",
|
inbox: "http://example.com/personal-inbox"
|
||||||
"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
user_two = insert(:user)
|
user_two = insert(:user)
|
||||||
|
|
||||||
|
@ -125,12 +109,10 @@ test "it returns sharedInbox for messages involving multiple recipients in total
|
||||||
|
|
||||||
test "it returns inbox for messages involving single recipients in total" do
|
test "it returns inbox for messages involving single recipients in total" do
|
||||||
user =
|
user =
|
||||||
insert(:user,
|
insert(:user, %{
|
||||||
source_data: %{
|
shared_inbox: "http://example.com/inbox",
|
||||||
"inbox" => "http://example.com/personal-inbox",
|
inbox: "http://example.com/personal-inbox"
|
||||||
"endpoints" => %{"sharedInbox" => "http://example.com/inbox"}
|
})
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
activity = %Activity{
|
activity = %Activity{
|
||||||
data: %{"to" => [user.ap_id], "cc" => []}
|
data: %{"to" => [user.ap_id], "cc" => []}
|
||||||
|
@ -258,11 +240,11 @@ test "it returns inbox for messages involving single recipients in total" do
|
||||||
[:passthrough],
|
[:passthrough],
|
||||||
[] do
|
[] do
|
||||||
follower =
|
follower =
|
||||||
insert(:user,
|
insert(:user, %{
|
||||||
local: false,
|
local: false,
|
||||||
source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
|
inbox: "https://domain.com/users/nick1/inbox",
|
||||||
ap_enabled: true
|
ap_enabled: true
|
||||||
)
|
})
|
||||||
|
|
||||||
actor = insert(:user, follower_address: follower.ap_id)
|
actor = insert(:user, follower_address: follower.ap_id)
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
@ -295,14 +277,14 @@ test "it returns inbox for messages involving single recipients in total" do
|
||||||
fetcher =
|
fetcher =
|
||||||
insert(:user,
|
insert(:user,
|
||||||
local: false,
|
local: false,
|
||||||
source_data: %{"inbox" => "https://domain.com/users/nick1/inbox"},
|
inbox: "https://domain.com/users/nick1/inbox",
|
||||||
ap_enabled: true
|
ap_enabled: true
|
||||||
)
|
)
|
||||||
|
|
||||||
another_fetcher =
|
another_fetcher =
|
||||||
insert(:user,
|
insert(:user,
|
||||||
local: false,
|
local: false,
|
||||||
source_data: %{"inbox" => "https://domain2.com/users/nick1/inbox"},
|
inbox: "https://domain2.com/users/nick1/inbox",
|
||||||
ap_enabled: true
|
ap_enabled: true
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -746,7 +746,7 @@ test "it works with custom profile fields" do
|
||||||
|
|
||||||
user = User.get_cached_by_ap_id(activity.actor)
|
user = User.get_cached_by_ap_id(activity.actor)
|
||||||
|
|
||||||
assert User.fields(user) == [
|
assert user.fields == [
|
||||||
%{"name" => "foo", "value" => "bar"},
|
%{"name" => "foo", "value" => "bar"},
|
||||||
%{"name" => "foo1", "value" => "bar1"}
|
%{"name" => "foo1", "value" => "bar1"}
|
||||||
]
|
]
|
||||||
|
@ -767,7 +767,7 @@ test "it works with custom profile fields" do
|
||||||
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
user = User.get_cached_by_ap_id(user.ap_id)
|
||||||
|
|
||||||
assert User.fields(user) == [
|
assert user.fields == [
|
||||||
%{"name" => "foo", "value" => "updated"},
|
%{"name" => "foo", "value" => "updated"},
|
||||||
%{"name" => "foo1", "value" => "updated"}
|
%{"name" => "foo1", "value" => "updated"}
|
||||||
]
|
]
|
||||||
|
@ -785,7 +785,7 @@ test "it works with custom profile fields" do
|
||||||
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
user = User.get_cached_by_ap_id(user.ap_id)
|
||||||
|
|
||||||
assert User.fields(user) == [
|
assert user.fields == [
|
||||||
%{"name" => "foo", "value" => "updated"},
|
%{"name" => "foo", "value" => "updated"},
|
||||||
%{"name" => "foo1", "value" => "updated"}
|
%{"name" => "foo1", "value" => "updated"}
|
||||||
]
|
]
|
||||||
|
@ -796,7 +796,7 @@ test "it works with custom profile fields" do
|
||||||
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
user = User.get_cached_by_ap_id(user.ap_id)
|
||||||
|
|
||||||
assert User.fields(user) == []
|
assert user.fields == []
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it works for incoming update activities which lock the account" do
|
test "it works for incoming update activities which lock the account" do
|
||||||
|
@ -2162,4 +2162,18 @@ test "sets `replies` collection with a limited number of self-replies" do
|
||||||
Transmogrifier.set_replies(object.data)["replies"]
|
Transmogrifier.set_replies(object.data)["replies"]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "take_emoji_tags/1" do
|
||||||
|
user = insert(:user, %{emoji: %{"firefox" => "https://example.org/firefox.png"}})
|
||||||
|
|
||||||
|
assert Transmogrifier.take_emoji_tags(user) == [
|
||||||
|
%{
|
||||||
|
"icon" => %{"type" => "Image", "url" => "https://example.org/firefox.png"},
|
||||||
|
"id" => "https://example.org/firefox.png",
|
||||||
|
"name" => ":firefox:",
|
||||||
|
"type" => "Emoji",
|
||||||
|
"updated" => "1970-01-01T00:00:00Z"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -38,7 +38,7 @@ test "Renders profile fields" do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "Renders with emoji tags" do
|
test "Renders with emoji tags" do
|
||||||
user = insert(:user, emoji: [%{"bib" => "/test"}])
|
user = insert(:user, emoji: %{"bib" => "/test"})
|
||||||
|
|
||||||
assert %{
|
assert %{
|
||||||
"tag" => [
|
"tag" => [
|
||||||
|
|
|
@ -97,18 +97,6 @@ test "it adds emoji in the object" do
|
||||||
assert Object.normalize(activity).data["emoji"]["firefox"]
|
assert Object.normalize(activity).data["emoji"]["firefox"]
|
||||||
end
|
end
|
||||||
|
|
||||||
test "it adds emoji when updating profiles" do
|
|
||||||
user = insert(:user, %{name: ":firefox:"})
|
|
||||||
|
|
||||||
{:ok, activity} = CommonAPI.update(user)
|
|
||||||
user = User.get_cached_by_ap_id(user.ap_id)
|
|
||||||
[firefox] = user.source_data["tag"]
|
|
||||||
|
|
||||||
assert firefox["name"] == ":firefox:"
|
|
||||||
|
|
||||||
assert Pleroma.Constants.as_public() in activity.recipients
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "posting" do
|
describe "posting" do
|
||||||
test "it supports explicit addressing" do
|
test "it supports explicit addressing" do
|
||||||
user = insert(:user)
|
user = insert(:user)
|
||||||
|
|
|
@ -7,7 +7,6 @@ defmodule Pleroma.Web.CommonAPI.UtilsTest do
|
||||||
alias Pleroma.Object
|
alias Pleroma.Object
|
||||||
alias Pleroma.Web.CommonAPI
|
alias Pleroma.Web.CommonAPI
|
||||||
alias Pleroma.Web.CommonAPI.Utils
|
alias Pleroma.Web.CommonAPI.Utils
|
||||||
alias Pleroma.Web.Endpoint
|
|
||||||
use Pleroma.DataCase
|
use Pleroma.DataCase
|
||||||
|
|
||||||
import ExUnit.CaptureLog
|
import ExUnit.CaptureLog
|
||||||
|
@ -42,28 +41,6 @@ test "correct password given" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
test "parses emoji from name and bio" do
|
|
||||||
{:ok, user} = UserBuilder.insert(%{name: ":blank:", bio: ":firefox:"})
|
|
||||||
|
|
||||||
expected = [
|
|
||||||
%{
|
|
||||||
"type" => "Emoji",
|
|
||||||
"icon" => %{"type" => "Image", "url" => "#{Endpoint.url()}/emoji/Firefox.gif"},
|
|
||||||
"name" => ":firefox:"
|
|
||||||
},
|
|
||||||
%{
|
|
||||||
"type" => "Emoji",
|
|
||||||
"icon" => %{
|
|
||||||
"type" => "Image",
|
|
||||||
"url" => "#{Endpoint.url()}/emoji/blank.png"
|
|
||||||
},
|
|
||||||
"name" => ":blank:"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
|
|
||||||
assert expected == Utils.emoji_from_profile(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "format_input/3" do
|
describe "format_input/3" do
|
||||||
test "works for bare text/plain" do
|
test "works for bare text/plain" do
|
||||||
text = "hello world!"
|
text = "hello world!"
|
||||||
|
|
|
@ -78,7 +78,7 @@ test "it federates only to reachable instances via AP" do
|
||||||
local: false,
|
local: false,
|
||||||
nickname: "nick1@domain.com",
|
nickname: "nick1@domain.com",
|
||||||
ap_id: "https://domain.com/users/nick1",
|
ap_id: "https://domain.com/users/nick1",
|
||||||
source_data: %{"inbox" => inbox1},
|
inbox: inbox1,
|
||||||
ap_enabled: true
|
ap_enabled: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ test "it federates only to reachable instances via AP" do
|
||||||
local: false,
|
local: false,
|
||||||
nickname: "nick2@domain2.com",
|
nickname: "nick2@domain2.com",
|
||||||
ap_id: "https://domain2.com/users/nick2",
|
ap_id: "https://domain2.com/users/nick2",
|
||||||
source_data: %{"inbox" => inbox2},
|
inbox: inbox2,
|
||||||
ap_enabled: true
|
ap_enabled: true
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -19,16 +19,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
|
||||||
end
|
end
|
||||||
|
|
||||||
test "Represent a user account" do
|
test "Represent a user account" do
|
||||||
source_data = %{
|
|
||||||
"tag" => [
|
|
||||||
%{
|
|
||||||
"type" => "Emoji",
|
|
||||||
"icon" => %{"url" => "/file.png"},
|
|
||||||
"name" => ":karjalanpiirakka:"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
background_image = %{
|
background_image = %{
|
||||||
"url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
|
"url" => [%{"href" => "https://example.com/images/asuka_hospital.png"}]
|
||||||
}
|
}
|
||||||
|
@ -37,13 +27,13 @@ test "Represent a user account" do
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
follower_count: 3,
|
follower_count: 3,
|
||||||
note_count: 5,
|
note_count: 5,
|
||||||
source_data: source_data,
|
|
||||||
background: background_image,
|
background: background_image,
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
name: ":karjalanpiirakka: shp",
|
name: ":karjalanpiirakka: shp",
|
||||||
bio:
|
bio:
|
||||||
"<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f",
|
"<script src=\"invalid-html\"></script><span>valid html</span>. a<br>b<br/>c<br >d<br />f",
|
||||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
inserted_at: ~N[2017-08-15 15:47:06.597036],
|
||||||
|
emoji: %{"karjalanpiirakka" => "/file.png"}
|
||||||
})
|
})
|
||||||
|
|
||||||
expected = %{
|
expected = %{
|
||||||
|
@ -117,7 +107,6 @@ test "Represent a Service(bot) account" do
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
follower_count: 3,
|
follower_count: 3,
|
||||||
note_count: 5,
|
note_count: 5,
|
||||||
source_data: %{},
|
|
||||||
actor_type: "Service",
|
actor_type: "Service",
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
||||||
|
@ -311,7 +300,6 @@ test "represent an embedded relationship" do
|
||||||
insert(:user, %{
|
insert(:user, %{
|
||||||
follower_count: 0,
|
follower_count: 0,
|
||||||
note_count: 5,
|
note_count: 5,
|
||||||
source_data: %{},
|
|
||||||
actor_type: "Service",
|
actor_type: "Service",
|
||||||
nickname: "shp@shitposter.club",
|
nickname: "shp@shitposter.club",
|
||||||
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
inserted_at: ~N[2017-08-15 15:47:06.597036]
|
||||||
|
|
Loading…
Reference in a new issue