Merge remote-tracking branch 'origin/develop' into birth-dates

This commit is contained in:
Alex Gleason 2022-01-22 14:24:50 -06:00
commit aaa9314f4c
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7
131 changed files with 499 additions and 45 deletions

View File

@ -90,6 +90,7 @@ unit-testing:
unit-testing-erratic:
stage: test
retry: 2
allow_failure: true
only:
changes:
- "**/*.ex"

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -34,11 +34,19 @@ 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)
%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)
link =
Phoenix.HTML.Tag.content_tag(
:span,
Phoenix.HTML.Tag.content_tag(
@ -52,12 +60,6 @@ def mention_handler("@" <> nickname, buffer, opts, acc) do
class: "h-card"
)
|> Phoenix.HTML.safe_to_string()
{link, %{acc | mentions: MapSet.put(acc.mentions, {"@" <> nickname, user})}}
_ ->
{buffer, acc}
end
end
def hashtag_handler("#" <> tag = tag_text, _buffer, _opts, acc) do

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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,

View File

@ -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 %>

View File

@ -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" %>

View File

@ -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"] %>

View File

@ -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" %>

View File

@ -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"},

View File

@ -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"},

View File

@ -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>

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.

Some files were not shown because too many files have changed in this diff Show More