Merge branch 'develop' into accept-tags-2.5

This commit is contained in:
silverpill 2023-02-27 23:10:36 +00:00
commit 98b9c1bcb1
46 changed files with 451 additions and 92 deletions

View File

@ -12,6 +12,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Fixed ### Fixed
- rel="me" was missing its cache
### Removed ### Removed
## 2.5.0 - 2022-12-23 ## 2.5.0 - 2022-12-23

View File

@ -1,4 +1,8 @@
FROM elixir:1.11.4-alpine as build ARG ELIXIR_VER=1.11.4
ARG ERLANG_VER=24.2.1
ARG ALPINE_VER=3.17.0
FROM hexpm/elixir:${ELIXIR_VER}-erlang-${ERLANG_VER}-alpine-${ALPINE_VER} as build
COPY . . COPY . .
@ -12,7 +16,7 @@ RUN apk add git gcc g++ musl-dev make cmake file-dev &&\
mkdir release &&\ mkdir release &&\
mix release --path release mix release --path release
FROM alpine FROM alpine:${ALPINE_VER}
ARG BUILD_DATE ARG BUILD_DATE
ARG VCS_REF ARG VCS_REF

View File

@ -1052,6 +1052,15 @@
description: description:
"Minimum required age (in days) for users to create account. Only used if birthday is required.", "Minimum required age (in days) for users to create account. Only used if birthday is required.",
suggestions: [6570] suggestions: [6570]
},
%{
key: :languages,
type: {:list, :string},
description:
"Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes.",
suggestions: [
"en"
]
} }
] ]
}, },

View File

@ -6,7 +6,70 @@ defmodule Mix.Tasks.Pleroma.OpenapiSpec do
def run([path]) do def run([path]) do
# Load Pleroma application to get version info # Load Pleroma application to get version info
Application.load(:pleroma) Application.load(:pleroma)
spec = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
File.write(path, spec) spec_json = Pleroma.Web.ApiSpec.spec(server_specific: false) |> Jason.encode!()
# to get rid of the structs
spec_regened = spec_json |> Jason.decode!()
check_specs!(spec_regened)
File.write(path, spec_json)
end
defp check_specs!(spec) do
with :ok <- check_specs(spec) do
:ok
else
{_, errors} ->
IO.puts(IO.ANSI.format([:red, :bright, "Spec check failed, errors:"]))
Enum.map(errors, &IO.puts/1)
raise "Spec check failed"
end
end
def check_specs(spec) do
errors =
spec["paths"]
|> Enum.flat_map(fn {path, %{} = endpoints} ->
Enum.map(
endpoints,
fn {method, endpoint} ->
with :ok <- check_endpoint(spec, endpoint) do
:ok
else
error ->
"#{endpoint["operationId"]} (#{method} #{path}): #{error}"
end
end
)
|> Enum.reject(fn res -> res == :ok end)
end)
if errors == [] do
:ok
else
{:error, errors}
end
end
defp check_endpoint(spec, endpoint) do
valid_tags = available_tags(spec)
with {_, [_ | _] = tags} <- {:tags, endpoint["tags"]},
{_, []} <- {:unavailable, Enum.reject(tags, &(&1 in valid_tags))} do
:ok
else
{:tags, _} ->
"No tags specified"
{:unavailable, tags} ->
"Tags #{inspect(tags)} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
end
end
defp available_tags(spec) do
spec["x-tagGroups"]
|> Enum.flat_map(fn %{"tags" => tags} -> tags end)
end end
end end

View File

@ -209,7 +209,8 @@ defp cachex_children do
build_cachex("chat_message_id_idempotency_key", build_cachex("chat_message_id_idempotency_key",
expiration: chat_message_id_idempotency_key_expiration(), expiration: chat_message_id_idempotency_key_expiration(),
limit: 500_000 limit: 500_000
) ),
build_cachex("rel_me", limit: 2500)
] ]
end end

View File

@ -178,6 +178,7 @@ defp exclude_filtered(query, user) do
from([_n, a, o] in query, from([_n, a, o] in query,
where: where:
fragment("not(?->>'content' ~* ?)", o.data, ^regex) or fragment("not(?->>'content' ~* ?)", o.data, ^regex) or
fragment("?->>'content' is null", o.data) or
fragment("?->>'actor' = ?", o.data, ^user.ap_id) fragment("?->>'actor' = ?", o.data, ^user.ap_id)
) )
end end
@ -679,7 +680,7 @@ def skip?(
cond do cond do
opts[:type] == "poll" -> false opts[:type] == "poll" -> false
user.ap_id == actor -> false user.ap_id == actor -> false
!User.following?(follower, user) -> true !User.following?(user, follower) -> true
true -> false true -> false
end end
end end

View File

@ -33,7 +33,10 @@ defp read_when_empty(current_description, _, _) when is_binary(current_descripti
defp read_when_empty(_, file, tag) do defp read_when_empty(_, file, tag) do
try do try do
{tag_content, 0} = {tag_content, 0} =
System.cmd("exiftool", ["-b", "-s3", tag, file], stderr_to_stdout: true, parallelism: true) System.cmd("exiftool", ["-b", "-s3", tag, file],
stderr_to_stdout: false,
parallelism: true
)
tag_content = String.trim(tag_content) tag_content = String.trim(tag_content)

View File

@ -14,6 +14,7 @@ defmodule Pleroma.Upload.Filter.Exiftool.StripLocation do
# Formats not compatible with exiftool at this time # Formats not compatible with exiftool at this time
def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop} def filter(%Pleroma.Upload{content_type: "image/heic"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop} def filter(%Pleroma.Upload{content_type: "image/webp"}), do: {:ok, :noop}
def filter(%Pleroma.Upload{content_type: "image/svg" <> _}), do: {:ok, :noop}
def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do def filter(%Pleroma.Upload{tempfile: file, content_type: "image" <> _}) do
try do try do

View File

@ -31,7 +31,7 @@ def extract_report_info(
defp make_fake_activity(act, user) do defp make_fake_activity(act, user) do
%Activity{ %Activity{
id: "pleroma:fake", id: "pleroma:fake:#{act["id"]}",
data: %{ data: %{
"actor" => user.ap_id, "actor" => user.ap_id,
"type" => "Create", "type" => "Create",

View File

@ -95,7 +95,8 @@ def spec(opts \\ []) do
"Relays", "Relays",
"Report managment", "Report managment",
"Status administration", "Status administration",
"User administration" "User administration",
"Announcement management"
] ]
}, },
%{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]}, %{"name" => "Applications", "tags" => ["Applications", "Push subscriptions"]},
@ -110,10 +111,12 @@ def spec(opts \\ []) do
"Follow requests", "Follow requests",
"Mascot", "Mascot",
"Markers", "Markers",
"Notifications" "Notifications",
"Filters",
"Settings"
] ]
}, },
%{"name" => "Instance", "tags" => ["Custom emojis"]}, %{"name" => "Instance", "tags" => ["Custom emojis", "Instance misc"]},
%{"name" => "Messaging", "tags" => ["Chats", "Conversations"]}, %{"name" => "Messaging", "tags" => ["Chats", "Conversations"]},
%{ %{
"name" => "Statuses", "name" => "Statuses",
@ -125,10 +128,21 @@ def spec(opts \\ []) do
"Retrieve status information", "Retrieve status information",
"Scheduled statuses", "Scheduled statuses",
"Search", "Search",
"Status actions" "Status actions",
"Media attachments"
] ]
}, },
%{"name" => "Miscellaneous", "tags" => ["Emoji packs", "Reports", "Suggestions"]} %{
"name" => "Miscellaneous",
"tags" => [
"Emoji packs",
"Reports",
"Suggestions",
"Announcements",
"Remote interaction",
"Others"
]
}
] ]
} }
} }

View File

@ -461,7 +461,7 @@ def blocks_operation do
def lookup_operation do def lookup_operation do
%Operation{ %Operation{
tags: ["Account lookup"], tags: ["Retrieve account information"],
summary: "Find a user by nickname", summary: "Find a user by nickname",
operationId: "AccountController.lookup", operationId: "AccountController.lookup",
parameters: [ parameters: [

View File

@ -17,7 +17,7 @@ def open_api_operation(action) do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Announcement managment"], tags: ["Announcement management"],
summary: "Retrieve a list of announcements", summary: "Retrieve a list of announcements",
operationId: "AdminAPI.AnnouncementController.index", operationId: "AdminAPI.AnnouncementController.index",
security: [%{"oAuth" => ["admin:read"]}], security: [%{"oAuth" => ["admin:read"]}],
@ -46,7 +46,7 @@ def index_operation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Announcement managment"], tags: ["Announcement management"],
summary: "Display one announcement", summary: "Display one announcement",
operationId: "AdminAPI.AnnouncementController.show", operationId: "AdminAPI.AnnouncementController.show",
security: [%{"oAuth" => ["admin:read"]}], security: [%{"oAuth" => ["admin:read"]}],
@ -69,7 +69,7 @@ def show_operation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Announcement managment"], tags: ["Announcement management"],
summary: "Delete one announcement", summary: "Delete one announcement",
operationId: "AdminAPI.AnnouncementController.delete", operationId: "AdminAPI.AnnouncementController.delete",
security: [%{"oAuth" => ["admin:write"]}], security: [%{"oAuth" => ["admin:write"]}],
@ -92,7 +92,7 @@ def delete_operation do
def create_operation do def create_operation do
%Operation{ %Operation{
tags: ["Announcement managment"], tags: ["Announcement management"],
summary: "Create one announcement", summary: "Create one announcement",
operationId: "AdminAPI.AnnouncementController.create", operationId: "AdminAPI.AnnouncementController.create",
security: [%{"oAuth" => ["admin:write"]}], security: [%{"oAuth" => ["admin:write"]}],
@ -107,7 +107,7 @@ def create_operation do
def change_operation do def change_operation do
%Operation{ %Operation{
tags: ["Announcement managment"], tags: ["Announcement management"],
summary: "Change one announcement", summary: "Change one announcement",
operationId: "AdminAPI.AnnouncementController.change", operationId: "AdminAPI.AnnouncementController.change",
security: [%{"oAuth" => ["admin:write"]}], security: [%{"oAuth" => ["admin:write"]}],

View File

@ -70,7 +70,7 @@ def index_operation do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Status adminitration)"], tags: ["Status administration"],
summary: "Get status", summary: "Get status",
operationId: "AdminAPI.StatusController.show", operationId: "AdminAPI.StatusController.show",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
@ -84,7 +84,7 @@ def show_operation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Status adminitration)"], tags: ["Status administration"],
summary: "Change the scope of a status", summary: "Change the scope of a status",
operationId: "AdminAPI.StatusController.update", operationId: "AdminAPI.StatusController.update",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
@ -99,7 +99,7 @@ def update_operation do
def delete_operation do def delete_operation do
%Operation{ %Operation{
tags: ["Status adminitration)"], tags: ["Status administration"],
summary: "Delete status", summary: "Delete status",
operationId: "AdminAPI.StatusController.delete", operationId: "AdminAPI.StatusController.delete",
parameters: [id_param() | admin_api_params()], parameters: [id_param() | admin_api_params()],
@ -143,7 +143,7 @@ def admin_account do
} }
}, },
tags: %Schema{type: :string}, tags: %Schema{type: :string},
is_confirmed: %Schema{type: :string} is_confirmed: %Schema{type: :boolean}
} }
} }
end end

View File

@ -15,7 +15,7 @@ def open_api_operation(action) do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Announcement"], tags: ["Announcements"],
summary: "Retrieve a list of announcements", summary: "Retrieve a list of announcements",
operationId: "MastodonAPI.AnnouncementController.index", operationId: "MastodonAPI.AnnouncementController.index",
security: [%{"oAuth" => []}], security: [%{"oAuth" => []}],
@ -28,7 +28,7 @@ def index_operation do
def mark_read_operation do def mark_read_operation do
%Operation{ %Operation{
tags: ["Announcement"], tags: ["Announcements"],
summary: "Mark one announcement as read", summary: "Mark one announcement as read",
operationId: "MastodonAPI.AnnouncementController.mark_read", operationId: "MastodonAPI.AnnouncementController.mark_read",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],

View File

@ -17,7 +17,7 @@ def open_api_operation(action) do
def index_operation do def index_operation do
%Operation{ %Operation{
tags: ["Directory"], tags: ["Others"],
summary: "Profile directory", summary: "Profile directory",
operationId: "DirectoryController.index", operationId: "DirectoryController.index",
parameters: parameters:

View File

@ -13,7 +13,7 @@ def open_api_operation(action) do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Instance"], tags: ["Instance misc"],
summary: "Retrieve instance information", summary: "Retrieve instance information",
description: "Information about the server", description: "Information about the server",
operationId: "InstanceController.show", operationId: "InstanceController.show",
@ -25,7 +25,7 @@ def show_operation do
def peers_operation do def peers_operation do
%Operation{ %Operation{
tags: ["Instance"], tags: ["Instance misc"],
summary: "Retrieve list of known instances", summary: "Retrieve list of known instances",
operationId: "InstanceController.peers", operationId: "InstanceController.peers",
responses: %{ responses: %{

View File

@ -133,7 +133,11 @@ defp name_param do
defp files_object do defp files_object do
%Schema{ %Schema{
type: :object, type: :object,
additionalProperties: %Schema{type: :string}, additionalProperties: %Schema{
type: :string,
description: "Filename of the emoji",
extensions: %{"x-additionalPropertiesName": "Emoji name"}
},
description: "Object with emoji names as keys and filenames as values" description: "Object with emoji names as keys and filenames as values"
} }
end end

View File

@ -227,13 +227,29 @@ defp ok_response do
defp emoji_packs_response do defp emoji_packs_response do
Operation.response( Operation.response(
"Object with pack names as keys and pack contents as values", "Emoji packs and the count",
"application/json", "application/json",
%Schema{ %Schema{
type: :object, type: :object,
additionalProperties: emoji_pack(), properties: %{
packs: %Schema{
type: :object,
description: "Object with pack names as keys and pack contents as values",
additionalProperties: %Schema{
emoji_pack()
| extensions: %{"x-additionalPropertiesName": "Pack name"}
}
},
count: %Schema{
type: :integer,
description: "Number of emoji packs"
}
},
example: %{ example: %{
"emojos" => emoji_pack().example "packs" => %{
"emojos" => emoji_pack().example
},
"count" => 1
} }
} }
) )
@ -274,7 +290,11 @@ defp emoji_pack do
defp files_object do defp files_object do
%Schema{ %Schema{
type: :object, type: :object,
additionalProperties: %Schema{type: :string}, additionalProperties: %Schema{
type: :string,
description: "Filename",
extensions: %{"x-additionalPropertiesName": "Emoji name"}
},
description: "Object with emoji names as keys and filenames as values" description: "Object with emoji names as keys and filenames as values"
} }
end end

View File

@ -13,7 +13,7 @@ def open_api_operation(action) do
def show_operation do def show_operation do
%Operation{ %Operation{
tags: ["Instance"], tags: ["Instance misc"],
summary: "Retrieve federation status", summary: "Retrieve federation status",
description: "Information about instances deemed unreachable by the server", description: "Information about instances deemed unreachable by the server",
operationId: "PleromaInstances.show", operationId: "PleromaInstances.show",

View File

@ -440,7 +440,7 @@ def bookmarks_operation do
def show_history_operation do def show_history_operation do
%Operation{ %Operation{
tags: ["Retrieve status history"], tags: ["Retrieve status information"],
summary: "Status history", summary: "Status history",
description: "View history of a status", description: "View history of a status",
operationId: "StatusController.show_history", operationId: "StatusController.show_history",
@ -457,7 +457,7 @@ def show_history_operation do
def show_source_operation do def show_source_operation do
%Operation{ %Operation{
tags: ["Retrieve status source"], tags: ["Retrieve status information"],
summary: "Status source", summary: "Status source",
description: "View source of a status", description: "View source of a status",
operationId: "StatusController.show_source", operationId: "StatusController.show_source",
@ -474,7 +474,7 @@ def show_source_operation do
def update_operation do def update_operation do
%Operation{ %Operation{
tags: ["Update status"], tags: ["Status actions"],
summary: "Update status", summary: "Update status",
description: "Change the content of a status", description: "Change the content of a status",
operationId: "StatusController.update", operationId: "StatusController.update",

View File

@ -17,7 +17,7 @@ def open_api_operation(action) do
def emoji_operation do def emoji_operation do
%Operation{ %Operation{
tags: ["Emojis"], tags: ["Custom emojis"],
summary: "List all custom emojis", summary: "List all custom emojis",
operationId: "UtilController.emoji", operationId: "UtilController.emoji",
parameters: [], parameters: [],
@ -30,7 +30,8 @@ def emoji_operation do
properties: %{ properties: %{
image_url: %Schema{type: :string}, image_url: %Schema{type: :string},
tags: %Schema{type: :array, items: %Schema{type: :string}} tags: %Schema{type: :array, items: %Schema{type: :string}}
} },
extensions: %{"x-additionalPropertiesName": "Emoji name"}
}, },
example: %{ example: %{
"firefox" => %{ "firefox" => %{
@ -45,7 +46,7 @@ def emoji_operation do
def frontend_configurations_operation do def frontend_configurations_operation do
%Operation{ %Operation{
tags: ["Configuration"], tags: ["Others"],
summary: "Dump frontend configurations", summary: "Dump frontend configurations",
operationId: "UtilController.frontend_configurations", operationId: "UtilController.frontend_configurations",
parameters: [], parameters: [],
@ -53,7 +54,12 @@ def frontend_configurations_operation do
200 => 200 =>
Operation.response("List", "application/json", %Schema{ Operation.response("List", "application/json", %Schema{
type: :object, type: :object,
additionalProperties: %Schema{type: :object} additionalProperties: %Schema{
type: :object,
description:
"Opaque object representing the instance-wide configuration for the frontend",
extensions: %{"x-additionalPropertiesName": "Frontend name"}
}
}) })
} }
} }
@ -132,7 +138,7 @@ defp change_email_request do
def update_notificaton_settings_operation do def update_notificaton_settings_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Settings"],
summary: "Update Notification Settings", summary: "Update Notification Settings",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.update_notificaton_settings", operationId: "UtilController.update_notificaton_settings",
@ -207,6 +213,7 @@ def captcha_operation do
%Operation{ %Operation{
summary: "Get a captcha", summary: "Get a captcha",
operationId: "UtilController.captcha", operationId: "UtilController.captcha",
tags: ["Others"],
parameters: [], parameters: [],
responses: %{ responses: %{
200 => Operation.response("Success", "application/json", %Schema{type: :object}) 200 => Operation.response("Success", "application/json", %Schema{type: :object})
@ -356,7 +363,7 @@ defp delete_alias_request do
def healthcheck_operation do def healthcheck_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Others"],
summary: "Quick status check on the instance", summary: "Quick status check on the instance",
security: [%{"oAuth" => ["write:accounts"]}], security: [%{"oAuth" => ["write:accounts"]}],
operationId: "UtilController.healthcheck", operationId: "UtilController.healthcheck",
@ -371,7 +378,7 @@ def healthcheck_operation do
def remote_subscribe_operation do def remote_subscribe_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Remote interaction"],
summary: "Remote Subscribe", summary: "Remote Subscribe",
operationId: "UtilController.remote_subscribe", operationId: "UtilController.remote_subscribe",
parameters: [], parameters: [],
@ -381,7 +388,7 @@ def remote_subscribe_operation do
def remote_interaction_operation do def remote_interaction_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Remote interaction"],
summary: "Remote interaction", summary: "Remote interaction",
operationId: "UtilController.remote_interaction", operationId: "UtilController.remote_interaction",
requestBody: request_body("Parameters", remote_interaction_request(), required: true), requestBody: request_body("Parameters", remote_interaction_request(), required: true),
@ -407,7 +414,7 @@ defp remote_interaction_request do
def show_subscribe_form_operation do def show_subscribe_form_operation do
%Operation{ %Operation{
tags: ["Accounts"], tags: ["Remote interaction"],
summary: "Show remote subscribe form", summary: "Show remote subscribe form",
operationId: "UtilController.show_subscribe_form", operationId: "UtilController.show_subscribe_form",
parameters: [], parameters: [],

View File

@ -144,7 +144,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
properties: %{ properties: %{
content: %Schema{ content: %Schema{
type: :object, type: :object,
additionalProperties: %Schema{type: :string}, additionalProperties: %Schema{
type: :string,
description: "Alternate representation in the MIME type specified",
extensions: %{"x-additionalPropertiesName": "MIME type"}
},
description: description:
"A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`" "A map consisting of alternate representations of the `content` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`"
}, },
@ -195,7 +199,11 @@ defmodule Pleroma.Web.ApiSpec.Schemas.Status do
}, },
spoiler_text: %Schema{ spoiler_text: %Schema{
type: :object, type: :object,
additionalProperties: %Schema{type: :string}, additionalProperties: %Schema{
type: :string,
description: "Alternate representation in the MIME type specified",
extensions: %{"x-additionalPropertiesName": "MIME type"}
},
description: description:
"A map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`." "A map consisting of alternate representations of the `spoiler_text` property with the key being it's mimetype. Currently the only alternate representation supported is `text/plain`."
}, },

View File

@ -269,14 +269,11 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
end end
defp normalize_fields_attributes(fields) do defp normalize_fields_attributes(fields) do
if Enum.all?(fields, &is_tuple/1) do if(Enum.all?(fields, &is_tuple/1), do: Enum.map(fields, fn {_, v} -> v end), else: fields)
Enum.map(fields, fn {_, v} -> v end) |> Enum.map(fn
else %{} = field -> %{"name" => field.name, "value" => field.value}
Enum.map(fields, fn field -> field
%{} = field -> %{"name" => field.name, "value" => field.value} end)
field -> field
end)
end
end end
@doc "GET /api/v1/accounts/relationships" @doc "GET /api/v1/accounts/relationships"

View File

@ -27,7 +27,7 @@ def render("show.json", _) do
thumbnail: thumbnail:
URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail)) URI.merge(Pleroma.Web.Endpoint.url(), Keyword.get(instance, :instance_thumbnail))
|> to_string, |> to_string,
languages: ["en"], languages: Keyword.get(instance, :languages, ["en"]),
registrations: Keyword.get(instance, :registrations_open), registrations: Keyword.get(instance, :registrations_open),
approval_required: Keyword.get(instance, :account_approval_required), approval_required: Keyword.get(instance, :account_approval_required),
# Extra (not present in Mastodon): # Extra (not present in Mastodon):

View File

@ -9,17 +9,13 @@ defmodule Pleroma.Web.RelMe do
recv_timeout: 2_000 recv_timeout: 2_000
] ]
if Pleroma.Config.get(:env) == :test do @cachex Pleroma.Config.get([:cachex, :provider], Cachex)
def parse(url) when is_binary(url), do: parse_url(url) def parse(url) when is_binary(url) do
else @cachex.fetch!(:rel_me_cache, url, fn _ ->
@cachex Pleroma.Config.get([:cachex, :provider], Cachex) {:commit, parse_url(url)}
def parse(url) when is_binary(url) do end)
@cachex.fetch!(:rel_me_cache, url, fn _ -> rescue
{:commit, parse_url(url)} e -> {:error, "Cachex error: #{inspect(e)}"}
end)
rescue
e -> {:error, "Cachex error: #{inspect(e)}"}
end
end end
def parse(_), do: {:error, "No URL provided"} def parse(_), do: {:error, "No URL provided"}

10
mix.exs
View File

@ -148,11 +148,9 @@ defp deps do
{:ex_aws, "~> 2.1.6"}, {:ex_aws, "~> 2.1.6"},
{:ex_aws_s3, "~> 2.0"}, {:ex_aws_s3, "~> 2.0"},
{:sweet_xml, "~> 0.7.2"}, {:sweet_xml, "~> 0.7.2"},
{:earmark, "~> 1.4.15"}, {:earmark, "~> 1.4.22"},
{:bbcode_pleroma, "~> 0.2.0"}, {:bbcode_pleroma, "~> 0.2.0"},
{:crypt, {:crypt, "~> 1.0"},
git: "https://github.com/msantos/crypt.git",
ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"},
{:cors_plug, "~> 2.0"}, {:cors_plug, "~> 2.0"},
{:web_push_encryption, "~> 0.3.1"}, {:web_push_encryption, "~> 0.3.1"},
{:swoosh, "~> 1.0"}, {:swoosh, "~> 1.0"},
@ -162,7 +160,7 @@ defp deps do
{:floki, "~> 0.27"}, {:floki, "~> 0.27"},
{:timex, "~> 3.6"}, {:timex, "~> 3.6"},
{:ueberauth, "~> 0.4"}, {:ueberauth, "~> 0.4"},
{:linkify, "~> 0.5.2"}, {:linkify, "~> 0.5.3"},
{:http_signatures, "~> 0.1.1"}, {:http_signatures, "~> 0.1.1"},
{:telemetry, "~> 1.0.0", override: true}, {:telemetry, "~> 1.0.0", override: true},
{:poolboy, "~> 1.5"}, {:poolboy, "~> 1.5"},
@ -196,7 +194,7 @@ defp deps do
{:restarter, path: "./restarter"}, {:restarter, path: "./restarter"},
{:majic, "~> 1.0"}, {:majic, "~> 1.0"},
{:eblurhash, "~> 1.2.2"}, {:eblurhash, "~> 1.2.2"},
{:open_api_spex, "~> 3.10"}, {:open_api_spex, "~> 3.16"},
{:ecto_psql_extras, "~> 0.6"}, {:ecto_psql_extras, "~> 0.6"},
# indirect dependency version override # indirect dependency version override

View File

@ -21,13 +21,13 @@
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"}, "cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"}, "credo": {:hex, :credo, "1.6.7", "323f5734350fd23a456f2688b9430e7d517afb313fbd38671b8a4449798a7854", [:mix], [{:bunt, "~> 0.2.1", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "41e110bfb007f7eda7f897c10bf019ceab9a0b269ce79f015d54b0dcf4fc7dd3"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"}, "crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://github.com/msantos/crypt.git", "f75cd55325e33cbea198fb41fe41871392f8fb76", [ref: "f75cd55325e33cbea198fb41fe41871392f8fb76"]}, "crypt": {:hex, :crypt, "1.0.1", "a3567e1c651a2ec42c6650d9f3ab789e0f12a508c060653a9bbb5fafe60f043c", [:rebar3], [], "hexpm", "968dffe321c7a5d9f9b4577c4a4ff56a1c26d1a8a2270eb22c7636a0b43d3982"},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"}, "custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"}, "db_connection": {:hex, :db_connection, "2.4.2", "f92e79aff2375299a16bcb069a14ee8615c3414863a6fef93156aee8e86c2ff3", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4fe53ca91b99f55ea249693a0229356a08f4d1a7931d8ffa79289b145fe83668"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"}, "deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"earmark": {:hex, :earmark, "1.4.18", "618c4ff1563450d1832b7fb41dc6755e470f91a6fd4c70f350a58b14f64a7db8", [:mix], [{:earmark_parser, ">= 1.4.17", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "57ac3b6da3958ed09c669a9b159e86377fcccda56bacde8a209fa4dcdef52560"}, "earmark": {:hex, :earmark, "1.4.22", "ea3e45c6359446dc308be0a64ce82a03260d973de7d0625a762e6d352ff57958", [:mix], [{:earmark_parser, "~> 1.4.23", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "1caf5145665a42fd76d5317286b0c171861fb1c04f86ab103dde76868814fdfb"},
"earmark_parser": {:hex, :earmark_parser, "1.4.17", "6f3c7e94170377ba45241d394389e800fb15adc5de51d0a3cd52ae766aafd63f", [:mix], [], "hexpm", "f93ac89c9feca61c165b264b5837bf82344d13bebc634cd575cb711e2e342023"}, "earmark_parser": {:hex, :earmark_parser, "1.4.29", "149d50dcb3a93d9f3d6f3ecf18c918fb5a2d3c001b5d3305c926cddfbd33355b", [:mix], [], "hexpm", "4902af1b3eb139016aed210888748db8070b8125c2342ce3dcae4f38dcc63503"},
"eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"}, "eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"},
"ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"}, "ecto": {:hex, :ecto, "3.9.2", "017db3bc786ff64271108522c01a5d3f6ba0aea5c84912cfb0dd73bf13684108", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "21466d5177e09e55289ac7eade579a642578242c7a3a9f91ad5c6583337a9d15"},
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"}, "ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
@ -64,7 +64,7 @@
"joken": {:hex, :joken, "2.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"}, "joken": {:hex, :joken, "2.3.0", "62a979c46f2c81dcb8ddc9150453b60d3757d1ac393c72bb20fc50a7b0827dc6", [:mix], [{:jose, "~> 1.10", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "57b263a79c0ec5d536ac02d569c01e6b4de91bd1cb825625fe90eab4feb7bc1e"},
"jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"}, "jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"},
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"}, "jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
"linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"}, "linkify": {:hex, :linkify, "0.5.3", "5f8143d8f61f5ff08d3aeeff47ef6509492b4948d8f08007fbf66e4d2246a7f2", [:mix], [], "hexpm", "3ef35a1377d47c25506e07c1c005ea9d38d700699d92ee92825f024434258177"},
"majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"}, "majic": {:hex, :majic, "1.0.0", "37e50648db5f5c2ff0c9fb46454d034d11596c03683807b9fb3850676ffdaab3", [:make, :mix], [{:elixir_make, "~> 0.6.1", [hex: :elixir_make, repo: "hexpm", optional: false]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:nimble_pool, "~> 0.2", [hex: :nimble_pool, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "7905858f76650d49695f14ea55cd9aaaee0c6654fa391671d4cf305c275a0a9e"},
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"}, "makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
"makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"}, "makeup_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
@ -83,7 +83,7 @@
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"}, "nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
"nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]}, "nodex": {:git, "https://git.pleroma.social/pleroma/nodex", "cb6730f943cfc6aad674c92161be23a8411f15d1", [ref: "cb6730f943cfc6aad674c92161be23a8411f15d1"]},
"oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"}, "oban": {:hex, :oban, "2.13.4", "b4c4f48f4c89cc01036670eefa28aa9c03d09aadd402655475b936983d597006", [:mix], [{:ecto_sql, "~> 3.6", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.16", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "a7d26f82b409e2d7928fbb75a17716e06ad3f783ebe9af260e3dd23abed7f124"},
"open_api_spex": {:hex, :open_api_spex, "3.10.0", "94e9521ad525b3fcf6dc77da7c45f87fdac24756d4de588cb0816b413e7c1844", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.1", [hex: :poison, repo: "hexpm", optional: true]}], "hexpm", "2dbb2bde3d2b821f06936e8dfaf3284331186556291946d84eeba3750ac28765"}, "open_api_spex": {:hex, :open_api_spex, "3.16.0", "9843af4e87550cd8ac5821b10e4c74f1d51f0d4e3310f824d780614743423b25", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:poison, "~> 3.0 or ~> 4.0 or ~> 5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:ymlr, "~> 2.0 or ~> 3.0", [hex: :ymlr, repo: "hexpm", optional: true]}], "hexpm", "bb0be24a648b73e8fc8cbda17f514b8486262275e8b33e8b5ae66283df972129"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"}, "parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"}, "pbkdf2_elixir": {:hex, :pbkdf2_elixir, "1.2.1", "9cbe354b58121075bd20eb83076900a3832324b7dd171a6895fab57b6bb2752c", [:mix], [{:comeonin, "~> 5.3", [hex: :comeonin, repo: "hexpm", optional: false]}], "hexpm", "d3b40a4a4630f0b442f19eca891fcfeeee4c40871936fed2f68e1c4faa30481f"},
"phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"}, "phoenix": {:hex, :phoenix, "1.6.15", "0a1d96bbc10747fd83525370d691953cdb6f3ccbac61aa01b4acb012474b047d", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0 or ~> 2.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d70ab9fbf6b394755ea88b644d34d79d8b146e490973151f248cacd122d20672"},

View File

@ -6033,3 +6033,15 @@ msgstr ""
msgctxt "config label at :pleroma-:instance > :moderator_privileges" msgctxt "config label at :pleroma-:instance > :moderator_privileges"
msgid "Moderator privileges" msgid "Moderator privileges"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/docs/translator.ex:5
msgctxt "config description at :pleroma-:instance > :languages"
msgid "Languages to be exposed in /api/v1/instance. Should be in the format of BCP47 language codes."
msgstr ""
#, elixir-autogen, elixir-format
#: lib/pleroma/docs/translator.ex:5
msgctxt "config label at :pleroma-:instance > :languages"
msgid "Languages"
msgstr ""

View File

@ -111,7 +111,7 @@ msgid "Can't display this activity"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:337 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334
msgid "Can't find user" msgid "Can't find user"
msgstr "" msgstr ""
@ -236,7 +236,7 @@ msgid "Poll's author can't vote"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:502 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:499
#: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20 #: lib/pleroma/web/mastodon_api/controllers/fallback_controller.ex:20
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:39
#: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51 #: lib/pleroma/web/mastodon_api/controllers/poll_controller.ex:51
@ -558,7 +558,7 @@ msgid "Access denied"
msgstr "" msgstr ""
#, elixir-autogen, elixir-format #, elixir-autogen, elixir-format
#: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:334 #: lib/pleroma/web/mastodon_api/controllers/account_controller.ex:331
msgid "This API requires an authenticated user" msgid "This API requires an authenticated user"
msgstr "" msgstr ""

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

BIN
test/fixtures/image_with_stray_data_after.png vendored Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

View File

@ -0,0 +1,62 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Mix.Tasks.Pleroma.OpenapiSpecTest do
use Pleroma.DataCase, async: true
alias Mix.Tasks.Pleroma.OpenapiSpec
@spec_base %{
"paths" => %{
"/cofe" => %{
"get" => %{
"operationId" => "Some.operation",
"tags" => []
}
},
"/mew" => %{
"post" => %{
"operationId" => "Another.operation",
"tags" => ["mew mew"]
}
}
},
"x-tagGroups" => [
%{
"name" => "mew",
"tags" => ["mew mew", "abc"]
},
%{
"name" => "lol",
"tags" => ["lol lol", "xyz"]
}
]
}
describe "check_specs/1" do
test "Every operation must have a tag" do
assert {:error, ["Some.operation (get /cofe): No tags specified"]} ==
OpenapiSpec.check_specs(@spec_base)
end
test "Every tag must be in tag groups" do
spec =
@spec_base
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "def", "not specified"])
assert {:error,
[
"Some.operation (get /cofe): Tags #{inspect(["def", "not specified"])} not available. Please add it in \"x-tagGroups\" in Pleroma.Web.ApiSpec"
]} == OpenapiSpec.check_specs(spec)
end
test "No errors if ok" do
spec =
@spec_base
|> put_in(["paths", "/cofe", "get", "tags"], ["abc", "mew mew"])
assert :ok == OpenapiSpec.check_specs(spec)
end
end
end

View File

@ -334,6 +334,32 @@ test "it disables notifications from strangers" do
refute Notification.create_notification(activity, followed) refute Notification.create_notification(activity, followed)
end end
test "it disables notifications from non-followees" do
follower = insert(:user)
followed =
insert(:user,
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
CommonAPI.follow(follower, followed)
{:ok, activity} = CommonAPI.post(follower, %{status: "hey @#{followed.nickname}"})
refute Notification.create_notification(activity, followed)
end
test "it allows notifications from followees" do
poster = insert(:user)
receiver =
insert(:user,
notification_settings: %Pleroma.User.NotificationSetting{block_from_strangers: true}
)
CommonAPI.follow(receiver, poster)
{:ok, activity} = CommonAPI.post(poster, %{status: "hey @#{receiver.nickname}"})
assert Notification.create_notification(activity, receiver)
end
test "it doesn't create a notification for user if he is the activity author" do test "it doesn't create a notification for user if he is the activity author" do
activity = insert(:note_activity) activity = insert(:note_activity)
author = User.get_cached_by_ap_id(activity.data["actor"]) author = User.get_cached_by_ap_id(activity.data["actor"])
@ -1225,5 +1251,32 @@ test "it returns notifications about favorites with filtered word", %{user: user
assert length(Notification.for_user(user)) == 1 assert length(Notification.for_user(user)) == 1
end end
test "it returns notifications when related object is without content and filters are defined",
%{user: user} do
followed_user = insert(:user, is_locked: true)
insert(:filter, user: followed_user, phrase: "test", hide: true)
{:ok, _, _, _activity} = CommonAPI.follow(user, followed_user)
refute FollowingRelationship.following?(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
assert %{type: "follow_request"} =
NotificationView.render("show.json", %{
notification: notification,
for: followed_user
})
assert {:ok, _} = CommonAPI.accept_follow_request(user, followed_user)
assert [notification] = Notification.for_user(followed_user)
assert %{type: "follow"} =
NotificationView.render("show.json", %{
notification: notification,
for: followed_user
})
end
end end
end end

View File

@ -42,6 +42,33 @@ test "otherwise returns ImageDescription when present" do
{:ok, :filtered, uploads_after} {:ok, :filtered, uploads_after}
end end
test "Ignores warnings" do
uploads = %Pleroma.Upload{
name: "image_with_imagedescription_and_caption-abstract_and_stray_data_after.png",
content_type: "image/png",
path:
Path.absname(
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
),
tempfile:
Path.absname(
"test/fixtures/image_with_imagedescription_and_caption-abstract_and_stray_data_after.png"
)
}
assert {:ok, :filtered, %{description: "a descriptive white pixel"}} =
Filter.Exiftool.ReadDescription.filter(uploads)
uploads = %Pleroma.Upload{
name: "image_with_stray_data_after.png",
content_type: "image/png",
path: Path.absname("test/fixtures/image_with_stray_data_after.png"),
tempfile: Path.absname("test/fixtures/image_with_stray_data_after.png")
}
assert {:ok, :filtered, %{description: nil}} = Filter.Exiftool.ReadDescription.filter(uploads)
end
test "otherwise returns iptc:Caption-Abstract when present" do test "otherwise returns iptc:Caption-Abstract when present" do
upload = %Pleroma.Upload{ upload = %Pleroma.Upload{
name: "image_with_caption-abstract.jpg", name: "image_with_caption-abstract.jpg",

View File

@ -31,12 +31,19 @@ test "apply exiftool filter" do
refute String.match?(exif_filtered, ~r/GPS/) refute String.match?(exif_filtered, ~r/GPS/)
end end
test "verify webp files are skipped" do test "verify webp, heic, svg files are skipped" do
upload = %Pleroma.Upload{ uploads =
name: "sample.webp", ~w{webp heic svg svg+xml}
content_type: "image/webp" |> Enum.map(fn type ->
} %Pleroma.Upload{
name: "sample.#{type}",
content_type: "image/#{type}"
}
end)
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop} uploads
|> Enum.each(fn upload ->
assert Filter.Exiftool.StripLocation.filter(upload) == {:ok, :noop}
end)
end end
end end

View File

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.User.ImportTest do defmodule Pleroma.User.ImportTest do
alias Pleroma.Repo
alias Pleroma.Tests.ObanHelpers alias Pleroma.Tests.ObanHelpers
alias Pleroma.User alias Pleroma.User

View File

@ -3,7 +3,6 @@
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserSearchTest do defmodule Pleroma.UserSearchTest do
alias Pleroma.Repo
alias Pleroma.User alias Pleroma.User
use Pleroma.DataCase use Pleroma.DataCase

View File

@ -65,7 +65,7 @@ test "it works for incoming unqualified emoji reactions" do
object = Object.get_by_ap_id(data["object"]) object = Object.get_by_ap_id(data["object"])
assert object.data["reaction_count"] == 1 assert object.data["reaction_count"] == 1
assert match?([[emoji, _]], object.data["reactions"]) assert match?([[^emoji, _]], object.data["reactions"])
end end
test "it reject invalid emoji reactions" do test "it reject invalid emoji reactions" do

View File

@ -104,6 +104,7 @@ test "it does not fetch reply-to activities beyond max replies depth limit" do
end end
end end
@tag capture_log: true
test "it does not crash if the object in inReplyTo can't be fetched" do test "it does not crash if the object in inReplyTo can't be fetched" do
data = data =
File.read!("test/fixtures/mastodon-post-activity.json") File.read!("test/fixtures/mastodon-post-activity.json")
@ -723,6 +724,7 @@ test "the standalone note uses its own ID when context is missing" do
assert modified.data["context"] == object.data["id"] assert modified.data["context"] == object.data["id"]
end end
@tag capture_log: true
test "the reply note uses its parent's ID when context is missing and reply is unreachable" do test "the reply note uses its parent's ID when context is missing and reply is unreachable" do
insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8") insert(:user, ap_id: "https://mk.absturztau.be/users/8ozbzjs3o8")

View File

@ -316,6 +316,7 @@ test "create new config setting in db", %{conn: conn} do
assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []} assert Application.get_env(:idna, :key5) == {"string", Pleroma.Captcha.NotReal, []}
end end
@tag capture_log: true
test "save configs setting without explicit key", %{conn: conn} do test "save configs setting without explicit key", %{conn: conn} do
adapter = Application.get_env(:http, :adapter) adapter = Application.get_env(:http, :adapter)
send_user_agent = Application.get_env(:http, :send_user_agent) send_user_agent = Application.get_env(:http, :send_user_agent)

View File

@ -366,6 +366,34 @@ test "returns reports with specified state", %{conn: conn} do
|> json_response_and_validate_schema(:ok) |> json_response_and_validate_schema(:ok)
end end
test "renders content correctly", %{conn: conn} do
[reporter, target_user] = insert_pair(:user)
note = insert(:note, user: target_user, data: %{"content" => "mew 1"})
note2 = insert(:note, user: target_user, data: %{"content" => "mew 2"})
activity = insert(:note_activity, user: target_user, note: note)
activity2 = insert(:note_activity, user: target_user, note: note2)
{:ok, _report} =
CommonAPI.report(reporter, %{
account_id: target_user.id,
comment: "I feel offended",
status_ids: [activity.id, activity2.id]
})
CommonAPI.delete(activity.id, target_user)
CommonAPI.delete(activity2.id, target_user)
response =
conn
|> get(report_path(conn, :index))
|> json_response_and_validate_schema(:ok)
assert [open_report] = response["reports"]
assert %{"statuses" => [s1, s2]} = open_report
assert "mew 1" in [s1["content"], s2["content"]]
assert "mew 2" in [s1["content"], s2["content"]]
end
test "returns 403 when requested by a non-admin" do test "returns 403 when requested by a non-admin" do
user = insert(:user) user = insert(:user)
token = insert(:oauth_token, user: user) token = insert(:oauth_token, user: user)

View File

@ -178,6 +178,10 @@ test "links" do
code = "https://github.com/pragdave/earmark/" code = "https://github.com/pragdave/earmark/"
{result, [], []} = Utils.format_input(code, "text/markdown") {result, [], []} = Utils.format_input(code, "text/markdown")
assert result == ~s[<p><a href="#{code}">#{code}</a></p>] assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
code = "https://github.com/~foo/bar"
{result, [], []} = Utils.format_input(code, "text/markdown")
assert result == ~s[<p><a href="#{code}">#{code}</a></p>]
end end
test "link with local mention" do test "link with local mention" do

View File

@ -518,6 +518,25 @@ test "it de-duplicates tags" do
assert Object.tags(object) == ["2hu"] assert Object.tags(object) == ["2hu"]
end end
test "zwnj is treated as word character" do
user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: "#ساٴين‌س"})
object = Object.normalize(activity, fetch: false)
assert Object.tags(object) == ["ساٴين‌س"]
end
test "double dot in link is allowed" do
user = insert(:user)
text = "https://example.to/something..mp3"
{:ok, activity} = CommonAPI.post(user, %{status: text})
object = Object.normalize(activity, fetch: false)
assert object.data["content"] == "<a href=\"#{text}\" rel=\"ugc\">#{text}</a>"
end
test "it adds emoji in the object" do test "it adds emoji in the object" do
user = insert(:user) user = insert(:user)
{:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"}) {:ok, activity} = CommonAPI.post(user, %{status: ":firefox:"})

View File

@ -92,4 +92,18 @@ test "get peers", %{conn: conn} do
assert ["peer1.com", "peer2.com"] == Enum.sort(result) assert ["peer1.com", "peer2.com"] == Enum.sort(result)
end end
test "instance languages", %{conn: conn} do
assert %{"languages" => ["en"]} =
conn
|> get("/api/v1/instance")
|> json_response_and_validate_schema(200)
clear_config([:instance, :languages], ["aa", "bb"])
assert %{"languages" => ["aa", "bb"]} =
conn
|> get("/api/v1/instance")
|> json_response_and_validate_schema(200)
end
end end

View File

@ -375,7 +375,9 @@ test "updates the user's background, upload_limit, returns a HTTP 413", %{
"pleroma_background_image" => new_background_oversized "pleroma_background_image" => new_background_oversized
}) })
assert user_response = json_response_and_validate_schema(res, 413) assert %{"error" => "File is too large"} == json_response_and_validate_schema(res, 413)
user = Repo.get(User, user.id)
assert user.background == %{} assert user.background == %{}
clear_config([:instance, :upload_limit], upload_limit) clear_config([:instance, :upload_limit], upload_limit)

View File

@ -2,6 +2,8 @@
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/> # Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only # SPDX-License-Identifier: AGPL-3.0-only
Code.put_compiler_option(:warnings_as_errors, true)
os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: [] os_exclude = if :os.type() == {:unix, :darwin}, do: [skip_on_mac: true], else: []
ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude) ExUnit.start(exclude: [:federated, :erratic] ++ os_exclude)