Merge branch 'revert-d31bbb1c' into 'develop'
Rich Text Redo Branch See merge request pleroma/pleroma!314
This commit is contained in:
commit
614e47aa7c
@ -74,7 +74,12 @@
|
|||||||
rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
|
rewrite_policy: Pleroma.Web.ActivityPub.MRF.NoOpPolicy,
|
||||||
public: true,
|
public: true,
|
||||||
quarantined_instances: [],
|
quarantined_instances: [],
|
||||||
managed_config: true
|
managed_config: true,
|
||||||
|
allowed_post_formats: [
|
||||||
|
"text/plain",
|
||||||
|
"text/html",
|
||||||
|
"text/markdown"
|
||||||
|
]
|
||||||
|
|
||||||
config :pleroma, :markup,
|
config :pleroma, :markup,
|
||||||
# XXX - unfortunately, inline images must be enabled by default right now, because
|
# XXX - unfortunately, inline images must be enabled by default right now, because
|
||||||
@ -98,6 +103,7 @@
|
|||||||
redirect_root_login: "/main/friends",
|
redirect_root_login: "/main/friends",
|
||||||
show_instance_panel: true,
|
show_instance_panel: true,
|
||||||
scope_options_enabled: false,
|
scope_options_enabled: false,
|
||||||
|
formatting_options_enabled: false,
|
||||||
collapse_message_with_subject: false
|
collapse_message_with_subject: false
|
||||||
|
|
||||||
config :pleroma, :activitypub,
|
config :pleroma, :activitypub,
|
||||||
|
@ -192,7 +192,11 @@ def get_custom_emoji() do
|
|||||||
]
|
]
|
||||||
|
|
||||||
# TODO: make it use something other than @link_regex
|
# TODO: make it use something other than @link_regex
|
||||||
def html_escape(text) do
|
def html_escape(text, "text/html") do
|
||||||
|
HTML.filter_tags(text)
|
||||||
|
end
|
||||||
|
|
||||||
|
def html_escape(text, "text/plain") do
|
||||||
Regex.split(@link_regex, text, include_captures: true)
|
Regex.split(@link_regex, text, include_captures: true)
|
||||||
|> Enum.map_every(2, fn chunk ->
|
|> Enum.map_every(2, fn chunk ->
|
||||||
{:safe, part} = Phoenix.HTML.html_escape(chunk)
|
{:safe, part} = Phoenix.HTML.html_escape(chunk)
|
||||||
|
@ -73,6 +73,11 @@ def get_visibility(%{"in_reply_to_status_id" => status_id}) when not is_nil(stat
|
|||||||
def get_visibility(_), do: "public"
|
def get_visibility(_), do: "public"
|
||||||
|
|
||||||
@instance Application.get_env(:pleroma, :instance)
|
@instance Application.get_env(:pleroma, :instance)
|
||||||
|
@allowed_post_formats Keyword.get(@instance, :allowed_post_formats)
|
||||||
|
|
||||||
|
defp get_content_type(content_type) when content_type in @allowed_post_formats, do: content_type
|
||||||
|
defp get_content_type(_), do: "text/plain"
|
||||||
|
|
||||||
@limit Keyword.get(@instance, :limit)
|
@limit Keyword.get(@instance, :limit)
|
||||||
def post(user, %{"status" => status} = data) do
|
def post(user, %{"status" => status} = data) do
|
||||||
visibility = get_visibility(data)
|
visibility = get_visibility(data)
|
||||||
@ -85,7 +90,14 @@ def post(user, %{"status" => status} = data) do
|
|||||||
{to, cc} <- to_for_user_and_mentions(user, mentions, inReplyTo, visibility),
|
{to, cc} <- to_for_user_and_mentions(user, mentions, inReplyTo, visibility),
|
||||||
tags <- Formatter.parse_tags(status, data),
|
tags <- Formatter.parse_tags(status, data),
|
||||||
content_html <-
|
content_html <-
|
||||||
make_content_html(status, mentions, attachments, tags, data["no_attachment_links"]),
|
make_content_html(
|
||||||
|
status,
|
||||||
|
mentions,
|
||||||
|
attachments,
|
||||||
|
tags,
|
||||||
|
get_content_type(data["content_type"]),
|
||||||
|
data["no_attachment_links"]
|
||||||
|
),
|
||||||
context <- make_context(inReplyTo),
|
context <- make_context(inReplyTo),
|
||||||
cw <- data["spoiler_text"],
|
cw <- data["spoiler_text"],
|
||||||
object <-
|
object <-
|
||||||
|
@ -63,9 +63,16 @@ def to_for_user_and_mentions(_user, mentions, inReplyTo, "direct") do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def make_content_html(status, mentions, attachments, tags, no_attachment_links \\ false) do
|
def make_content_html(
|
||||||
|
status,
|
||||||
|
mentions,
|
||||||
|
attachments,
|
||||||
|
tags,
|
||||||
|
content_type,
|
||||||
|
no_attachment_links \\ false
|
||||||
|
) do
|
||||||
status
|
status
|
||||||
|> format_input(mentions, tags)
|
|> format_input(mentions, tags, content_type)
|
||||||
|> maybe_add_attachments(attachments, no_attachment_links)
|
|> maybe_add_attachments(attachments, no_attachment_links)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -92,9 +99,9 @@ def add_attachments(text, attachments) do
|
|||||||
Enum.join([text | attachment_text], "<br>")
|
Enum.join([text | attachment_text], "<br>")
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_input(text, mentions, tags) do
|
def format_input(text, mentions, tags, "text/plain") do
|
||||||
text
|
text
|
||||||
|> Formatter.html_escape()
|
|> Formatter.html_escape("text/plain")
|
||||||
|> String.replace(~r/\r?\n/, "<br>")
|
|> String.replace(~r/\r?\n/, "<br>")
|
||||||
|> (&{[], &1}).()
|
|> (&{[], &1}).()
|
||||||
|> Formatter.add_links()
|
|> Formatter.add_links()
|
||||||
@ -103,6 +110,25 @@ def format_input(text, mentions, tags) do
|
|||||||
|> Formatter.finalize()
|
|> Formatter.finalize()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def format_input(text, mentions, tags, "text/html") do
|
||||||
|
text
|
||||||
|
|> Formatter.html_escape("text/html")
|
||||||
|
|> String.replace(~r/\r?\n/, "<br>")
|
||||||
|
|> (&{[], &1}).()
|
||||||
|
|> Formatter.add_user_links(mentions)
|
||||||
|
|> Formatter.finalize()
|
||||||
|
end
|
||||||
|
|
||||||
|
def format_input(text, mentions, tags, "text/markdown") do
|
||||||
|
text
|
||||||
|
|> Earmark.as_html!()
|
||||||
|
|> Formatter.html_escape("text/html")
|
||||||
|
|> String.replace(~r/\r?\n/, "")
|
||||||
|
|> (&{[], &1}).()
|
||||||
|
|> Formatter.add_user_links(mentions)
|
||||||
|
|> Formatter.finalize()
|
||||||
|
end
|
||||||
|
|
||||||
def add_tag_links(text, tags) do
|
def add_tag_links(text, tags) do
|
||||||
tags =
|
tags =
|
||||||
tags
|
tags
|
||||||
|
@ -92,7 +92,8 @@ def nodeinfo(conn, %{"version" => "2.0"}) do
|
|||||||
mrf_policies: mrf_policies,
|
mrf_policies: mrf_policies,
|
||||||
mrf_simple: mrf_simple,
|
mrf_simple: mrf_simple,
|
||||||
quarantined_instances: quarantined
|
quarantined_instances: quarantined
|
||||||
}
|
},
|
||||||
|
postFormats: Keyword.get(instance, :allowed_post_formats)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,6 +176,7 @@ def config(conn, _params) do
|
|||||||
chatDisabled: !Keyword.get(@instance_chat, :enabled),
|
chatDisabled: !Keyword.get(@instance_chat, :enabled),
|
||||||
showInstanceSpecificPanel: Keyword.get(@instance_fe, :show_instance_panel),
|
showInstanceSpecificPanel: Keyword.get(@instance_fe, :show_instance_panel),
|
||||||
scopeOptionsEnabled: Keyword.get(@instance_fe, :scope_options_enabled),
|
scopeOptionsEnabled: Keyword.get(@instance_fe, :scope_options_enabled),
|
||||||
|
formattingOptionsEnabled: Keyword.get(@instance_fe, :formatting_options_enabled),
|
||||||
collapseMessageWithSubject: Keyword.get(@instance_fe, :collapse_message_with_subject)
|
collapseMessageWithSubject: Keyword.get(@instance_fe, :collapse_message_with_subject)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ def update_profile(%{assigns: %{user: user}} = conn, params) do
|
|||||||
{String.trim(name, ":"), url}
|
{String.trim(name, ":"), url}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
bio_html = CommonUtils.format_input(bio, mentions, tags)
|
bio_html = CommonUtils.format_input(bio, mentions, tags, "text/plain")
|
||||||
Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
|
Map.put(params, "bio", bio_html |> Formatter.emojify(emoji))
|
||||||
else
|
else
|
||||||
params
|
params
|
||||||
|
1
mix.exs
1
mix.exs
@ -48,6 +48,7 @@ defp deps do
|
|||||||
{:mogrify, "~> 0.6.1"},
|
{:mogrify, "~> 0.6.1"},
|
||||||
{:ex_aws, "~> 2.0"},
|
{:ex_aws, "~> 2.0"},
|
||||||
{:ex_aws_s3, "~> 2.0"},
|
{:ex_aws_s3, "~> 2.0"},
|
||||||
|
{:earmark, "~> 1.2"},
|
||||||
{:ex_machina, "~> 2.2", only: :test},
|
{:ex_machina, "~> 2.2", only: :test},
|
||||||
{:credo, "~> 0.9.3", only: [:dev, :test]},
|
{:credo, "~> 0.9.3", only: [:dev, :test]},
|
||||||
{:mock, "~> 0.3.1", only: :test},
|
{:mock, "~> 0.3.1", only: :test},
|
||||||
|
1
mix.lock
1
mix.lock
@ -11,6 +11,7 @@
|
|||||||
"crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
|
"crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
|
||||||
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
"db_connection": {:hex, :db_connection, "1.1.3", "89b30ca1ef0a3b469b1c779579590688561d586694a3ce8792985d4d7e575a61", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
|
"decimal": {:hex, :decimal, "1.5.0", "b0433a36d0e2430e3d50291b1c65f53c37d56f83665b43d79963684865beab68", [:mix], [], "hexpm"},
|
||||||
|
"earmark": {:hex, :earmark, "1.2.6", "b6da42b3831458d3ecc57314dff3051b080b9b2be88c2e5aa41cd642a5b044ed", [:mix], [], "hexpm"},
|
||||||
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
"ecto": {:hex, :ecto, "2.2.10", "e7366dc82f48f8dd78fcbf3ab50985ceeb11cb3dc93435147c6e13f2cda0992e", [:mix], [{:db_connection, "~> 1.1", [hex: :db_connection, repo: "hexpm", optional: true]}, {:decimal, "~> 1.2", [hex: :decimal, repo: "hexpm", optional: false]}, {:mariaex, "~> 0.8.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:poison, "~> 2.2 or ~> 3.0", [hex: :poison, repo: "hexpm", optional: true]}, {:poolboy, "~> 1.5", [hex: :poolboy, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.13.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:sbroker, "~> 1.0", [hex: :sbroker, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
"eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
|
"eternal": {:hex, :eternal, "1.2.0", "e2a6b6ce3b8c248f7dc31451aefca57e3bdf0e48d73ae5043229380a67614c41", [:mix], [], "hexpm"},
|
||||||
"ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
|
"ex_aws": {:hex, :ex_aws, "2.1.0", "b92651527d6c09c479f9013caa9c7331f19cba38a650590d82ebf2c6c16a1d8a", [:mix], [{:configparser_ex, "~> 2.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "1.6.3 or 1.6.5 or 1.7.1 or 1.8.6 or ~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jsx, "~> 2.8", [hex: :jsx, repo: "hexpm", optional: true]}, {:poison, ">= 1.2.0", [hex: :poison, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}, {:xml_builder, "~> 0.1.0", [hex: :xml_builder, repo: "hexpm", optional: true]}], "hexpm"},
|
||||||
|
@ -21,4 +21,36 @@ test "it adds emoji when updating profiles" do
|
|||||||
|
|
||||||
assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
|
assert karjalanpiirakka["name"] == ":karjalanpiirakka:"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "posting" do
|
||||||
|
test "it filters out obviously bad tags when accepting a post as HTML" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
post = "<p><b>2hu</b></p><script>alert('xss')</script>"
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(user, %{
|
||||||
|
"status" => post,
|
||||||
|
"content_type" => "text/html"
|
||||||
|
})
|
||||||
|
|
||||||
|
content = activity.data["object"]["content"]
|
||||||
|
assert content == "<p><b>2hu</b></p>alert('xss')"
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it filters out obviously bad tags when accepting a post as Markdown" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
post = "<p><b>2hu</b></p><script>alert('xss')</script>"
|
||||||
|
|
||||||
|
{:ok, activity} =
|
||||||
|
CommonAPI.post(user, %{
|
||||||
|
"status" => post,
|
||||||
|
"content_type" => "text/markdown"
|
||||||
|
})
|
||||||
|
|
||||||
|
content = activity.data["object"]["content"]
|
||||||
|
assert content == "<p><b>2hu</b></p>alert('xss')"
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user