|> fix_replies()
|> fix_source()
|> fix_misskey_content()
- |> Transmogrifier.fix_quote_url()
|> Transmogrifier.fix_attachments()
|> Transmogrifier.fix_emoji()
|> Transmogrifier.fix_content_map()
|> fix_attachments()
|> fix_context()
|> fix_in_reply_to(options)
+ |> fix_quote_url(options)
|> fix_emoji()
|> fix_tag()
|> fix_content_map()
def fix_in_reply_to(object, _options), do: object
+ def fix_quote_url(object, options \\ [])
+
+ def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
+ when not is_nil(quote_url) do
+ depth = (options[:depth] || 0) + 1
+
+ if Federator.allowed_thread_distance?(depth) do
+ with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
+ %Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
+ object
+ |> Map.put("quoteUri", quoted_object.data["id"])
+ else
+ e ->
+ Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
+ object
+ end
+ else
+ object
+ end
+ end
+
+ # Soapbox
+ def fix_quote_url(%{"quoteUrl" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUri", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ # Old Fedibird (bug)
+ # https://github.com/fedibird/mastodon/issues/9
+ def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUri", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
+ object
+ |> Map.put("quoteUri", quote_url)
+ |> fix_quote_url(options)
+ end
+
+ def fix_quote_url(object, _), do: object
+
defp prepare_in_reply_to(in_reply_to) do
cond do
is_bitstring(in_reply_to) ->
|> strip_internal_fields()
|> fix_type(fetch_options)
|> fix_in_reply_to(fetch_options)
+ |> fix_quote_url(fetch_options)
data = Map.put(data, "object", object)
options = Keyword.put(options, :local, false)
defp strip_internal_tags(object), do: object
- def fix_quote_url(object, options \\ [])
-
- def fix_quote_url(%{"quoteUri" => quote_url} = object, options)
- when not is_nil(quote_url) do
- with {:ok, quoted_object} <- get_obj_helper(quote_url, options),
- %Activity{} <- Activity.get_create_by_object_ap_id(quoted_object.data["id"]) do
- Map.put(object, "quoteUri", quoted_object.data["id"])
- else
- e ->
- Logger.warn("Couldn't fetch #{inspect(quote_url)}, error: #{inspect(e)}")
- object
- end
- end
-
- # Soapbox
- def fix_quote_url(%{"quoteUrl" => quote_url} = object, options) do
- object
- |> Map.put("quoteUri", quote_url)
- |> fix_quote_url(options)
- end
-
- # Old Fedibird (bug)
- # https://github.com/fedibird/mastodon/issues/9
- def fix_quote_url(%{"quoteURL" => quote_url} = object, options) do
- object
- |> Map.put("quoteUri", quote_url)
- |> fix_quote_url(options)
- end
-
- def fix_quote_url(%{"_misskey_quote" => quote_url} = object, options) do
- object
- |> Map.put("quoteUri", quote_url)
- |> fix_quote_url(options)
- end
-
- def fix_quote_url(object, _), do: object
-
def perform(:user_upgrade, user) do
# we pass a fake user so that the followers collection is stripped away
old_follower_address = User.ap_followers(%User{nickname: user.nickname})
--- /dev/null
+{
+ "@context": [
+ "https://www.w3.org/ns/activitystreams",
+ "https://w3id.org/security/v1",
+ {
+ "manuallyApprovesFollowers": "as:manuallyApprovesFollowers",
+ "sensitive": "as:sensitive",
+ "Hashtag": "as:Hashtag",
+ "quoteUrl": "as:quoteUrl",
+ "toot": "http://joinmastodon.org/ns#",
+ "Emoji": "toot:Emoji",
+ "featured": "toot:featured",
+ "discoverable": "toot:discoverable",
+ "schema": "http://schema.org#",
+ "PropertyValue": "schema:PropertyValue",
+ "value": "schema:value",
+ "misskey": "https://misskey-hub.net/ns#",
+ "_misskey_content": "misskey:_misskey_content",
+ "_misskey_quote": "misskey:_misskey_quote",
+ "_misskey_reaction": "misskey:_misskey_reaction",
+ "_misskey_votes": "misskey:_misskey_votes",
+ "_misskey_talk": "misskey:_misskey_talk",
+ "isCat": "misskey:isCat",
+ "vcard": "http://www.w3.org/2006/vcard/ns#"
+ }
+ ],
+ "id": "https://misskey.io/notes/934gok3482",
+ "type": "Note",
+ "attributedTo": "https://misskey.io/users/93492q0ip0",
+ "summary": null,
+ "content": "<p><span>i quompt u</p>",
+ "_misskey_content": "i quompt u",
+ "source": {
+ "content": "i quompt u",
+ "mediaType": "text/x.misskeymarkdown"
+ },
+ "_misskey_quote": "https://misskey.io/notes/934gok3482",
+ "quoteUrl": "https://misskey.io/notes/934gok3482",
+ "published": "2022-07-25T15:21:48.208Z",
+ "to": [
+ "https://www.w3.org/ns/activitystreams#Public"
+ ],
+ "cc": [],
+ "inReplyTo": null,
+ "attachment": [],
+ "sensitive": false,
+ "tag": []
+}
}
} = ArticleNotePageValidator.cast_and_validate(note)
end
-
- test "a misskey quote should work", _ do
- Tesla.Mock.mock(fn %{
- method: :get,
- url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
- } ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/quoted_status.json"),
- headers: HttpRequestMock.activitypub_object_headers()
- }
- end)
-
- insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
- insert(:user, %{ap_id: "https://example.com/users/user"})
-
- note =
- "test/fixtures/misskey/quote.json"
- |> File.read!()
- |> Jason.decode!()
-
- %{
- valid?: true,
- changes: %{
- quoteUri: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
- }
- } = ArticleNotePageValidator.cast_and_validate(note)
- end
-
- test "a fedibird quote should work", _ do
- Tesla.Mock.mock(fn %{
- method: :get,
- url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
- } ->
- %Tesla.Env{
- status: 200,
- body: File.read!("test/fixtures/quoted_status.json"),
- headers: HttpRequestMock.activitypub_object_headers()
- }
- end)
-
- insert(:user, %{ap_id: "https://fedibird.com/users/akkoma_ap_integration_tester"})
- insert(:user, %{ap_id: "https://example.com/users/user"})
-
- note =
- "test/fixtures/fedibird/quote.json"
- |> File.read!()
- |> Jason.decode!()
-
- %{
- valid?: true,
- changes: %{
- quoteUri: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
- }
- } = ArticleNotePageValidator.cast_and_validate(note)
- end
end
end
}
]
end
+
+ describe "fix_quote_url/1" do
+ test "a misskey quote should work", _ do
+ Tesla.Mock.mock(fn %{
+ method: :get,
+ url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/quoted_status.json"),
+ headers: HttpRequestMock.activitypub_object_headers()
+ }
+ end)
+
+ insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
+ insert(:user, %{ap_id: "https://example.com/users/user"})
+
+ note =
+ "test/fixtures/misskey/quote.json"
+ |> File.read!()
+ |> Jason.decode!()
+
+ %{"quoteUri" => "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"} =
+ Transmogrifier.fix_quote_url(note)
+ end
+
+ test "a fedibird quote should work", _ do
+ Tesla.Mock.mock(fn %{
+ method: :get,
+ url: "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/quoted_status.json"),
+ headers: HttpRequestMock.activitypub_object_headers()
+ }
+ end)
+
+ insert(:user, %{ap_id: "https://fedibird.com/users/akkoma_ap_integration_tester"})
+ insert(:user, %{ap_id: "https://example.com/users/user"})
+
+ note =
+ "test/fixtures/fedibird/quote.json"
+ |> File.read!()
+ |> Jason.decode!()
+
+ %{
+ "quoteUri" => "https://example.com/objects/43479e20-c0f8-4f49-bf7f-13fab8234924"
+ } = Transmogrifier.fix_quote_url(note)
+ end
+
+ test "quote fetching should stop after n levels", _ do
+ clear_config([:instance, :federation_incoming_replies_max_depth], 1)
+
+ Tesla.Mock.mock(fn %{
+ method: :get,
+ url: "https://misskey.io/notes/934gok3482"
+ } ->
+ %Tesla.Env{
+ status: 200,
+ body: File.read!("test/fixtures/misskey/recursive_quote.json"),
+ headers: HttpRequestMock.activitypub_object_headers()
+ }
+ end)
+
+ insert(:user, %{ap_id: "https://misskey.io/users/93492q0ip0"})
+
+ note =
+ "test/fixtures/misskey/recursive_quote.json"
+ |> File.read!()
+ |> Jason.decode!()
+
+ %{
+ "quoteUri" => "https://misskey.io/notes/934gok3482"
+ } = Transmogrifier.fix_quote_url(note)
+ end
+ end
end