Add custom profile fields
This commit is contained in:
parent
744e2ce8b4
commit
e0ac5c7a66
|
@ -255,6 +255,7 @@
|
||||||
dynamic_configuration: false,
|
dynamic_configuration: false,
|
||||||
user_bio_length: 5000,
|
user_bio_length: 5000,
|
||||||
user_name_length: 100,
|
user_name_length: 100,
|
||||||
|
max_account_fields: 4,
|
||||||
external_user_synchronization: true
|
external_user_synchronization: true
|
||||||
|
|
||||||
config :pleroma, :markup,
|
config :pleroma, :markup,
|
||||||
|
|
|
@ -132,6 +132,7 @@ config :pleroma, Pleroma.Emails.Mailer,
|
||||||
* `skip_thread_containment`: Skip filter out broken threads. The default is `false`.
|
* `skip_thread_containment`: Skip filter out broken threads. The default is `false`.
|
||||||
* `limit_to_local_content`: Limit unauthenticated users to search for local statutes and users only. Possible values: `:unauthenticated`, `:all` and `false`. The default is `:unauthenticated`.
|
* `limit_to_local_content`: Limit unauthenticated users to search for local statutes and users only. Possible values: `:unauthenticated`, `:all` and `false`. The default is `:unauthenticated`.
|
||||||
* `dynamic_configuration`: Allow transferring configuration to DB with the subsequent customization from Admin api.
|
* `dynamic_configuration`: Allow transferring configuration to DB with the subsequent customization from Admin api.
|
||||||
|
* `max_account_fields`: The maximum number of custom fields in the user profile (default: `4`)
|
||||||
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
|
* `external_user_synchronization`: Enabling following/followers counters synchronization for external users.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ defmodule Pleroma.User.Info do
|
||||||
field(:mascot, :map, default: nil)
|
field(:mascot, :map, default: nil)
|
||||||
field(:emoji, {:array, :map}, default: [])
|
field(:emoji, {:array, :map}, default: [])
|
||||||
field(:pleroma_settings_store, :map, default: %{})
|
field(:pleroma_settings_store, :map, default: %{})
|
||||||
|
field(:fields, {:array, :map}, default: [])
|
||||||
|
|
||||||
field(:notification_settings, :map,
|
field(:notification_settings, :map,
|
||||||
default: %{
|
default: %{
|
||||||
|
@ -286,10 +287,32 @@ def profile_update(info, params) do
|
||||||
:background,
|
:background,
|
||||||
:show_role,
|
:show_role,
|
||||||
:skip_thread_containment,
|
:skip_thread_containment,
|
||||||
|
:fields,
|
||||||
:pleroma_settings_store
|
:pleroma_settings_store
|
||||||
])
|
])
|
||||||
|
|> validate_fields()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_fields(changeset) do
|
||||||
|
limit = Pleroma.Config.get([:instance, :max_account_fields], 0)
|
||||||
|
|
||||||
|
changeset
|
||||||
|
|> validate_length(:fields, max: limit)
|
||||||
|
|> validate_change(:fields, fn :fields, fields ->
|
||||||
|
if Enum.all?(fields, &valid_field?/1) do
|
||||||
|
[]
|
||||||
|
else
|
||||||
|
[fields: "invalid"]
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp valid_field?(%{"name" => name, "value" => value}) do
|
||||||
|
is_binary(name) && is_binary(value)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp valid_field?(_), do: false
|
||||||
|
|
||||||
@spec confirmation_changeset(Info.t(), keyword()) :: Changeset.t()
|
@spec confirmation_changeset(Info.t(), keyword()) :: Changeset.t()
|
||||||
def confirmation_changeset(info, opts) do
|
def confirmation_changeset(info, opts) do
|
||||||
need_confirmation? = Keyword.get(opts, :need_confirmation)
|
need_confirmation? = Keyword.get(opts, :need_confirmation)
|
||||||
|
@ -384,6 +407,14 @@ def remove_reblog_mute(info, ap_id) do
|
||||||
cast(info, params, [:muted_reblogs])
|
cast(info, params, [:muted_reblogs])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def fields(%{source_data: %{"attachment" => attachment}}) do
|
||||||
|
attachment
|
||||||
|
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
||||||
|
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fields(%{fields: fields}), do: fields
|
||||||
|
|
||||||
def follow_information_update(info, params) do
|
def follow_information_update(info, params) do
|
||||||
info
|
info
|
||||||
|> cast(params, [
|
|> cast(params, [
|
||||||
|
|
|
@ -156,6 +156,17 @@ def update_credentials(%{assigns: %{user: user}} = conn, params) do
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|> add_if_present(params, "default_scope", :default_scope)
|
|> add_if_present(params, "default_scope", :default_scope)
|
||||||
|
|> add_if_present(params, "fields", :fields, fn fields ->
|
||||||
|
fields =
|
||||||
|
Enum.map(fields, fn field ->
|
||||||
|
%{
|
||||||
|
"name" => Formatter.html_escape(field["name"], "text/plain"),
|
||||||
|
"value" => Formatter.html_escape(field["value"], "text/plain")
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
|
||||||
|
{:ok, fields}
|
||||||
|
end)
|
||||||
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
|
|> add_if_present(params, "pleroma_settings_store", :pleroma_settings_store, fn value ->
|
||||||
{:ok, Map.merge(user.info.pleroma_settings_store, value)}
|
{:ok, Map.merge(user.info.pleroma_settings_store, value)}
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -93,10 +93,8 @@ defp do_render("account.json", %{user: user} = opts) do
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
fields =
|
fields = User.Info.fields(user.info)
|
||||||
(user.info.source_data["attachment"] || [])
|
fields_html = Enum.map(fields, fn f -> Map.update!(f, "value", &AutoLinker.link(&1)) end)
|
||||||
|> Enum.filter(fn %{"type" => t} -> t == "PropertyValue" end)
|
|
||||||
|> Enum.map(fn fields -> Map.take(fields, ["name", "value"]) end)
|
|
||||||
|
|
||||||
bio = HTML.filter_tags(user.bio, User.html_filter_policy(opts[:for]))
|
bio = HTML.filter_tags(user.bio, User.html_filter_policy(opts[:for]))
|
||||||
|
|
||||||
|
@ -119,11 +117,12 @@ defp do_render("account.json", %{user: user} = opts) do
|
||||||
header: header,
|
header: header,
|
||||||
header_static: header,
|
header_static: header,
|
||||||
emojis: emojis,
|
emojis: emojis,
|
||||||
fields: fields,
|
fields: fields_html,
|
||||||
bot: bot,
|
bot: bot,
|
||||||
source: %{
|
source: %{
|
||||||
note: HTML.strip_tags((user.bio || "") |> String.replace("<br>", "\n")),
|
note: HTML.strip_tags((user.bio || "") |> String.replace("<br>", "\n")),
|
||||||
sensitive: false,
|
sensitive: false,
|
||||||
|
fields: fields,
|
||||||
pleroma: %{}
|
pleroma: %{}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -300,5 +300,44 @@ test "updates profile emojos", %{conn: conn} do
|
||||||
assert user["display_name"] == name
|
assert user["display_name"] == name
|
||||||
assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user["emojis"]
|
assert [%{"shortcode" => "blank"}, %{"shortcode" => "firefox"}] = user["emojis"]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "update fields", %{conn: conn} do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
%{"name" => "<b>foo<b>", "value" => "<i>bar</i>"},
|
||||||
|
%{"name" => "link", "value" => "cofe.io"}
|
||||||
|
]
|
||||||
|
|
||||||
|
account =
|
||||||
|
conn
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|
||||||
|
|> json_response(200)
|
||||||
|
|
||||||
|
assert account["fields"] == [
|
||||||
|
%{"name" => "<b>foo<b>", "value" => "<i>bar</i>"},
|
||||||
|
%{"name" => "link", "value" => "<a href=\"http://cofe.io\">cofe.io</a>"}
|
||||||
|
]
|
||||||
|
|
||||||
|
assert account["source"]["fields"] == [
|
||||||
|
%{"name" => "<b>foo<b>", "value" => "<i>bar</i>"},
|
||||||
|
%{"name" => "link", "value" => "cofe.io"}
|
||||||
|
]
|
||||||
|
|
||||||
|
Pleroma.Config.put([:instance, :max_account_fields], 1)
|
||||||
|
|
||||||
|
fields = [
|
||||||
|
%{"name" => "<b>foo<b>", "value" => "<i>bar</i>"},
|
||||||
|
%{"name" => "link", "value" => "cofe.io"}
|
||||||
|
]
|
||||||
|
|
||||||
|
conn =
|
||||||
|
conn
|
||||||
|
|> assign(:user, user)
|
||||||
|
|> patch("/api/v1/accounts/update_credentials", %{"fields" => fields})
|
||||||
|
|
||||||
|
assert %{"error" => "Invalid request"} == json_response(conn, 403)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue