Merge remote-tracking branch 'origin/develop' into birth-dates
This commit is contained in:
commit
aaa9314f4c
|
@ -90,6 +90,7 @@ unit-testing:
|
|||
unit-testing-erratic:
|
||||
stage: test
|
||||
retry: 2
|
||||
allow_failure: true
|
||||
only:
|
||||
changes:
|
||||
- "**/*.ex"
|
||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -16,6 +16,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
### Added
|
||||
- `activeMonth` and `activeHalfyear` fields in NodeInfo usage.users object
|
||||
- Experimental support for Finch. Put `config :tesla, :adapter, {Tesla.Adapter.Finch, name: MyFinch}` in your secrets file to use it. Reverse Proxy will still use Hackney.
|
||||
- `ForceMentionsInPostContent` MRF policy
|
||||
- AdminAPI: allow moderators to manage reports, users, invites, and custom emojis
|
||||
- AdminAPI: restrict moderators to access sensitive data: change user credentials, get password reset token, read private statuses and chats, etc
|
||||
- PleromaAPI: Add remote follow API endpoint at `POST /api/v1/pleroma/remote_interaction`
|
||||
|
@ -34,6 +35,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
- Handle Reject for already-accepted Follows properly
|
||||
- Display OpenGraph data on alternative notice routes.
|
||||
- Fix replies count for remote replies
|
||||
- Fixed hashtags disappearing from the end of lines when Markdown is enabled
|
||||
- ChatAPI: Add link headers
|
||||
- Limited number of search results to 40 to prevent DoS attacks
|
||||
- ActivityPub: fixed federation of attachment dimensions
|
||||
|
@ -45,6 +47,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
|||
|
||||
### Removed
|
||||
|
||||
## 2.4.2 - 2022-01-10
|
||||
|
||||
### Fixed
|
||||
- Federation issues caused by HTTP pool checkout timeouts
|
||||
- Compatibility with Elixir 1.13
|
||||
|
||||
### Upgrade notes
|
||||
|
||||
1. Restart Pleroma
|
||||
|
||||
## 2.4.1 - 2021-08-29
|
||||
|
||||
### Changed
|
||||
|
|
|
@ -116,3 +116,9 @@ Feel free to contact us to be added to this list!
|
|||
- Contact: [@r@freesoftwareextremist.com](https://freesoftwareextremist.com/users/r)
|
||||
- Features: Does not requires JavaScript
|
||||
- Features: MastoAPI
|
||||
|
||||
### Glitch-lily
|
||||
- Source Code: <https://lily.kazv.moe/infra/glitch-lily>
|
||||
- Contact: [@tusooa@kazv.moe](https://kazv.moe/users/tusooa)
|
||||
- Features: MastoAPI
|
||||
- Based on [glitch-soc](https://github.com/glitch-soc/mastodon) frontend
|
||||
|
|
|
@ -125,6 +125,8 @@ To add configuration to your config file, you can copy it from the base config.
|
|||
* `Pleroma.Web.ActivityPub.MRF.ActivityExpirationPolicy`: Sets a default expiration on all posts made by users of the local instance. Requires `Pleroma.Workers.PurgeExpiredActivity` to be enabled for processing the scheduled delections.
|
||||
* `Pleroma.Web.ActivityPub.MRF.ForceBotUnlistedPolicy`: Makes all bot posts to disappear from public timelines.
|
||||
* `Pleroma.Web.ActivityPub.MRF.FollowBotPolicy`: Automatically follows newly discovered users from the specified bot account. Local accounts, locked accounts, and users with "#nobot" in their bio are respected and excluded from being followed.
|
||||
* `Pleroma.Web.ActivityPub.MRF.KeywordPolicy`: Rejects or removes from the federated timeline or replaces keywords. (See [`:mrf_keyword`](#mrf_keyword)).
|
||||
* `Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent`: Forces every mentioned user to be reflected in the post content.
|
||||
* `transparency`: Make the content of your Message Rewrite Facility settings public (via nodeinfo).
|
||||
* `transparency_exclusions`: Exclude specific instance names from MRF transparency. The use of the exclusions feature will be disclosed in nodeinfo as a boolean value.
|
||||
|
||||
|
|
|
@ -660,3 +660,38 @@ Emoji reactions work a lot like favourites do. They make it possible to react to
|
|||
"url": "https://example.com/media/backups/archive-foobar-20200910T161803-QUhx6VYDRQ2wfV0SdA2Pfj_2CLM_ATUlw-D5l5TJf4Q.zip"
|
||||
}]
|
||||
```
|
||||
|
||||
## `GET /api/oauth_tokens`
|
||||
### Retrieve a list of active sessions for the user
|
||||
* Method: `GET`
|
||||
* Authentication: required
|
||||
* Params: none
|
||||
* Response: JSON
|
||||
* Example response:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"app_name": "Pleroma FE",
|
||||
"id": 9275,
|
||||
"valid_until": "2121-11-24T15:51:08.234234"
|
||||
},
|
||||
{
|
||||
"app_name": "Patron",
|
||||
"id": 8805,
|
||||
"valid_until": "2121-10-26T18:09:59.857150"
|
||||
},
|
||||
{
|
||||
"app_name": "Soapbox FE",
|
||||
"id": 9727,
|
||||
"valid_until": "2121-12-25T16:52:39.692877"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## `DELETE /api/oauth_tokens/:id`
|
||||
### Revoke a user session by its ID
|
||||
* Method: `DELETE`
|
||||
* Authentication: required
|
||||
* Params: none
|
||||
* Response: HTTP 200 on success, 500 on error
|
||||
|
|
|
@ -34,32 +34,34 @@ def escape_mention_handler("@" <> nickname = mention, buffer, _, _) do
|
|||
|
||||
def mention_handler("@" <> nickname, buffer, opts, acc) do
|
||||
case User.get_cached_by_nickname(nickname) do
|
||||
%User{id: id} = user ->
|
||||
user_url = user.uri || user.ap_id
|
||||
nickname_text = get_nickname_text(nickname, opts)
|
||||
|
||||
link =
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:span,
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:a,
|
||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||
"data-user": id,
|
||||
class: "u-url mention",
|
||||
href: user_url,
|
||||
rel: "ugc"
|
||||
),
|
||||
class: "h-card"
|
||||
)
|
||||
|> Phoenix.HTML.safe_to_string()
|
||||
|
||||
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||
%User{} = user ->
|
||||
{mention_from_user(user, opts),
|
||||
%{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
|
||||
|
||||
_ ->
|
||||
{buffer, acc}
|
||||
end
|
||||
end
|
||||
|
||||
def mention_from_user(%User{id: id} = user, opts \\ %{mentions_format: :full}) do
|
||||
user_url = user.uri || user.ap_id
|
||||
nickname_text = get_nickname_text(user.nickname, opts)
|
||||
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:span,
|
||||
Phoenix.HTML.Tag.content_tag(
|
||||
:a,
|
||||
["@", Phoenix.HTML.Tag.content_tag(:span, nickname_text)],
|
||||
"data-user": id,
|
||||
class: "u-url mention",
|
||||
href: user_url,
|
||||
rel: "ugc"
|
||||
),
|
||||
class: "h-card"
|
||||
)
|
||||
|> Phoenix.HTML.safe_to_string()
|
||||
end
|
||||
|
||||
def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do
|
||||
tag = String.downcase(tag)
|
||||
url = "#{Pleroma.Web.Endpoint.url()}/tag/#{tag}"
|
||||
|
|
|
@ -1084,6 +1084,10 @@ def get_by_ap_id(ap_id) do
|
|||
Repo.get_by(User, ap_id: ap_id)
|
||||
end
|
||||
|
||||
def get_by_uri(uri) do
|
||||
Repo.get_by(User, uri: uri)
|
||||
end
|
||||
|
||||
def get_all_by_ap_id(ap_ids) do
|
||||
from(u in __MODULE__,
|
||||
where: u.ap_id in ^ap_ids
|
||||
|
|
|
@ -1675,7 +1675,10 @@ def pin_data_from_featured_collection(%{
|
|||
"orderedItems" => objects
|
||||
})
|
||||
when type in ["OrderedCollection", "Collection"] do
|
||||
Map.new(objects, fn %{"id" => object_ap_id} -> {object_ap_id, NaiveDateTime.utc_now()} end)
|
||||
Map.new(objects, fn
|
||||
%{"id" => object_ap_id} -> {object_ap_id, NaiveDateTime.utc_now()}
|
||||
object_ap_id when is_binary(object_ap_id) -> {object_ap_id, NaiveDateTime.utc_now()}
|
||||
end)
|
||||
end
|
||||
|
||||
def fetch_and_prepare_featured_from_ap_id(nil) do
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
# Pleroma: A lightweight social networking server
|
||||
# Copyright © 2017-2022 Pleroma Authors <https://pleroma.social/>
|
||||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
defmodule Pleroma.Web.ActivityPub.MRF.ForceMentionsInContent do
|
||||
alias Pleroma.Formatter
|
||||
alias Pleroma.User
|
||||
|
||||
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
|
||||
|
||||
defp do_extract({:a, attrs, _}, acc) do
|
||||
if Enum.find(attrs, fn {name, value} ->
|
||||
name == "class" && value in ["mention", "u-url mention", "mention u-url"]
|
||||
end) do
|
||||
href = Enum.find(attrs, fn {name, _} -> name == "href" end) |> elem(1)
|
||||
acc ++ [href]
|
||||
else
|
||||
acc
|
||||
end
|
||||
end
|
||||
|
||||
defp do_extract({_, _, children}, acc) do
|
||||
do_extract(children, acc)
|
||||
end
|
||||
|
||||
defp do_extract(nodes, acc) when is_list(nodes) do
|
||||
Enum.reduce(nodes, acc, fn node, acc -> do_extract(node, acc) end)
|
||||
end
|
||||
|
||||
defp do_extract(_, acc), do: acc
|
||||
|
||||
defp extract_mention_uris_from_content(content) do
|
||||
{:ok, tree} = :fast_html.decode(content, format: [:html_atoms])
|
||||
do_extract(tree, [])
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(%{"type" => "Create", "object" => %{"type" => "Note", "tag" => tag}} = object) do
|
||||
# image-only posts from pleroma apparently reach this MRF without the content field
|
||||
content = object["object"]["content"] || ""
|
||||
|
||||
mention_users =
|
||||
tag
|
||||
|> Enum.filter(fn tag -> tag["type"] == "Mention" end)
|
||||
|> Enum.map(& &1["href"])
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|> Enum.map(fn ap_id_or_uri ->
|
||||
case User.get_or_fetch_by_ap_id(ap_id_or_uri) do
|
||||
{:ok, user} -> {ap_id_or_uri, user}
|
||||
_ -> {ap_id_or_uri, User.get_by_uri(ap_id_or_uri)}
|
||||
end
|
||||
end)
|
||||
|> Enum.reject(fn {_, user} -> user == nil end)
|
||||
|> Enum.into(%{})
|
||||
|
||||
explicitly_mentioned_uris = extract_mention_uris_from_content(content)
|
||||
|
||||
added_mentions =
|
||||
Enum.reduce(mention_users, "", fn {uri, user}, acc ->
|
||||
unless uri in explicitly_mentioned_uris do
|
||||
acc <> Formatter.mention_from_user(user)
|
||||
else
|
||||
acc
|
||||
end
|
||||
end)
|
||||
|
||||
content =
|
||||
if added_mentions != "",
|
||||
do: added_mentions <> " " <> content,
|
||||
else: content
|
||||
|
||||
{:ok, put_in(object["object"]["content"], content)}
|
||||
end
|
||||
|
||||
@impl true
|
||||
def filter(object), do: {:ok, object}
|
||||
|
||||
@impl true
|
||||
def describe, do: {:ok, %{}}
|
||||
end
|
|
@ -67,6 +67,9 @@ def features do
|
|||
"shareable_emoji_packs",
|
||||
"multifetch",
|
||||
"pleroma:api/v1/notifications:include_types_filter",
|
||||
if Config.get([:activitypub, :blockers_visible]) do
|
||||
"blockers_visible"
|
||||
end,
|
||||
if Config.get([:media_proxy, :enabled]) do
|
||||
"media_proxy"
|
||||
end,
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
|
||||
<div class="input">
|
||||
<%= label f, :code, "Authentication code" %>
|
||||
<%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %>
|
||||
<%= text_input f, :code, [autocomplete: "one-time-code", autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %>
|
||||
<%= hidden_input f, :mfa_token, value: @mfa_token %>
|
||||
<%= hidden_input f, :state, value: @state %>
|
||||
<%= hidden_input f, :redirect_uri, value: @redirect_uri %>
|
||||
|
|
|
@ -12,11 +12,11 @@
|
|||
|
||||
<div class="input">
|
||||
<%= label f, :nickname, "Nickname" %>
|
||||
<%= text_input f, :nickname, value: @nickname %>
|
||||
<%= text_input f, :nickname, value: @nickname, autocomplete: "username" %>
|
||||
</div>
|
||||
<div class="input">
|
||||
<%= label f, :email, "Email" %>
|
||||
<%= text_input f, :email, value: @email %>
|
||||
<%= text_input f, :email, value: @email, autocomplete: "email" %>
|
||||
</div>
|
||||
|
||||
<%= submit "Proceed as new user", name: "op", value: "register" %>
|
||||
|
@ -25,11 +25,11 @@
|
|||
|
||||
<div class="input">
|
||||
<%= label f, :name, "Name or email" %>
|
||||
<%= text_input f, :name %>
|
||||
<%= text_input f, :name, autocomplete: "username" %>
|
||||
</div>
|
||||
<div class="input">
|
||||
<%= label f, :password, "Password" %>
|
||||
<%= password_input f, :password %>
|
||||
<%= password_input f, :password, autocomplete: "password" %>
|
||||
</div>
|
||||
|
||||
<%= submit "Proceed as existing user", name: "op", value: "connect" %>
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<p>Choose carefully! You won't be able to change this later. You will be able to change your display name, though.</p>
|
||||
<div class="input">
|
||||
<%= label f, :nickname, "Pleroma Handle" %>
|
||||
<%= text_input f, :nickname, placeholder: "lain" %>
|
||||
<%= text_input f, :nickname, placeholder: "lain", autocomplete: "username" %>
|
||||
</div>
|
||||
<%= hidden_input f, :name, value: @params["name"] %>
|
||||
<%= hidden_input f, :password, value: @params["password"] %>
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
<p><%= @followee.nickname %></p>
|
||||
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
|
||||
<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %>
|
||||
<%= text_input f, :name, placeholder: "Username", required: true %>
|
||||
<%= text_input f, :name, placeholder: "Username", required: true, autocomplete: "username" %>
|
||||
<br>
|
||||
<%= password_input f, :password, placeholder: "Password", required: true %>
|
||||
<%= password_input f, :password, placeholder: "Password", required: true, autocomplete: "password" %>
|
||||
<br>
|
||||
<%= hidden_input f, :id, value: @followee.id %>
|
||||
<%= submit "Authorize" %>
|
||||
|
|
2
mix.exs
2
mix.exs
|
@ -157,7 +157,7 @@ defp deps do
|
|||
{:floki, "~> 0.27"},
|
||||
{:timex, "~> 3.6"},
|
||||
{:ueberauth, "~> 0.4"},
|
||||
{:linkify, "~> 0.5.1"},
|
||||
{:linkify, "~> 0.5.2"},
|
||||
{:http_signatures, "~> 0.1.1"},
|
||||
{:telemetry, "~> 0.3"},
|
||||
{:poolboy, "~> 1.5"},
|
||||
|
|
2
mix.lock
2
mix.lock
|
@ -69,7 +69,7 @@
|
|||
"jose": {:hex, :jose, "1.11.1", "59da64010c69aad6cde2f5b9248b896b84472e99bd18f246085b7b9fe435dcdb", [:mix, :rebar3], [], "hexpm", "078f6c9fb3cd2f4cfafc972c814261a7d1e8d2b3685c0a76eb87e158efff1ac5"},
|
||||
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},
|
||||
"libring": {:hex, :libring, "1.4.0", "41246ba2f3fbc76b3971f6bce83119dfec1eee17e977a48d8a9cfaaf58c2a8d6", [:mix], [], "hexpm"},
|
||||
"linkify": {:hex, :linkify, "0.5.1", "6dc415cbc948b2f6ecec7cb226aab7ba9d3a1815bb501ae33e042334d707ecee", [:mix], [], "hexpm", "a3128c7e22fada4aa7214009501d8131e1fa3faf2f0a68b33dba379dc84ff944"},
|
||||
"linkify": {:hex, :linkify, "0.5.2", "fb66be139fdf1656ecb31f78a93592724d1b78d960a1b3598bd661013ea0e3c7", [:mix], [], "hexpm", "8d71ac690218d8952c90cbeb63cb8cc33738bb230d8a56d487d9447f2a5eab86"},
|
||||
"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_elixir": {:hex, :makeup_elixir, "0.14.1", "4f0e96847c63c17841d42c08107405a005a2680eb9c7ccadfd757bd31dabccfb", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "f2438b1a80eaec9ede832b5c41cd4f373b38fd7aa33e3b22d9db79e640cbde11"},
|
||||
|
|
|
@ -1 +1 @@
|
|||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.9a4c5ede37b2f0230836.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.fb9ee54b02db0c974e51.js></script><script type=text/javascript src=/static/js/app.ce97bd1883ee9dd7b809.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.7d2d223f75c3a14b0991.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.cea10ab53f3aa19fc30e.js></script><script type=text/javascript src=/static/js/app.6c972d84b60f601b01f8.js></script></body></html>
|
Binary file not shown.
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue