@@ -184,6 +184,7 @@ Additional parameters can be added to the JSON body/Form data: | |||||
- `pleroma_settings_store` - Opaque user settings to be saved on the backend. | - `pleroma_settings_store` - Opaque user settings to be saved on the backend. | ||||
- `skip_thread_containment` - if true, skip filtering out broken threads | - `skip_thread_containment` - if true, skip filtering out broken threads | ||||
- `allow_following_move` - if true, allows automatically follow moved following accounts | - `allow_following_move` - if true, allows automatically follow moved following accounts | ||||
- `also_known_as` - array of ActivityPub IDs, needed for following move | |||||
- `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset. | - `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset. | ||||
- `discoverable` - if true, discovery of this account in search results and other services is allowed. | - `discoverable` - if true, discovery of this account in search results and other services is allowed. | ||||
- `actor_type` - the type of this account. | - `actor_type` - the type of this account. | ||||
@@ -570,23 +570,3 @@ Emoji reactions work a lot like favourites do. They make it possible to react to | |||||
{"name": "😀", "count": 2, "me": true, "accounts": [{"id" => "xyz.."...}, {"id" => "zyx..."}]} | {"name": "😀", "count": 2, "me": true, "accounts": [{"id" => "xyz.."...}, {"id" => "zyx..."}]} | ||||
] | ] | ||||
``` | ``` | ||||
# Account aliases | |||||
Set and delete ActivityPub aliases for follower move. | |||||
## `POST /api/v1/pleroma/accounts/ap_aliases` | |||||
### Add account aliases | |||||
* Method: `POST` | |||||
* Authentication: required | |||||
* Params: | |||||
* `aliases`: array of ActivityPub IDs to add | |||||
* Response: JSON, the user's account | |||||
## `DELETE /api/v1/pleroma/accounts/ap_aliases` | |||||
### Delete account aliases | |||||
* Method: `DELETE` | |||||
* Authentication: required | |||||
* Params: | |||||
* `aliases`: array of ActivityPub IDs to delete | |||||
* Response: JSON, the user's account |
@@ -96,7 +96,6 @@ defmodule Pleroma.User do | |||||
field(:keys, :string) | field(:keys, :string) | ||||
field(:public_key, :string) | field(:public_key, :string) | ||||
field(:ap_id, :string) | field(:ap_id, :string) | ||||
field(:ap_aliases, {:array, :string}, default: []) | |||||
field(:avatar, :map, default: %{}) | field(:avatar, :map, default: %{}) | ||||
field(:local, :boolean, default: true) | field(:local, :boolean, default: true) | ||||
field(:follower_address, :string) | field(:follower_address, :string) | ||||
@@ -486,6 +485,7 @@ defmodule Pleroma.User do | |||||
:hide_follows_count, | :hide_follows_count, | ||||
:hide_favorites, | :hide_favorites, | ||||
:allow_following_move, | :allow_following_move, | ||||
:also_known_as, | |||||
:background, | :background, | ||||
:show_role, | :show_role, | ||||
:skip_thread_containment, | :skip_thread_containment, | ||||
@@ -494,12 +494,12 @@ defmodule Pleroma.User do | |||||
:pleroma_settings_store, | :pleroma_settings_store, | ||||
:discoverable, | :discoverable, | ||||
:actor_type, | :actor_type, | ||||
:also_known_as, | |||||
:accepts_chat_messages | :accepts_chat_messages | ||||
] | ] | ||||
) | ) | ||||
|> unique_constraint(:nickname) | |> unique_constraint(:nickname) | ||||
|> validate_format(:nickname, local_nickname_regex()) | |> validate_format(:nickname, local_nickname_regex()) | ||||
|> validate_also_known_as() | |||||
|> validate_length(:bio, max: bio_limit) | |> validate_length(:bio, max: bio_limit) | ||||
|> validate_length(:name, min: 1, max: name_limit) | |> validate_length(:name, min: 1, max: name_limit) | ||||
|> validate_inclusion(:actor_type, ["Person", "Service"]) | |> validate_inclusion(:actor_type, ["Person", "Service"]) | ||||
@@ -2387,36 +2387,11 @@ defmodule Pleroma.User do | |||||
|> Map.put(:fields, fields) | |> Map.put(:fields, fields) | ||||
end | end | ||||
def add_aliases(%User{} = user, aliases) when is_list(aliases) do | |||||
alias_set = | |||||
(user.ap_aliases ++ aliases) | |||||
|> MapSet.new() | |||||
|> MapSet.to_list() | |||||
user | |||||
|> change(%{ap_aliases: alias_set}) | |||||
|> validate_ap_aliases() | |||||
|> Repo.update() | |||||
end | |||||
def delete_aliases(%User{} = user, aliases) when is_list(aliases) do | |||||
alias_set = | |||||
user.ap_aliases | |||||
|> MapSet.new() | |||||
|> MapSet.difference(MapSet.new(aliases)) | |||||
|> MapSet.to_list() | |||||
user | |||||
|> change(%{ap_aliases: alias_set}) | |||||
|> validate_ap_aliases() | |||||
|> Repo.update() | |||||
end | |||||
defp validate_ap_aliases(changeset) do | |||||
validate_change(changeset, :ap_aliases, fn :ap_aliases, ap_aliases -> | |||||
case Enum.all?(ap_aliases, fn a -> Regex.match?(@url_regex, a) end) do | |||||
defp validate_also_known_as(changeset) do | |||||
validate_change(changeset, :also_known_as, fn :also_known_as, also_known_as -> | |||||
case Enum.all?(also_known_as, fn a -> Regex.match?(@url_regex, a) end) do | |||||
true -> [] | true -> [] | ||||
false -> [ap_aliases: "Invalid ap_id format. Must be a URL."] | |||||
false -> [also_known_as: "Invalid ap_id format. Must be a URL."] | |||||
end | end | ||||
end) | end) | ||||
end | end | ||||
@@ -597,6 +597,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
nullable: true, | nullable: true, | ||||
description: "Allows automatically follow moved following accounts" | description: "Allows automatically follow moved following accounts" | ||||
}, | }, | ||||
also_known_as: %Schema{ | |||||
type: :array, | |||||
items: %Schema{type: :string}, | |||||
nullable: true, | |||||
description: "List of alternate ActivityPub IDs" | |||||
}, | |||||
pleroma_background_image: %Schema{ | pleroma_background_image: %Schema{ | ||||
type: :string, | type: :string, | ||||
nullable: true, | nullable: true, | ||||
@@ -627,6 +633,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do | |||||
pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}}, | pleroma_settings_store: %{"pleroma-fe" => %{"key" => "val"}}, | ||||
skip_thread_containment: false, | skip_thread_containment: false, | ||||
allow_following_move: false, | allow_following_move: false, | ||||
also_known_as: ["https://foo.bar/users/foo"], | |||||
discoverable: false, | discoverable: false, | ||||
actor_type: "Person" | actor_type: "Person" | ||||
} | } | ||||
@@ -4,8 +4,6 @@ | |||||
defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | ||||
alias OpenApiSpex.Operation | alias OpenApiSpex.Operation | ||||
alias OpenApiSpex.Schema | |||||
alias Pleroma.Web.ApiSpec.Schemas.Account | |||||
alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship | alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship | ||||
alias Pleroma.Web.ApiSpec.Schemas.ApiError | alias Pleroma.Web.ApiSpec.Schemas.ApiError | ||||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID | alias Pleroma.Web.ApiSpec.Schemas.FlakeID | ||||
@@ -89,54 +87,10 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | |||||
} | } | ||||
end | end | ||||
def add_aliases_operation do | |||||
%Operation{ | |||||
tags: ["Accounts"], | |||||
summary: "Add ActivityPub aliases", | |||||
operationId: "PleromaAPI.AccountController.add_aliases", | |||||
requestBody: request_body("Parameters", alias_request(), required: true), | |||||
security: [%{"oAuth" => ["write:accounts"]}], | |||||
responses: %{ | |||||
200 => Operation.response("Account", "application/json", Account), | |||||
403 => Operation.response("Forbidden", "application/json", ApiError) | |||||
} | |||||
} | |||||
end | |||||
def delete_aliases_operation do | |||||
%Operation{ | |||||
tags: ["Accounts"], | |||||
summary: "Delete ActivityPub aliases", | |||||
operationId: "PleromaAPI.AccountController.delete_aliases", | |||||
requestBody: request_body("Parameters", alias_request(), required: true), | |||||
security: [%{"oAuth" => ["write:accounts"]}], | |||||
responses: %{ | |||||
200 => Operation.response("Account", "application/json", Account) | |||||
} | |||||
} | |||||
end | |||||
defp id_param do | defp id_param do | ||||
Operation.parameter(:id, :path, FlakeID, "Account ID", | Operation.parameter(:id, :path, FlakeID, "Account ID", | ||||
example: "9umDrYheeY451cQnEe", | example: "9umDrYheeY451cQnEe", | ||||
required: true | required: true | ||||
) | ) | ||||
end | end | ||||
defp alias_request do | |||||
%Schema{ | |||||
title: "AccountAliasRequest", | |||||
description: "POST body for adding/deleting AP aliases", | |||||
type: :object, | |||||
properties: %{ | |||||
aliases: %Schema{ | |||||
type: :array, | |||||
items: %Schema{type: :string} | |||||
} | |||||
}, | |||||
example: %{ | |||||
"aliases" => ["https://beepboop.social/users/beep", "https://mushroom.kingdom/users/toad"] | |||||
} | |||||
} | |||||
end | |||||
end | end |
@@ -41,7 +41,7 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Account do | |||||
type: :object, | type: :object, | ||||
properties: %{ | properties: %{ | ||||
ap_id: %Schema{type: :string}, | ap_id: %Schema{type: :string}, | ||||
ap_aliases: %Schema{type: :array, items: %Schema{type: :string}}, | |||||
also_known_as: %Schema{type: :array, items: %Schema{type: :string}}, | |||||
allow_following_move: %Schema{ | allow_following_move: %Schema{ | ||||
type: :boolean, | type: :boolean, | ||||
description: "whether the user allows automatically follow moved following accounts" | description: "whether the user allows automatically follow moved following accounts" | ||||
@@ -186,6 +186,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
:show_role, | :show_role, | ||||
:skip_thread_containment, | :skip_thread_containment, | ||||
:allow_following_move, | :allow_following_move, | ||||
:also_known_as, | |||||
:discoverable, | :discoverable, | ||||
:accepts_chat_messages | :accepts_chat_messages | ||||
] | ] | ||||
@@ -210,6 +211,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||||
if bot, do: {:ok, "Service"}, else: {:ok, "Person"} | if bot, do: {:ok, "Service"}, else: {:ok, "Person"} | ||||
end) | end) | ||||
|> Maps.put_if_present(:actor_type, params[:actor_type]) | |> Maps.put_if_present(:actor_type, params[:actor_type]) | ||||
|> Maps.put_if_present(:also_known_as, params[:also_known_as]) | |||||
# What happens here: | # What happens here: | ||||
# | # | ||||
@@ -267,7 +267,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do | |||||
# Pleroma extension | # Pleroma extension | ||||
pleroma: %{ | pleroma: %{ | ||||
ap_id: user.ap_id, | ap_id: user.ap_id, | ||||
ap_aliases: user.ap_aliases, | |||||
also_known_as: user.also_known_as, | |||||
confirmation_pending: user.confirmation_pending, | confirmation_pending: user.confirmation_pending, | ||||
tags: user.tags, | tags: user.tags, | ||||
hide_followers_count: user.hide_followers_count, | hide_followers_count: user.hide_followers_count, | ||||
@@ -39,11 +39,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
%{scopes: ["read:favourites"], fallback: :proceed_unauthenticated} when action == :favourites | %{scopes: ["read:favourites"], fallback: :proceed_unauthenticated} when action == :favourites | ||||
) | ) | ||||
plug( | |||||
OAuthScopesPlug, | |||||
%{scopes: ["write:accounts"]} when action in [:add_aliases, :delete_aliases] | |||||
) | |||||
plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend) | plug(RateLimiter, [name: :account_confirmation_resend] when action == :confirmation_resend) | ||||
plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe]) | plug(:assign_account_by_id when action in [:favourites, :subscribe, :unsubscribe]) | ||||
@@ -112,24 +107,4 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||||
{:error, message} -> json_response(conn, :forbidden, %{error: message}) | {:error, message} -> json_response(conn, :forbidden, %{error: message}) | ||||
end | end | ||||
end | end | ||||
@doc "POST /api/v1/pleroma/accounts/ap_aliases" | |||||
def add_aliases(%{assigns: %{user: user}, body_params: %{aliases: aliases}} = conn, _params) | |||||
when is_list(aliases) do | |||||
with {:ok, user} <- User.add_aliases(user, aliases) do | |||||
render(conn, "show.json", user: user) | |||||
else | |||||
{:error, message} -> json_response(conn, :forbidden, %{error: message}) | |||||
end | |||||
end | |||||
@doc "DELETE /api/v1/pleroma/accounts/ap_aliases" | |||||
def delete_aliases(%{assigns: %{user: user}, body_params: %{aliases: aliases}} = conn, _params) | |||||
when is_list(aliases) do | |||||
with {:ok, user} <- User.delete_aliases(user, aliases) do | |||||
render(conn, "show.json", user: user) | |||||
else | |||||
{:error, message} -> json_response(conn, :forbidden, %{error: message}) | |||||
end | |||||
end | |||||
end | end |
@@ -345,9 +345,6 @@ defmodule Pleroma.Web.Router do | |||||
post("/accounts/:id/subscribe", AccountController, :subscribe) | post("/accounts/:id/subscribe", AccountController, :subscribe) | ||||
post("/accounts/:id/unsubscribe", AccountController, :unsubscribe) | post("/accounts/:id/unsubscribe", AccountController, :unsubscribe) | ||||
post("/accounts/ap_aliases", AccountController, :add_aliases) | |||||
delete("/accounts/ap_aliases", AccountController, :delete_aliases) | |||||
end | end | ||||
post("/accounts/confirmation_resend", AccountController, :confirmation_resend) | post("/accounts/confirmation_resend", AccountController, :confirmation_resend) | ||||
@@ -59,10 +59,7 @@ defmodule Pleroma.Web.WebFinger do | |||||
end | end | ||||
defp gather_aliases(%User{} = user) do | defp gather_aliases(%User{} = user) do | ||||
user.ap_aliases | |||||
|> MapSet.new() | |||||
|> MapSet.put(user.ap_id) | |||||
|> MapSet.to_list() | |||||
[user.ap_id] ++ user.also_known_as | |||||
end | end | ||||
def represent_user(user, "JSON") do | def represent_user(user, "JSON") do | ||||
@@ -78,6 +75,10 @@ defmodule Pleroma.Web.WebFinger do | |||||
def represent_user(user, "XML") do | def represent_user(user, "XML") do | ||||
{:ok, user} = User.ensure_keys_present(user) | {:ok, user} = User.ensure_keys_present(user) | ||||
aliases = | |||||
gather_aliases(user) | |||||
|> Enum.map(fn the_alias -> {:Alias, the_alias} end) | |||||
links = | links = | ||||
gather_links(user) | gather_links(user) | ||||
|> Enum.map(fn link -> {:Link, link} end) | |> Enum.map(fn link -> {:Link, link} end) | ||||
@@ -86,9 +87,8 @@ defmodule Pleroma.Web.WebFinger do | |||||
:XRD, | :XRD, | ||||
%{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"}, | %{xmlns: "http://docs.oasis-open.org/ns/xri/xrd-1.0"}, | ||||
[ | [ | ||||
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"}, | |||||
{:Alias, user.ap_id} | |||||
] ++ links | |||||
{:Subject, "acct:#{user.nickname}@#{Pleroma.Web.Endpoint.host()}"} | |||||
] ++ aliases ++ links | |||||
} | } | ||||
|> XmlBuilder.to_doc() | |> XmlBuilder.to_doc() | ||||
end | end | ||||
@@ -1,9 +0,0 @@ | |||||
defmodule Pleroma.Repo.Migrations.AddAliasesToUsers do | |||||
use Ecto.Migration | |||||
def change do | |||||
alter table(:users) do | |||||
add(:ap_aliases, {:array, :string}, default: []) | |||||
end | |||||
end | |||||
end |
@@ -2024,48 +2024,4 @@ defmodule Pleroma.UserTest do | |||||
assert User.avatar_url(user, no_default: true) == nil | assert User.avatar_url(user, no_default: true) == nil | ||||
end | end | ||||
test "add_aliases/2" do | |||||
user = insert(:user) | |||||
aliases = [ | |||||
"https://gleasonator.com/users/alex", | |||||
"https://gleasonator.com/users/alex", | |||||
"https://animalliberation.social/users/alex" | |||||
] | |||||
{:ok, user} = User.add_aliases(user, aliases) | |||||
assert user.ap_aliases == [ | |||||
"https://animalliberation.social/users/alex", | |||||
"https://gleasonator.com/users/alex" | |||||
] | |||||
end | |||||
test "add_aliases/2 with invalid alias" do | |||||
user = insert(:user) | |||||
{:error, _} = User.add_aliases(user, ["invalid_alias"]) | |||||
{:error, _} = User.add_aliases(user, ["http://still_invalid"]) | |||||
{:error, _} = User.add_aliases(user, ["http://validalias.com/users/dude", "invalid_alias"]) | |||||
end | |||||
test "delete_aliases/2" do | |||||
user = | |||||
insert(:user, | |||||
ap_aliases: [ | |||||
"https://animalliberation.social/users/alex", | |||||
"https://benis.social/users/benis", | |||||
"https://gleasonator.com/users/alex" | |||||
] | |||||
) | |||||
aliases = ["https://benis.social/users/benis"] | |||||
{:ok, user} = User.delete_aliases(user, aliases) | |||||
assert user.ap_aliases == [ | |||||
"https://animalliberation.social/users/alex", | |||||
"https://gleasonator.com/users/alex" | |||||
] | |||||
end | |||||
end | end |
@@ -216,6 +216,16 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController.UpdateCredentialsTest do | |||||
assert user_data["display_name"] == "markorepairs" | assert user_data["display_name"] == "markorepairs" | ||||
end | end | ||||
test "updates the user's AKAs", %{conn: conn} do | |||||
conn = | |||||
patch(conn, "/api/v1/accounts/update_credentials", %{ | |||||
"also_known_as" => ["https://mushroom.kingdom/users/mario"] | |||||
}) | |||||
assert user_data = json_response_and_validate_schema(conn, 200) | |||||
assert user_data["pleroma"]["also_known_as"] == ["https://mushroom.kingdom/users/mario"] | |||||
end | |||||
test "updates the user's avatar", %{user: user, conn: conn} do | test "updates the user's avatar", %{user: user, conn: conn} do | ||||
new_avatar = %Plug.Upload{ | new_avatar = %Plug.Upload{ | ||||
content_type: "image/jpg", | content_type: "image/jpg", | ||||
@@ -38,7 +38,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
inserted_at: ~N[2017-08-15 15:47:06.597036], | inserted_at: ~N[2017-08-15 15:47:06.597036], | ||||
emoji: %{"karjalanpiirakka" => "/file.png"}, | emoji: %{"karjalanpiirakka" => "/file.png"}, | ||||
raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"", | raw_bio: "valid html. a\nb\nc\nd\nf '&<>\"", | ||||
ap_aliases: ["https://shitposter.zone/users/shp"] | |||||
also_known_as: ["https://shitposter.zone/users/shp"] | |||||
}) | }) | ||||
expected = %{ | expected = %{ | ||||
@@ -78,7 +78,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
}, | }, | ||||
pleroma: %{ | pleroma: %{ | ||||
ap_id: user.ap_id, | ap_id: user.ap_id, | ||||
ap_aliases: ["https://shitposter.zone/users/shp"], | |||||
also_known_as: ["https://shitposter.zone/users/shp"], | |||||
background_image: "https://example.com/images/asuka_hospital.png", | background_image: "https://example.com/images/asuka_hospital.png", | ||||
favicon: | favicon: | ||||
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", | "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", | ||||
@@ -174,7 +174,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do | |||||
}, | }, | ||||
pleroma: %{ | pleroma: %{ | ||||
ap_id: user.ap_id, | ap_id: user.ap_id, | ||||
ap_aliases: [], | |||||
also_known_as: [], | |||||
background_image: nil, | background_image: nil, | ||||
favicon: | favicon: | ||||
"https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", | "https://shitposter.club/plugins/Qvitter/img/gnusocial-favicons/favicon-16x16.png", | ||||
@@ -281,33 +281,4 @@ defmodule Pleroma.Web.PleromaAPI.AccountControllerTest do | |||||
assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404) | assert %{"error" => "Record not found"} = json_response_and_validate_schema(conn, 404) | ||||
end | end | ||||
end | end | ||||
describe "aliases controllers" do | |||||
setup do: oauth_access(["write:accounts"]) | |||||
test "adds aliases", %{conn: conn} do | |||||
aliases = ["https://gleasonator.com/users/alex"] | |||||
conn = | |||||
conn | |||||
|> put_req_header("content-type", "application/json") | |||||
|> post("/api/v1/pleroma/accounts/ap_aliases", %{"aliases" => aliases}) | |||||
assert %{"pleroma" => %{"ap_aliases" => res}} = json_response_and_validate_schema(conn, 200) | |||||
assert Enum.count(res) == 1 | |||||
end | |||||
test "deletes aliases", %{conn: conn, user: user} do | |||||
aliases = ["https://gleasonator.com/users/alex"] | |||||
User.add_aliases(user, aliases) | |||||
conn = | |||||
conn | |||||
|> put_req_header("content-type", "application/json") | |||||
|> delete("/api/v1/pleroma/accounts/ap_aliases", %{"aliases" => aliases}) | |||||
assert %{"pleroma" => %{"ap_aliases" => res}} = json_response_and_validate_schema(conn, 200) | |||||
assert Enum.count(res) == 0 | |||||
end | |||||
end | |||||
end | end |
@@ -33,7 +33,7 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do | |||||
user = | user = | ||||
insert(:user, | insert(:user, | ||||
ap_id: "https://hyrule.world/users/zelda", | ap_id: "https://hyrule.world/users/zelda", | ||||
ap_aliases: ["https://mushroom.kingdom/users/toad"] | |||||
also_known_as: ["https://mushroom.kingdom/users/toad"] | |||||
) | ) | ||||
response = | response = | ||||
@@ -61,14 +61,20 @@ defmodule Pleroma.Web.WebFinger.WebFingerControllerTest do | |||||
end | end | ||||
test "Webfinger XML" do | test "Webfinger XML" do | ||||
user = insert(:user) | |||||
user = | |||||
insert(:user, | |||||
ap_id: "https://hyrule.world/users/zelda", | |||||
also_known_as: ["https://mushroom.kingdom/users/toad"] | |||||
) | |||||
response = | response = | ||||
build_conn() | build_conn() | ||||
|> put_req_header("accept", "application/xrd+xml") | |> put_req_header("accept", "application/xrd+xml") | ||||
|> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") | |> get("/.well-known/webfinger?resource=acct:#{user.nickname}@localhost") | ||||
|> response(200) | |||||
assert response(response, 200) | |||||
assert response =~ "<Alias>https://hyrule.world/users/zelda</Alias>" | |||||
assert response =~ "<Alias>https://mushroom.kingdom/users/toad</Alias>" | |||||
end | end | ||||
test "it returns 404 when user isn't found (XML)" do | test "it returns 404 when user isn't found (XML)" do | ||||