From 441cd77966f10bede1a6d0ca57acb9dee2ea3b1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?nicole=20miko=C5=82ajczyk?= Date: Sat, 24 Jan 2026 11:55:00 +0100 Subject: [PATCH] Support `indexable` for use by Mastodon search MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: nicole mikołajczyk --- changelog.d/mastodon-indexable.add | 1 + lib/pleroma/user.ex | 7 +++++-- lib/pleroma/web/activity_pub/activity_pub.ex | 3 ++- lib/pleroma/web/activity_pub/views/user_view.ex | 6 ++++-- .../web/api_spec/operations/account_operation.ex | 8 +++++++- lib/pleroma/web/api_spec/schemas/account.ex | 1 + .../mastodon_api/controllers/account_controller.ex | 3 ++- lib/pleroma/web/mastodon_api/views/account_view.ex | 1 + .../20260123213700_add_indexable_to_users.exs | 13 +++++++++++++ priv/static/schemas/litepub-0.1.jsonld | 1 + .../web/mastodon_api/views/account_view_test.exs | 2 ++ 11 files changed, 39 insertions(+), 7 deletions(-) create mode 100644 changelog.d/mastodon-indexable.add create mode 100644 priv/repo/migrations/20260123213700_add_indexable_to_users.exs diff --git a/changelog.d/mastodon-indexable.add b/changelog.d/mastodon-indexable.add new file mode 100644 index 0000000000..1d90a1a3fe --- /dev/null +++ b/changelog.d/mastodon-indexable.add @@ -0,0 +1 @@ +Support `indexable` for use by Mastodon search diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 75da41da9b..df906fcca7 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -162,6 +162,7 @@ defmodule Pleroma.User do field(:birthday, :date) field(:show_birthday, :boolean, default: false) field(:language, :string) + field(:indexable, :boolean, default: true) embeds_one( :notification_settings, @@ -534,7 +535,8 @@ defmodule Pleroma.User do :accepts_chat_messages, :pinned_objects, :birthday, - :show_birthday + :show_birthday, + :indexable ] ) |> cast(params, [:name], empty_values: []) @@ -597,7 +599,8 @@ defmodule Pleroma.User do :accepts_chat_messages, :disclose_client, :birthday, - :show_birthday + :show_birthday, + :indexable ] ) |> validate_min_age() diff --git a/lib/pleroma/web/activity_pub/activity_pub.ex b/lib/pleroma/web/activity_pub/activity_pub.ex index e58e3dd57d..587f625dd5 100644 --- a/lib/pleroma/web/activity_pub/activity_pub.ex +++ b/lib/pleroma/web/activity_pub/activity_pub.ex @@ -1692,7 +1692,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do birthday: birthday, show_birthday: show_birthday, pinned_objects: pinned_objects, - nickname: nickname + nickname: nickname, + indexable: Map.get(data, "indexable", true) } end diff --git a/lib/pleroma/web/activity_pub/views/user_view.ex b/lib/pleroma/web/activity_pub/views/user_view.ex index 4362db3247..7432ef52ea 100644 --- a/lib/pleroma/web/activity_pub/views/user_view.ex +++ b/lib/pleroma/web/activity_pub/views/user_view.ex @@ -59,7 +59,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do "publicKeyPem" => public_key }, "endpoints" => endpoints, - "invisible" => User.invisible?(user) + "invisible" => User.invisible?(user), + "indexable" => user.indexable } |> Map.merge(Utils.make_json_ld_header()) end @@ -129,7 +130,8 @@ defmodule Pleroma.Web.ActivityPub.UserView do "alsoKnownAs" => user.also_known_as, "vcard:bday" => birthday, "webfinger" => "acct:#{User.full_nickname(user)}", - "published" => Pleroma.Web.CommonAPI.Utils.to_masto_date(user.inserted_at) + "published" => Pleroma.Web.CommonAPI.Utils.to_masto_date(user.inserted_at), + "indexable" => user.indexable } |> Map.merge( maybe_make_image( diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 07eb9328b5..52799cbc3c 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -861,6 +861,11 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do type: :string, nullable: true, description: "Header image description." + }, + indexable: %Schema{ + allOf: [BooleanLike], + nullable: true, + description: "Whether public posts should be searchable to anyone (used by software like Mastodon)." } }, example: %{ @@ -883,7 +888,8 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do discoverable: false, actor_type: "Person", show_birthday: false, - birthday: "2001-02-12" + birthday: "2001-02-12", + indexable: true } } end diff --git a/lib/pleroma/web/api_spec/schemas/account.ex b/lib/pleroma/web/api_spec/schemas/account.ex index 7d0b83afee..696d73e44d 100644 --- a/lib/pleroma/web/api_spec/schemas/account.ex +++ b/lib/pleroma/web/api_spec/schemas/account.ex @@ -37,6 +37,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do statuses_count: %Schema{type: :integer}, url: %Schema{type: :string, format: :uri}, username: %Schema{type: :string}, + indexable: %Schema{type: :boolean}, pleroma: %Schema{ type: :object, properties: %{ diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 6dc731ed47..40f3fac361 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -202,7 +202,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do :allow_following_move, :also_known_as, :accepts_chat_messages, - :show_birthday + :show_birthday, + :indexable ] |> Enum.reduce(%{}, fn key, acc -> Maps.put_if_present(acc, key, params[key], &{:ok, Params.truthy_param?(&1)}) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index a7d994593c..fd48e3c5fa 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -308,6 +308,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do } }, last_status_at: last_status_at, + indexable: user.indexable, # Pleroma extensions # Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub diff --git a/priv/repo/migrations/20260123213700_add_indexable_to_users.exs b/priv/repo/migrations/20260123213700_add_indexable_to_users.exs new file mode 100644 index 0000000000..1a8d652475 --- /dev/null +++ b/priv/repo/migrations/20260123213700_add_indexable_to_users.exs @@ -0,0 +1,13 @@ +# Pleroma: A lightweight social networking server +# Copyright © 2017-2026 Pleroma Authors +# SPDX-License-Identifier: AGPL-3.0-only + +defmodule Pleroma.Repo.Migrations.AddIndexableToUsers do + use Ecto.Migration + + def change do + alter table(:users) do + add(:indexable, :boolean, default: true, null: false) + end + end +end diff --git a/priv/static/schemas/litepub-0.1.jsonld b/priv/static/schemas/litepub-0.1.jsonld index 3569165a40..b85a0e9b1f 100644 --- a/priv/static/schemas/litepub-0.1.jsonld +++ b/priv/static/schemas/litepub-0.1.jsonld @@ -13,6 +13,7 @@ "@type": "@id" }, "discoverable": "toot:discoverable", + "indexable": "toot:indexable", "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", "capabilities": "litepub:capabilities", "ostatus": "http://ostatus.org#", diff --git a/test/pleroma/web/mastodon_api/views/account_view_test.exs b/test/pleroma/web/mastodon_api/views/account_view_test.exs index bd151cc617..593706060b 100644 --- a/test/pleroma/web/mastodon_api/views/account_view_test.exs +++ b/test/pleroma/web/mastodon_api/views/account_view_test.exs @@ -78,6 +78,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do }, fqn: "shp@shitposter.club", last_status_at: user.last_status_at |> NaiveDateTime.to_date() |> Date.to_iso8601(), + indexable: true, pleroma: %{ ap_id: user.ap_id, also_known_as: ["https://shitposter.zone/users/shp"], @@ -343,6 +344,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do }, fqn: "shp@shitposter.club", last_status_at: nil, + indexable: true, pleroma: %{ ap_id: user.ap_id, also_known_as: [],