MRF InlineQuotePolicy: Don't inline quoted post URL in Mastodon quotes

This commit is contained in:
Phantasm 2025-11-29 17:12:32 +00:00 committed by nicole mikołajczyk
commit 5cb141a54e
4 changed files with 114 additions and 0 deletions

View file

@ -0,0 +1 @@
MRF InlineQuotePolicy: Don't inline quoted post URL in Mastodon quote posts

View file

@ -18,6 +18,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy do
content =~ quote_url -> true
# Does the content already have a .quote-inline span?
content =~ "<span class=\"quote-inline\">" -> true
# Does the content already have a .quote-inline p? (Mastodon)
content =~ "<p class=\"quote-inline\">" -> true
# No inline quote found
true -> false
end

View file

@ -0,0 +1,93 @@
{
"@context": [
"https://www.w3.org/ns/activitystreams",
{
"ostatus": "http://ostatus.org#",
"atomUri": "ostatus:atomUri",
"inReplyToAtomUri": "ostatus:inReplyToAtomUri",
"conversation": "ostatus:conversation",
"sensitive": "as:sensitive",
"toot": "http://joinmastodon.org/ns#",
"votersCount": "toot:votersCount",
"quote": "https://w3id.org/fep/044f#quote",
"quoteUri": "http://fedibird.com/ns#quoteUri",
"_misskey_quote": "https://misskey-hub.net/ns#_misskey_quote",
"quoteAuthorization": {
"@id": "https://w3id.org/fep/044f#quoteAuthorization",
"@type": "@id"
},
"gts": "https://gotosocial.org/ns#",
"interactionPolicy": {
"@id": "gts:interactionPolicy",
"@type": "@id"
},
"canQuote": {
"@id": "gts:canQuote",
"@type": "@id"
},
"automaticApproval": {
"@id": "gts:automaticApproval",
"@type": "@id"
},
"manualApproval": {
"@id": "gts:manualApproval",
"@type": "@id"
}
}
],
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171",
"type": "Note",
"summary": null,
"inReplyTo": null,
"published": "2025-10-09T17:54:47Z",
"url": "https://mastodon.social/@gwynnion/115345489087257171",
"attributedTo": "https://mastodon.social/users/gwynnion",
"to": [
"https://www.w3.org/ns/activitystreams#Public"
],
"cc": [
"https://mastodon.social/users/gwynnion/followers"
],
"sensitive": false,
"atomUri": "https://mastodon.social/users/gwynnion/statuses/115345489087257171",
"inReplyToAtomUri": null,
"conversation": "https://mastodon.social/contexts/109836797527169643-115345489087257171",
"context": "https://mastodon.social/contexts/109836797527169643-115345489087257171",
"content": "<p class=\"quote-inline\">RE: <a href=\"https://mastodon.social/@404mediaco/115344945575874225\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">mastodon.social/@404mediaco/11</span><span class=\"invisible\">5344945575874225</span></a></p><p>Every age verification system is just a scheme for companies and hackers to steal your identity.</p>",
"contentMap": {
"en": "<p class=\"quote-inline\">RE: <a href=\"https://mastodon.social/@404mediaco/115344945575874225\" target=\"_blank\" rel=\"nofollow noopener\" translate=\"no\"><span class=\"invisible\">https://</span><span class=\"ellipsis\">mastodon.social/@404mediaco/11</span><span class=\"invisible\">5344945575874225</span></a></p><p>Every age verification system is just a scheme for companies and hackers to steal your identity.</p>"
},
"quote": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
"_misskey_quote": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
"quoteUri": "https://mastodon.social/users/404mediaco/statuses/115344945575874225",
"quoteAuthorization": "https://mastodon.social/users/404mediaco/quote_authorizations/115345489087269783",
"interactionPolicy": {
"canQuote": {
"automaticApproval": [
"https://www.w3.org/ns/activitystreams#Public"
]
}
},
"attachment": [],
"tag": [],
"replies": {
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies",
"type": "Collection",
"first": {
"type": "CollectionPage",
"next": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies?only_other_accounts=true&page=true",
"partOf": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/replies",
"items": []
}
},
"likes": {
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/likes",
"type": "Collection",
"totalItems": 26
},
"shares": {
"id": "https://mastodon.social/users/gwynnion/statuses/115345489087257171/shares",
"type": "Collection",
"totalItems": 28
}
}

View file

@ -109,4 +109,22 @@ defmodule Pleroma.Web.ActivityPub.MRF.InlineQuotePolicyTest do
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
# Mastodon uses p tags instead of span in their quote posts
# URLs in quoteUri and post content are already mismatched
test "skips objects which already have an .inline-quote p" do
object = File.read!("test/fixtures/quote_post/mastodon_quote_post.json") |> Jason.decode!()
# Normally the ObjectValidator will fix this before it reaches MRF
object = Map.put(object, "quoteUrl", object["quoteUri"])
activity = %{
"type" => "Create",
"actor" => "https://mastodon.social/users/gwynnion",
"object" => object
}
{:ok, filtered} = InlineQuotePolicy.filter(activity)
assert filtered == activity
end
end