Merge pull request 'web/metadata: provide alternate link for ActivityPub' (#905) from Oneric/akkoma:metadata_aplink into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/905
This commit is contained in:
commit
487473cd75
4 changed files with 91 additions and 1 deletions
|
@ -64,7 +64,11 @@ def activity_nsfw?(_) do
|
||||||
|
|
||||||
defp activated_providers do
|
defp activated_providers do
|
||||||
unless Pleroma.Config.restrict_unauthenticated_access?(:activities, :local) do
|
unless Pleroma.Config.restrict_unauthenticated_access?(:activities, :local) do
|
||||||
[Pleroma.Web.Metadata.Providers.Feed | Pleroma.Config.get([__MODULE__, :providers], [])]
|
[
|
||||||
|
Pleroma.Web.Metadata.Providers.Feed,
|
||||||
|
Pleroma.Web.Metadata.Providers.ApUrl
|
||||||
|
| Pleroma.Config.get([__MODULE__, :providers], [])
|
||||||
|
]
|
||||||
else
|
else
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
35
lib/pleroma/web/metadata/providers/ap_url.ex
Normal file
35
lib/pleroma/web/metadata/providers/ap_url.ex
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
# Akkoma: Magically expressive social media
|
||||||
|
# Copyright © 2025 Akkoma Authors <https://akkoma.dev/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Metadata.Providers.ApUrl do
|
||||||
|
alias Pleroma.Web.Metadata.Providers.Provider
|
||||||
|
|
||||||
|
@behaviour Provider
|
||||||
|
|
||||||
|
defp alt_link(uri, type) do
|
||||||
|
{
|
||||||
|
:link,
|
||||||
|
[rel: "alternate", href: uri, type: type],
|
||||||
|
[]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
defp ap_alt_links(uri) do
|
||||||
|
[
|
||||||
|
alt_link(uri, "application/activity+json"),
|
||||||
|
alt_link(uri, "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"")
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl Provider
|
||||||
|
def build_tags(%{object: %{data: %{"id" => ap_id}}}) when is_binary(ap_id) do
|
||||||
|
ap_alt_links(ap_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_tags(%{user: %{ap_id: ap_id}}) when is_binary(ap_id) do
|
||||||
|
ap_alt_links(ap_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_tags(_), do: []
|
||||||
|
end
|
31
test/pleroma/web/metadata/providers/ap_url_test.exs
Normal file
31
test/pleroma/web/metadata/providers/ap_url_test.exs
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Web.Metadata.Providers.ApUrlTest do
|
||||||
|
use Pleroma.DataCase, async: true
|
||||||
|
import Pleroma.Factory
|
||||||
|
alias Pleroma.Web.Metadata.Providers.ApUrl
|
||||||
|
|
||||||
|
@ap_type_compliant "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\""
|
||||||
|
@ap_type_mastodon "application/activity+json"
|
||||||
|
|
||||||
|
test "it preferentially renders a link to a post" do
|
||||||
|
user = insert(:user)
|
||||||
|
note = insert(:note, user: user)
|
||||||
|
|
||||||
|
assert ApUrl.build_tags(%{object: note, user: user}) == [
|
||||||
|
{:link, [rel: "alternate", href: note.data["id"], type: @ap_type_mastodon], []},
|
||||||
|
{:link, [rel: "alternate", href: note.data["id"], type: @ap_type_compliant], []}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
test "it renders a link to a user" do
|
||||||
|
user = insert(:user)
|
||||||
|
|
||||||
|
assert ApUrl.build_tags(%{user: user}) == [
|
||||||
|
{:link, [rel: "alternate", href: user.ap_id, type: @ap_type_mastodon], []},
|
||||||
|
{:link, [rel: "alternate", href: user.ap_id, type: @ap_type_compliant], []}
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
|
@ -321,6 +321,16 @@ defp meta_find_twitter(document, name) do
|
||||||
Floki.find(document, "head>meta[name=\"twitter:" <> name <> "\"]")
|
Floki.find(document, "head>meta[name=\"twitter:" <> name <> "\"]")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp meta_find_alt_links(document) do
|
||||||
|
Floki.find(document, "head>link[rel=\"alternate\"]")
|
||||||
|
|> Enum.map(fn {_, attr, _} ->
|
||||||
|
{
|
||||||
|
:proplists.get_value("type", attr),
|
||||||
|
:proplists.get_value("href", attr)
|
||||||
|
}
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
# Detailed metadata tests are already done for each builder individually, so just
|
# Detailed metadata tests are already done for each builder individually, so just
|
||||||
# one check per type of content should suffice to ensure we're calling the providers correctly
|
# one check per type of content should suffice to ensure we're calling the providers correctly
|
||||||
describe "metadata tags for" do
|
describe "metadata tags for" do
|
||||||
|
@ -350,6 +360,8 @@ test "user profile", %{conn: conn, user: user, user_avatar_url: user_avatar_url}
|
||||||
[{"meta", tw_desc, _}] = meta_find_twitter(document, "description")
|
[{"meta", tw_desc, _}] = meta_find_twitter(document, "description")
|
||||||
[{"meta", tw_img, _}] = meta_find_twitter(document, "image")
|
[{"meta", tw_img, _}] = meta_find_twitter(document, "image")
|
||||||
|
|
||||||
|
alt_links = meta_find_alt_links(document)
|
||||||
|
|
||||||
assert meta_content(og_type) == "article"
|
assert meta_content(og_type) == "article"
|
||||||
assert meta_content(og_title) == Pleroma.Web.Metadata.Utils.user_name_string(user)
|
assert meta_content(og_title) == Pleroma.Web.Metadata.Utils.user_name_string(user)
|
||||||
assert meta_content(og_url) == user.ap_id
|
assert meta_content(og_url) == user.ap_id
|
||||||
|
@ -362,6 +374,8 @@ test "user profile", %{conn: conn, user: user, user_avatar_url: user_avatar_url}
|
||||||
assert meta_content(tw_title) == meta_content(og_title)
|
assert meta_content(tw_title) == meta_content(og_title)
|
||||||
assert meta_content(tw_desc) == meta_content(og_desc)
|
assert meta_content(tw_desc) == meta_content(og_desc)
|
||||||
assert meta_content(tw_img) == meta_content(og_img)
|
assert meta_content(tw_img) == meta_content(og_img)
|
||||||
|
|
||||||
|
assert Enum.any?(alt_links, fn e -> e == {"application/activity+json", user.ap_id} end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "text-only post", %{conn: conn, user: user, user_avatar_url: user_avatar_url} do
|
test "text-only post", %{conn: conn, user: user, user_avatar_url: user_avatar_url} do
|
||||||
|
@ -386,6 +400,8 @@ test "text-only post", %{conn: conn, user: user, user_avatar_url: user_avatar_ur
|
||||||
[{"meta", tw_desc, _}] = meta_find_twitter(document, "description")
|
[{"meta", tw_desc, _}] = meta_find_twitter(document, "description")
|
||||||
[{"meta", tw_img, _}] = meta_find_twitter(document, "image")
|
[{"meta", tw_img, _}] = meta_find_twitter(document, "image")
|
||||||
|
|
||||||
|
alt_links = meta_find_alt_links(document)
|
||||||
|
|
||||||
assert meta_content(og_type) == "article"
|
assert meta_content(og_type) == "article"
|
||||||
assert meta_content(og_title) == Pleroma.Web.Metadata.Utils.user_name_string(user)
|
assert meta_content(og_title) == Pleroma.Web.Metadata.Utils.user_name_string(user)
|
||||||
assert meta_content(og_url) == activity.data["id"]
|
assert meta_content(og_url) == activity.data["id"]
|
||||||
|
@ -398,6 +414,10 @@ test "text-only post", %{conn: conn, user: user, user_avatar_url: user_avatar_ur
|
||||||
assert meta_content(tw_title) == meta_content(og_title)
|
assert meta_content(tw_title) == meta_content(og_title)
|
||||||
assert meta_content(tw_desc) == meta_content(og_desc)
|
assert meta_content(tw_desc) == meta_content(og_desc)
|
||||||
assert meta_content(tw_img) == meta_content(og_img)
|
assert meta_content(tw_img) == meta_content(og_img)
|
||||||
|
|
||||||
|
assert Enum.any?(alt_links, fn e ->
|
||||||
|
e == {"application/activity+json", activity.object.data["id"]}
|
||||||
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
test "post with attachments", %{conn: conn, user: user} do
|
test "post with attachments", %{conn: conn, user: user} do
|
||||||
|
|
Loading…
Reference in a new issue