diff --git a/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex
new file mode 100644
index 0000000000..9c610a64b8
--- /dev/null
+++ b/lib/pleroma/ecto_type/activity_pub/object_validators/map_of_string.ex
@@ -0,0 +1,29 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfString do
+ use Ecto.Type
+
+ def type, do: :map
+
+ def cast(object) when is_map(object) do
+ data =
+ object
+ |> Enum.reduce(%{}, fn
+ {lang, value}, acc when is_binary(lang) and is_binary(value) ->
+ Map.put(acc, lang, value)
+
+ _, acc ->
+ acc
+ end)
+
+ {:ok, data}
+ end
+
+ def cast(_), do: :error
+
+ def dump(data), do: {:ok, data}
+
+ def load(data), do: {:ok, data}
+end
diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
index 01960da831..c96717e78f 100644
--- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
@@ -15,6 +15,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
field(:type, :string, default: "Link")
field(:mediaType, ObjectValidators.MIME, default: "application/octet-stream")
field(:name, :string)
+ field(:nameMap, ObjectValidators.MapOfString)
field(:blurhash, :string)
embeds_many :url, UrlObjectValidator, primary_key: false do
@@ -44,7 +45,7 @@ def changeset(struct, data) do
|> fix_url()
struct
- |> cast(data, [:id, :type, :mediaType, :name, :blurhash])
+ |> cast(data, [:id, :type, :mediaType, :name, :nameMap, :blurhash])
|> cast_embed(:url, with: &url_changeset/2, required: true)
end
diff --git a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
index 22cf0cc05b..b626ccca6f 100644
--- a/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/common_fields.ex
@@ -50,7 +50,9 @@ defmacro status_object_fields do
embeds_many(:tag, TagValidator)
field(:name, :string)
+ field(:nameMap, ObjectValidators.MapOfString)
field(:summary, :string)
+ field(:summaryMap, ObjectValidators.MapOfString)
field(:context, :string)
diff --git a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex
index 8d7f7b9fa6..bbd1b25cc2 100644
--- a/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/question_options_validator.ex
@@ -7,10 +7,13 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do
import Ecto.Changeset
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators
+
@primary_key false
embedded_schema do
field(:name, :string)
+ field(:nameMap, ObjectValidators.MapOfString)
embeds_one :replies, Replies, primary_key: false do
field(:totalItems, :integer)
@@ -22,7 +25,7 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator do
def changeset(struct, data) do
struct
- |> cast(data, [:name, :type])
+ |> cast(data, [:name, :nameMap, :type])
|> cast_embed(:replies, with: &replies_changeset/2)
|> validate_inclusion(:type, ["Note"])
|> validate_required([:name, :type])
diff --git a/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs
new file mode 100644
index 0000000000..aecf482e3a
--- /dev/null
+++ b/test/pleroma/ecto_type/activity_pub/object_validators/map_of_string_test.exs
@@ -0,0 +1,43 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfStringTest do
+ alias Pleroma.EctoType.ActivityPub.ObjectValidators.MapOfString
+ use Pleroma.DataCase, async: true
+
+ test "it validates" do
+ data = %{
+ "en-US" => "mew mew",
+ "en-GB" => "meow meow"
+ }
+
+ assert {:ok, ^data} = MapOfString.cast(data)
+ end
+
+ test "it validates empty strings" do
+ data = %{
+ "en-US" => "mew mew",
+ "en-GB" => ""
+ }
+
+ assert {:ok, ^data} = MapOfString.cast(data)
+ end
+
+ test "it ignores non-strings within the map" do
+ data = %{
+ "en-US" => "mew mew",
+ "en-GB" => 123
+ }
+
+ assert {:ok, validated_data} = MapOfString.cast(data)
+
+ assert validated_data == %{"en-US" => "mew mew"}
+ end
+
+ test "it complains with non-map data" do
+ assert :error = MapOfString.cast("mew")
+ assert :error = MapOfString.cast(["mew"])
+ assert :error = MapOfString.cast([%{"en-US" => "mew"}])
+ end
+end
diff --git a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
index 511637e1d3..dedd389511 100644
--- a/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/article_note_page_validator_test.exs
@@ -37,6 +37,31 @@ test "a note from factory validates" do
note = insert(:note)
%{valid?: true} = ArticleNotePageValidator.cast_and_validate(note.data)
end
+
+ test "Note with contentMap and summaryMap", %{note: note} do
+ summary_map = %{
+ "en-US" => "mew",
+ "en-GB" => "meow"
+ }
+
+ content_map = %{
+ "en-US" => "mew mew",
+ "en-GB" => "meow meow"
+ }
+
+ note =
+ note
+ |> Map.put("summaryMap", summary_map)
+ |> Map.put("contentMap", content_map)
+
+ assert %{
+ valid?: true,
+ changes: %{
+ summaryMap: ^summary_map,
+ contentMap: ^content_map
+ }
+ } = ArticleNotePageValidator.cast_and_validate(note)
+ end
end
describe "Note with history" do
diff --git a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
index a615c1d9ac..e433e9cd9e 100644
--- a/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
+++ b/test/pleroma/web/activity_pub/object_validators/attachment_validator_test.exs
@@ -42,6 +42,26 @@ test "works with honkerific attachments" do
assert attachment.mediaType == "application/octet-stream"
end
+ test "works with nameMap" do
+ attachment_data = %{
+ "mediaType" => "",
+ "name" => "",
+ "nameMap" => %{
+ "en-US" => "mew mew",
+ "en-GB" => "meow meow"
+ },
+ "summary" => "298p3RG7j27tfsZ9RQ.jpg",
+ "type" => "Document",
+ "url" => "https://honk.tedunangst.com/d/298p3RG7j27tfsZ9RQ.jpg"
+ }
+
+ assert {:ok, attachment} =
+ AttachmentValidator.cast_and_validate(attachment_data)
+ |> Ecto.Changeset.apply_action(:insert)
+
+ assert attachment.nameMap == attachment_data["nameMap"]
+ end
+
test "works with an unknown but valid mime type" do
attachment = %{
"mediaType" => "x-custom/x-type",
diff --git a/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs b/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs
new file mode 100644
index 0000000000..87a0bafa07
--- /dev/null
+++ b/test/pleroma/web/activity_pub/object_validators/question_options_validator_test.exs
@@ -0,0 +1,27 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2022 Pleroma Authors
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidatorTest do
+ use Pleroma.DataCase, async: true
+
+ alias Pleroma.Web.ActivityPub.ObjectValidators.QuestionOptionsValidator
+
+ describe "Validates Question options" do
+ test "" do
+ name_map = %{
+ "en-US" => "mew",
+ "en-GB" => "meow"
+ }
+
+ data = %{
+ "type" => "Note",
+ "name" => "mew",
+ "nameMap" => name_map
+ }
+
+ assert %{valid?: true, changes: %{nameMap: ^name_map}} =
+ QuestionOptionsValidator.changeset(%QuestionOptionsValidator{}, data)
+ end
+ end
+end