fix(feed): complete Atom XML metadata
This commit is contained in:
parent
5f71532442
commit
c5230d98c5
6 changed files with 75 additions and 4 deletions
|
|
@ -43,7 +43,7 @@ defmodule Pleroma.Web.Feed.FeedView do
|
||||||
def most_recent_update(activities, :rss) do
|
def most_recent_update(activities, :rss) do
|
||||||
activities
|
activities
|
||||||
|> Enum.map(fn activity ->
|
|> Enum.map(fn activity ->
|
||||||
case Object.normalize(activity, fetch: false) do
|
case activity.object do
|
||||||
%Object{updated_at: updated_at} -> updated_at
|
%Object{updated_at: updated_at} -> updated_at
|
||||||
_ -> activity.updated_at
|
_ -> activity.updated_at
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<entry>
|
<entry>
|
||||||
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
<activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
|
||||||
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
<activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
|
||||||
<id><%= @data["id"] %></id>
|
<id><%= escape(@data["id"] || "") %></id>
|
||||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
||||||
<published><%= to_rfc3339(@data["published"]) %></published>
|
<published><%= to_rfc3339(@data["published"]) %></published>
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
<%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %>
|
<%= render Phoenix.Controller.view_module(@conn), "_tag_author.atom", assigns %>
|
||||||
|
|
||||||
<id><%= @data["id"] %></id>
|
<id><%= escape(@data["id"] || "") %></id>
|
||||||
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
<title><%= activity_title(@data, Keyword.get(@feed_config, :post_title, %{})) %></title>
|
||||||
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
<content type="html"><%= escape(atom_content_encoded(@data)) %></content>
|
||||||
<published><%= to_rfc3339(@data["published"]) %></published>
|
<published><%= to_rfc3339(@data["published"]) %></published>
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<subtitle><%= subtitle %></subtitle>
|
<subtitle><%= subtitle %></subtitle>
|
||||||
<% end %>
|
<% end %>
|
||||||
<logo><%= feed_logo() %></logo>
|
<logo><%= feed_logo() %></logo>
|
||||||
<updated><%= most_recent_update(@activities) %></updated>
|
<updated><%= most_recent_update(@activities) || to_rfc3339(NaiveDateTime.utc_now()) %></updated>
|
||||||
<link rel="self" href="<%= feed_self_url(@conn) %>" type="application/atom+xml"/>
|
<link rel="self" href="<%= feed_self_url(@conn) %>" type="application/atom+xml"/>
|
||||||
|
|
||||||
<%= for activity <- @activities do %>
|
<%= for activity <- @activities do %>
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,49 @@ defmodule Pleroma.Web.Feed.TagControllerTest do
|
||||||
refute response =~ "<lastBuildDate>"
|
refute response =~ "<lastBuildDate>"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "provides a valid updated timestamp for an empty Atom feed", %{conn: conn} do
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|
|> get(tag_feed_path(conn, :feed, "empty.atom"))
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
updated = response |> parse() |> xpath(~x"//feed/updated/text()"s)
|
||||||
|
assert {:ok, _datetime, 0} = DateTime.from_iso8601(updated)
|
||||||
|
end
|
||||||
|
|
||||||
|
test "escapes Atom IDs and tag feed self links", %{conn: conn} do
|
||||||
|
user = insert(:user, local: false)
|
||||||
|
object_id = "https://remote.example/object?first=one&second=two"
|
||||||
|
|
||||||
|
note =
|
||||||
|
insert(:note,
|
||||||
|
user: user,
|
||||||
|
object_local: false,
|
||||||
|
data: %{
|
||||||
|
"content" => "remote #atomlink",
|
||||||
|
"external_url" => object_id,
|
||||||
|
"id" => object_id,
|
||||||
|
"summary" => "",
|
||||||
|
"tag" => ["atomlink"]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
insert(:note_activity, user: user, note: note, local: false, object_local: false)
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> put_req_header("accept", "application/atom+xml")
|
||||||
|
|> get("/tags/atomlink.atom?third=three&fourth=four")
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
assert response =~ "https://remote.example/object?first=one&second=two"
|
||||||
|
assert response =~ "third=three&fourth=four"
|
||||||
|
|
||||||
|
xml = parse(response)
|
||||||
|
assert xpath(xml, ~x"//feed/entry/id/text()"s) == object_id
|
||||||
|
end
|
||||||
|
|
||||||
test "escapes and round-trips RSS item permalinks", %{conn: conn} do
|
test "escapes and round-trips RSS item permalinks", %{conn: conn} do
|
||||||
user = insert(:user, local: false)
|
user = insert(:user, local: false)
|
||||||
permalink = "https://remote.example/post?first=one&second=two"
|
permalink = "https://remote.example/post?first=one&second=two"
|
||||||
|
|
|
||||||
|
|
@ -150,6 +150,34 @@ defmodule Pleroma.Web.Feed.UserControllerTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
test "keeps fallback summary markup inert in rendered Atom content", %{
|
||||||
|
conn: conn,
|
||||||
|
object: object,
|
||||||
|
user: user
|
||||||
|
} do
|
||||||
|
data =
|
||||||
|
object.data
|
||||||
|
|> Map.put("content", "")
|
||||||
|
|> Map.put("summary", "<script>alert('feed')</script>")
|
||||||
|
|
||||||
|
object
|
||||||
|
|> Ecto.Changeset.change(data: data)
|
||||||
|
|> Pleroma.Repo.update!()
|
||||||
|
|
||||||
|
response =
|
||||||
|
conn
|
||||||
|
|> get("/users/#{user.nickname}/feed.atom")
|
||||||
|
|> response(200)
|
||||||
|
|
||||||
|
assert response =~ "&lt;script&gt;alert(&#39;feed&#39;)&lt;/script&gt;"
|
||||||
|
|
||||||
|
content_values = response |> parse() |> xpath(~x"//entry/content/text()"sl)
|
||||||
|
|
||||||
|
assert Enum.any?(content_values, fn content ->
|
||||||
|
String.starts_with?(content, "<script>alert('feed')</script>")
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
test "does not expose sensitive attachments as enclosures", %{
|
test "does not expose sensitive attachments as enclosures", %{
|
||||||
conn: conn,
|
conn: conn,
|
||||||
object: object,
|
object: object,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue