From 997551bac9fc8189f40675c2ff0b312c78b2ba59 Mon Sep 17 00:00:00 2001
From: Mark Felder <feld@feld.me>
Date: Mon, 19 Dec 2022 14:40:08 -0500
Subject: [PATCH] Fix TwitterCard meta tags
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

TwitterCard meta tags are supposed to use the attributes "name" and "content".
OpenGraph tags use the attributes "property" and "content".

Twitter itself is smart enough to detect broken meta tags and discover the TwitterCard
using "property" and "content", but other platforms that only implement parsing of TwitterCards
and not OpenGraph may fail to correctly detect the tags as they're under the wrong attributes.

> "Open Graph protocol also specifies the use of property and content attributes for markup while
> Twitter cards use name and content. Twitter’s parser will fall back to using property and content,
> so there is no need to modify existing Open Graph protocol markup if it already exists." [0]

[0] https://developer.twitter.com/en/docs/twitter-for-websites/cards/guides/getting-started
---
 .../web/metadata/providers/twitter_card.ex    | 43 +++++++-------
 .../metadata/providers/twitter_card_test.exs  | 56 +++++++++----------
 2 files changed, 49 insertions(+), 50 deletions(-)

diff --git a/lib/pleroma/web/metadata/providers/twitter_card.ex b/lib/pleroma/web/metadata/providers/twitter_card.ex
index 79183df86..b2497d14e 100644
--- a/lib/pleroma/web/metadata/providers/twitter_card.ex
+++ b/lib/pleroma/web/metadata/providers/twitter_card.ex
@@ -20,12 +20,12 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
 
     [
       title_tag(user),
-      {:meta, [property: "twitter:description", content: scrubbed_content], []}
+      {:meta, [name: "twitter:description", content: scrubbed_content], []}
     ] ++
       if attachments == [] or Metadata.activity_nsfw?(object) do
         [
           image_tag(user),
-          {:meta, [property: "twitter:card", content: "summary"], []}
+          {:meta, [name: "twitter:card", content: "summary"], []}
         ]
       else
         attachments
@@ -37,20 +37,19 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
     with truncated_bio = Utils.scrub_html_and_truncate(user.bio) do
       [
         title_tag(user),
-        {:meta, [property: "twitter:description", content: truncated_bio], []},
+        {:meta, [name: "twitter:description", content: truncated_bio], []},
         image_tag(user),
-        {:meta, [property: "twitter:card", content: "summary"], []}
+        {:meta, [name: "twitter:card", content: "summary"], []}
       ]
     end
   end
 
   defp title_tag(user) do
-    {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []}
+    {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []}
   end
 
   def image_tag(user) do
-    {:meta, [property: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))],
-     []}
+    {:meta, [name: "twitter:image", content: MediaProxy.preview_url(User.avatar_url(user))], []}
   end
 
   defp build_attachments(id, %{data: %{"attachment" => attachments}}) do
@@ -60,10 +59,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
           case Utils.fetch_media_type(@media_types, url["mediaType"]) do
             "audio" ->
               [
-                {:meta, [property: "twitter:card", content: "player"], []},
-                {:meta, [property: "twitter:player:width", content: "480"], []},
-                {:meta, [property: "twitter:player:height", content: "80"], []},
-                {:meta, [property: "twitter:player", content: player_url(id)], []}
+                {:meta, [name: "twitter:card", content: "player"], []},
+                {:meta, [name: "twitter:player:width", content: "480"], []},
+                {:meta, [name: "twitter:player:height", content: "80"], []},
+                {:meta, [name: "twitter:player", content: player_url(id)], []}
                 | acc
               ]
 
@@ -74,10 +73,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
             # workaround.
             "image" ->
               [
-                {:meta, [property: "twitter:card", content: "summary_large_image"], []},
+                {:meta, [name: "twitter:card", content: "summary_large_image"], []},
                 {:meta,
                  [
-                   property: "twitter:player",
+                   name: "twitter:player",
                    content: MediaProxy.url(url["href"])
                  ], []}
                 | acc
@@ -90,14 +89,14 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
               width = url["width"] || 480
 
               [
-                {:meta, [property: "twitter:card", content: "player"], []},
-                {:meta, [property: "twitter:player", content: player_url(id)], []},
-                {:meta, [property: "twitter:player:width", content: "#{width}"], []},
-                {:meta, [property: "twitter:player:height", content: "#{height}"], []},
-                {:meta, [property: "twitter:player:stream", content: MediaProxy.url(url["href"])],
+                {:meta, [name: "twitter:card", content: "player"], []},
+                {:meta, [name: "twitter:player", content: player_url(id)], []},
+                {:meta, [name: "twitter:player:width", content: "#{width}"], []},
+                {:meta, [name: "twitter:player:height", content: "#{height}"], []},
+                {:meta, [name: "twitter:player:stream", content: MediaProxy.url(url["href"])],
                  []},
-                {:meta,
-                 [property: "twitter:player:stream:content_type", content: url["mediaType"]], []}
+                {:meta, [name: "twitter:player:stream:content_type", content: url["mediaType"]],
+                 []}
                 | acc
               ]
 
@@ -123,8 +122,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCard do
       !is_nil(url["height"]) && !is_nil(url["width"]) ->
         metadata ++
           [
-            {:meta, [property: "twitter:player:width", content: "#{url["width"]}"], []},
-            {:meta, [property: "twitter:player:height", content: "#{url["height"]}"], []}
+            {:meta, [name: "twitter:player:width", content: "#{url["width"]}"], []},
+            {:meta, [name: "twitter:player:height", content: "#{url["height"]}"], []}
           ]
 
       true ->
diff --git a/test/pleroma/web/metadata/providers/twitter_card_test.exs b/test/pleroma/web/metadata/providers/twitter_card_test.exs
index 5d7ad08ef..731447094 100644
--- a/test/pleroma/web/metadata/providers/twitter_card_test.exs
+++ b/test/pleroma/web/metadata/providers/twitter_card_test.exs
@@ -22,10 +22,10 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
     res = TwitterCard.build_tags(%{user: user})
 
     assert res == [
-             {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
-             {:meta, [property: "twitter:description", content: "born 19 March 1994"], []},
-             {:meta, [property: "twitter:image", content: avatar_url], []},
-             {:meta, [property: "twitter:card", content: "summary"], []}
+             {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
+             {:meta, [name: "twitter:description", content: "born 19 March 1994"], []},
+             {:meta, [name: "twitter:image", content: avatar_url], []},
+             {:meta, [name: "twitter:card", content: "summary"], []}
            ]
   end
 
@@ -47,11 +47,11 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
     result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
 
     assert [
-             {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
-             {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
-             {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
+             {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
+             {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
+             {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
               []},
-             {:meta, [property: "twitter:card", content: "summary"], []}
+             {:meta, [name: "twitter:card", content: "summary"], []}
            ] == result
   end
 
@@ -73,15 +73,15 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
     result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
 
     assert [
-             {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
+             {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
              {:meta,
               [
-                property: "twitter:description",
+                name: "twitter:description",
                 content: "Public service announcement on caffeine consumption"
               ], []},
-             {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
+             {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
               []},
-             {:meta, [property: "twitter:card", content: "summary"], []}
+             {:meta, [name: "twitter:card", content: "summary"], []}
            ] == result
   end
 
@@ -123,11 +123,11 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
     result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
 
     assert [
-             {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
-             {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
-             {:meta, [property: "twitter:image", content: "http://localhost:4001/images/avi.png"],
+             {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
+             {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
+             {:meta, [name: "twitter:image", content: "http://localhost:4001/images/avi.png"],
               []},
-             {:meta, [property: "twitter:card", content: "summary"], []}
+             {:meta, [name: "twitter:card", content: "summary"], []}
            ] == result
   end
 
@@ -179,26 +179,26 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
     result = TwitterCard.build_tags(%{object: note, user: user, activity_id: activity.id})
 
     assert [
-             {:meta, [property: "twitter:title", content: Utils.user_name_string(user)], []},
-             {:meta, [property: "twitter:description", content: "pleroma in a nutshell"], []},
-             {:meta, [property: "twitter:card", content: "summary_large_image"], []},
-             {:meta, [property: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
-             {:meta, [property: "twitter:player:width", content: "1280"], []},
-             {:meta, [property: "twitter:player:height", content: "1024"], []},
-             {:meta, [property: "twitter:card", content: "player"], []},
+             {:meta, [name: "twitter:title", content: Utils.user_name_string(user)], []},
+             {:meta, [name: "twitter:description", content: "pleroma in a nutshell"], []},
+             {:meta, [name: "twitter:card", content: "summary_large_image"], []},
+             {:meta, [name: "twitter:player", content: "https://pleroma.gov/tenshi.png"], []},
+             {:meta, [name: "twitter:player:width", content: "1280"], []},
+             {:meta, [name: "twitter:player:height", content: "1024"], []},
+             {:meta, [name: "twitter:card", content: "player"], []},
              {:meta,
               [
-                property: "twitter:player",
+                name: "twitter:player",
                 content: Router.Helpers.o_status_url(Endpoint, :notice_player, activity.id)
               ], []},
-             {:meta, [property: "twitter:player:width", content: "800"], []},
-             {:meta, [property: "twitter:player:height", content: "600"], []},
+             {:meta, [name: "twitter:player:width", content: "800"], []},
+             {:meta, [name: "twitter:player:height", content: "600"], []},
              {:meta,
               [
-                property: "twitter:player:stream",
+                name: "twitter:player:stream",
                 content: "https://pleroma.gov/about/juche.webm"
               ], []},
-             {:meta, [property: "twitter:player:stream:content_type", content: "video/webm"], []}
+             {:meta, [name: "twitter:player:stream:content_type", content: "video/webm"], []}
            ] == result
   end
 end