fix(user): update the known user when fetched from a display URL

A fetch from a display URL (e.g. https://host/@user) returns the
actor with its canonical id. make_user_from_ap_id looked the user up
by the fetch URL, did not find it and tried to insert a duplicate.
Look the user up by the fetched id.

Based on Akkoma 48b3a3579.
This commit is contained in:
Lain Soykaf 2026-10-27 21:46:45 +04:00
commit f22caeff53
No known key found for this signature in database
3 changed files with 31 additions and 2 deletions

View file

@ -0,0 +1 @@
Update the known user instead of failing when an actor is fetched from a display URL

View file

@ -2055,11 +2055,12 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do
def enqueue_pin_fetches(_), do: nil
def make_user_from_ap_id(ap_id, additional \\ []) do
user = User.get_cached_by_ap_id(ap_id)
with {:ok, data} <- fetch_and_prepare_user_from_ap_id(ap_id, additional) do
enqueue_pin_fetches(data)
# the fetched actor's id differs from ap_id when it was fetched from a display URL
user = User.get_cached_by_ap_id(data.ap_id)
if user do
user
|> User.remote_user_changeset(data)

View file

@ -269,6 +269,33 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
refute User.get_by_ap_id(ap_id)
end
test "updates the known user when fetched from a display URL" do
ap_id = "https://example.com/users/lain"
display_url = "https://example.com/@lain"
user = insert(:user, local: false, ap_id: ap_id, nickname: "lain@example.com")
user_data =
"test/fixtures/users_mock/user.json"
|> File.read!()
|> String.replace("{{nickname}}", "lain")
|> Jason.decode!()
|> Map.merge(%{"featured" => nil, "name" => "new name"})
|> Jason.encode!()
Tesla.Mock.mock(fn %{method: :get, url: url} when url in [ap_id, display_url] ->
%Tesla.Env{
status: 200,
body: user_data,
headers: [{"content-type", "application/activity+json"}]
}
end)
assert {:ok, %User{id: id, name: "new name"}} =
ActivityPub.make_user_from_ap_id(display_url)
assert id == user.id
end
test "fetches user featured collection" do
ap_id = "https://example.com/users/lain"