Compare commits

..

30 commits

Author SHA1 Message Date
Kegan Myers dd17e0353a allow specifying secret file location 2023-07-23 14:35:54 -05:00
FloatingGhost 9d7c877de0 Merge branch 'develop' into stable 2023-05-26 20:46:56 +01:00
FloatingGhost 39b3d92cd8 Bump version 2023-05-26 20:46:38 +01:00
Haelwenn (lanodan) Monnier 70b0f93865 Apply oembed patch 2023-05-26 20:45:57 +01:00
FloatingGhost 39a878f530 Merge branch 'develop' into stable 2023-05-26 12:07:05 +01:00
FloatingGhost a388d2503e revert uploaded-media 2023-05-26 12:06:41 +01:00
FloatingGhost dcee1b109b Merge branch 'develop' into stable 2023-05-26 12:05:11 +01:00
FloatingGhost 7fb9960ccd Add CSP to mediaproxy links 2023-05-26 11:46:18 +01:00
FloatingGhost 9d83a1e23f Add csp 2023-05-26 11:41:22 +01:00
FloatingGhost 9a8373a3f5 Merge branch 'develop' into stable 2023-05-23 14:10:19 +01:00
FloatingGhost 82ca7a6470 bump version 2023-05-23 14:10:01 +01:00
FloatingGhost 9e9cf58fdf or not 2023-05-23 13:54:22 +01:00
FloatingGhost 2fc26609f6 ensure we depend on poison 2023-05-23 13:53:54 +01:00
FloatingGhost 8c208f751d Fix filtering out incorrect addresses 2023-05-23 13:46:25 +01:00
FloatingGhost 037f881187 Fix create processing in direct message disabled 2023-05-23 13:16:20 +01:00
FloatingGhost ab34680554 switch to using an enum system for DM acceptance 2023-05-23 10:29:08 +01:00
FloatingGhost d310f99d6a Add MRFs for direct message manipulation 2023-05-22 23:53:44 +01:00
floatingghost 4e969758e5 Merge pull request 'fix remote interaction form style' (#542) from denys/akkoma:style-remote-interaction into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/542
2023-05-22 21:35:51 +00:00
floatingghost f72d773cc3 Merge pull request 'Make UserNote comment default to the empty string.' (#530) from provable_ascent/akkoma:provable_ascent-patch-1 into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/530
2023-05-22 21:33:01 +00:00
floatingghost 3437e11cf7 Merge pull request 'Return empty string in the event of no detected language' (#535) from midnight/akkoma:fix-libretranslate into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/535
2023-05-22 21:30:51 +00:00
floatingghost 6225f24f5f Merge pull request 'Clean up bookmarks after prune_objects' (#544) from ilja/akkoma:clean_up_bookmarks_after_prune_objects into develop
Reviewed-on: https://akkoma.dev/AkkomaGang/akkoma/pulls/544
2023-05-22 21:28:48 +00:00
ilja f49e9e6d4c Clean up bookmarks after prune_objects
When doing prune_objects, it's possible that bookmarked objects are deleted.
This gave problems when fetching the bookmark TL.
Here we clean up the bookmarks during pruning in the case were it's possible that bookmarked objects are deleted.
2023-05-21 13:02:28 +02:00
ilja c7fb78cc32 Move deadline and old_insert_date to setup
Several tests for prune_objetcs need a date older than the deadline for pruning, so I moved that to the setup
2023-05-21 12:01:54 +02:00
Denys Nykula ddf4d8026d fix remote interaction form style 2023-05-18 22:53:40 +03:00
provable_ascent 3fef9d1b67 Merge branch 'develop' into provable_ascent-patch-1 2023-05-12 02:19:13 +00:00
provable_ascent 9c4203632d Add user_note_test.exs. 2023-05-12 02:18:24 +00:00
midnight f1e66b39c7 Return empty string in the event of no detected language 2023-05-08 18:52:19 -04:00
FloatingGhost 145c73076d Update dependencies 2023-05-08 16:29:25 +01:00
provable_ascent d8bed0ff63 Make UserNote comment default to the empty string.
This make the behavior consistent between when UserNote doesn't exist and when comment is null.

The current behavior may return null in APIs, which misleads some clients doing feature detection into thinking the server does not support comments.
For example, see https://codeberg.org/husky/husky/issues/92
2023-04-27 05:22:12 +00:00
FloatingGhost b86b3a9e29 Support public key URIs that incomprehensibly have GET args
Fixes #528
2023-04-25 13:30:20 +01:00
31 changed files with 550 additions and 94 deletions

View file

@ -4,6 +4,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## 2023.05
## Added
- Custom options for users to accept/reject private messages
- options: everybody, nobody, people\_i\_follow
- MRF to reject notes from accounts newer than a given age
- this will have the side-effect of rejecting legitimate messages if your
post gets boosted outside of your local bubble and people your instance
does not know about reply to it.
## Fixed
- Support for `streams` public key URIs
- Bookmarks are cleaned up on DB prune now
## Security
- Fixed mediaproxy being a bit of a silly billy
## 2023.04
## Added

View file

@ -418,6 +418,8 @@
config :pleroma, :mrf_follow_bot, follower_nickname: nil
config :pleroma, :mrf_reject_newly_created_account_notes, age: 86_400
config :pleroma, :rich_media,
enabled: true,
ignore_hosts: [],

View file

@ -63,8 +63,8 @@
# Finally import the config/prod.secret.exs
# which should be versioned separately.
if File.exists?("./config/prod.secret.exs") do
import_config "prod.secret.exs"
if File.exists?(System.get_env("PROD_SECRET_FILE", "./config/prod.secret.exs")) do
import_config System.get_env("PROD_SECRET_FILE", "./config/prod.secret.exs")
else
"`config/prod.secret.exs` not found. You may want to create one by running `mix pleroma.instance gen`"
|> IO.warn([])

View file

@ -171,6 +171,21 @@ def run(["prune_objects" | args]) do
end
|> Repo.delete_all(timeout: :infinity)
if !Keyword.get(options, :keep_threads) do
# Without the --keep-threads option, it's possible that bookmarked
# objects have been deleted. We remove the corresponding bookmarks.
"""
delete from public.bookmarks
where id in (
select b.id from public.bookmarks b
left join public.activities a on b.activity_id = a.id
left join public.objects o on a."data" ->> 'object' = o.data ->> 'id'
where o.id is null
)
"""
|> Repo.query([], timeout: :infinity)
end
if Keyword.get(options, :prune_orphaned_activities) do
# Prune activities who link to a single object
"""

View file

@ -40,7 +40,7 @@ def translate(string, from_language, to_language) do
if Map.has_key?(body, "detectedLanguage") do
get_in(body, ["detectedLanguage", "language"])
else
from_language
from_language || ""
end
{:ok, detected, translated}

View file

@ -251,6 +251,7 @@ defp build_resp_headers(headers, opts) do
|> Enum.filter(fn {k, _} -> k in @keep_resp_headers end)
|> build_resp_cache_headers(opts)
|> build_resp_content_disposition_header(opts)
|> build_csp_headers()
|> Keyword.merge(Keyword.get(opts, :resp_headers, []))
end
@ -316,6 +317,10 @@ defp build_resp_content_disposition_header(headers, opts) do
end
end
defp build_csp_headers(headers) do
List.keystore(headers, "content-security-policy", 0, {"content-security-policy", "sandbox"})
end
defp header_length_constraint(headers, limit) when is_integer(limit) and limit > 0 do
with {_, size} <- List.keyfind(headers, "content-length", 0),
{size, _} <- Integer.parse(size),

View file

@ -17,6 +17,7 @@ def key_id_to_actor_id(key_id) do
key_id
|> URI.parse()
|> Map.put(:fragment, nil)
|> Map.put(:query, nil)
|> remove_suffix(@known_suffixes)
maybe_ap_id = URI.to_string(uri)

View file

@ -159,6 +159,11 @@ defmodule Pleroma.User do
field(:language, :string)
field(:status_ttl_days, :integer, default: nil)
field(:accepts_direct_messages_from, Ecto.Enum,
values: [:everybody, :people_i_follow, :nobody],
default: :everybody
)
embeds_one(
:notification_settings,
Pleroma.User.NotificationSetting,
@ -536,7 +541,8 @@ def update_changeset(struct, params \\ %{}) do
:is_discoverable,
:actor_type,
:disclose_client,
:status_ttl_days
:status_ttl_days,
:accepts_direct_messages_from
]
)
|> unique_constraint(:nickname)
@ -2722,4 +2728,16 @@ def unfollow_hashtag(%User{} = user, %Hashtag{} = hashtag) do
def following_hashtag?(%User{} = user, %Hashtag{} = hashtag) do
not is_nil(HashtagFollow.get(user, hashtag))
end
def accepts_direct_messages?(
%User{accepts_direct_messages_from: :people_i_follow} = receiver,
%User{} = sender
) do
User.following?(receiver, sender)
end
def accepts_direct_messages?(%User{accepts_direct_messages_from: :everybody}, _), do: true
def accepts_direct_messages?(%User{accepts_direct_messages_from: :nobody}, _),
do: false
end

View file

@ -31,7 +31,7 @@ def show(%User{} = source, %User{} = target) do
UserNote
|> where(source_id: ^source.id, target_id: ^target.id)
|> Repo.one() do
note.comment
note.comment || ""
else
_ -> ""
end

View file

@ -147,7 +147,8 @@ def get_policies do
|> Enum.concat([
Pleroma.Web.ActivityPub.MRF.HashtagPolicy,
Pleroma.Web.ActivityPub.MRF.InlineQuotePolicy,
Pleroma.Web.ActivityPub.MRF.NormalizeMarkup
Pleroma.Web.ActivityPub.MRF.NormalizeMarkup,
Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy
])
|> Enum.uniq()
end

View file

@ -0,0 +1,65 @@
defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
alias Pleroma.User
require Pleroma.Constants
@moduledoc """
Removes entries from the "To" field from direct messages if the user has requested to not
allow direct messages
"""
@impl true
def filter(
%{
"type" => "Create",
"actor" => actor,
"object" => %{
"type" => "Note"
}
} = activity
) do
with recipients <- Map.get(activity, "to", []),
cc <- Map.get(activity, "cc", []),
true <- is_direct?(recipients, cc),
sender <- User.get_cached_by_ap_id(actor) do
new_to =
Enum.filter(recipients, fn recv ->
should_include?(sender, recv)
end)
{:ok,
activity
|> Map.put("to", new_to)
|> maybe_replace_object_to(new_to)}
else
_ ->
{:ok, activity}
end
end
@impl true
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
defp should_include?(sender, receiver_ap_id) do
with %User{local: true} = receiver <- User.get_cached_by_ap_id(receiver_ap_id) do
User.accepts_direct_messages?(receiver, sender)
else
_ -> true
end
end
defp maybe_replace_object_to(%{"object" => %{"to" => _}} = activity, to) do
Kernel.put_in(activity, ["object", "to"], to)
end
defp maybe_replace_object_to(other, _), do: other
defp is_direct?(to, cc) do
!(Enum.member?(to, Pleroma.Constants.as_public()) ||
Enum.member?(cc, Pleroma.Constants.as_public()))
end
end

View file

@ -0,0 +1,50 @@
defmodule Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy do
@behaviour Pleroma.Web.ActivityPub.MRF.Policy
alias Pleroma.User
@moduledoc """
Rejects notes from accounts that were created below a certain threshold of time ago
"""
@impl true
def filter(
%{
"type" => type,
"actor" => actor
} = activity
)
when type in ["Note", "Create"] do
min_age = Pleroma.Config.get([:mrf_reject_newly_created_account_notes, :age])
with %User{local: false} = user <- Pleroma.User.get_cached_by_ap_id(actor),
true <- Timex.diff(Timex.now(), user.inserted_at, :seconds) < min_age do
{:reject, "[RejectNewlyCreatedAccountNotesPolicy] Account created too recently"}
else
_ -> {:ok, activity}
end
end
@impl true
def filter(object), do: {:ok, object}
@impl true
def describe, do: {:ok, %{}}
@impl true
def config_description do
%{
key: :mrf_reject_newly_created_account_notes,
related_policy: "Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy",
label: "MRF Reject New Accounts",
description: "Reject notes from accounts created too recently",
children: [
%{
key: :age,
type: :integer,
description: "Time below which to reject (in seconds)",
suggestions: [86_400]
}
]
}
end
end

View file

@ -708,6 +708,16 @@ defp update_credentials_request do
nullable: true,
description:
"Number of days after which statuses will be deleted. Set to -1 to disable."
},
accepts_direct_messages_from: %Schema{
type: :string,
enum: [
"everybody",
"nobody",
"people_i_follow"
],
nullable: true,
description: "Who to accept DMs from"
}
},
example: %{
@ -729,7 +739,8 @@ defp update_credentials_request do
also_known_as: ["https://foo.bar/users/foo"],
discoverable: false,
actor_type: "Person",
status_ttl_days: 30
status_ttl_days: 30,
accepts_direct_messages_from: "everybody"
}
}
end

View file

@ -221,6 +221,7 @@ def update_credentials(%{assigns: %{user: user}, body_params: params} = conn, _p
|> Maps.put_if_present(:is_discoverable, params[:discoverable])
|> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language]))
|> Maps.put_if_present(:status_ttl_days, params[:status_ttl_days], status_ttl_days_value)
|> Maps.put_if_present(:accepts_direct_messages_from, params[:accepts_direct_messages_from])
# What happens here:
#

View file

@ -354,6 +354,7 @@ defp maybe_put_settings(
|> Kernel.put_in([:source, :privacy], user.default_scope)
|> Kernel.put_in([:source, :pleroma, :show_role], user.show_role)
|> Kernel.put_in([:source, :pleroma, :no_rich_text], user.no_rich_text)
|> Kernel.put_in([:accepts_direct_messages_from], user.accepts_direct_messages_from)
end
defp maybe_put_settings(data, _, _, _), do: data

View file

@ -6,8 +6,8 @@ defmodule Pleroma.Web.RichMedia.Parsers.OEmbed do
def parse(html, _data) do
with elements = [_ | _] <- get_discovery_data(html),
oembed_url when is_binary(oembed_url) <- get_oembed_url(elements),
{:ok, oembed_data} <- get_oembed_data(oembed_url) do
oembed_data
{:ok, oembed_data = %{"html" => html}} <- get_oembed_data(oembed_url) do
%{oembed_data | "html" => Pleroma.HTML.filter_tags(html)}
else
_e -> %{}
end

View file

@ -4,7 +4,7 @@ defmodule Pleroma.Mixfile do
def project do
[
app: :pleroma,
version: version("3.8.0"),
version: version("3.9.3"),
elixir: "~> 1.14",
elixirc_paths: elixirc_paths(Mix.env()),
compilers: [:phoenix] ++ Mix.compilers(),
@ -190,7 +190,6 @@ defp deps do
{:mfm_parser,
git: "https://akkoma.dev/AkkomaGang/mfm-parser.git",
ref: "912fba81152d4d572e457fd5427f9875b2bc3dbe"},
{:poison, ">= 0.0.0"},
## dev & test
{:ex_doc, "~> 0.22", only: :dev, runtime: false},

View file

@ -15,21 +15,21 @@
"concurrent_limiter": {:hex, :concurrent_limiter, "0.1.1", "43ae1dc23edda1ab03dd66febc739c4ff710d047bb4d735754909f9a474ae01c", [:mix], [{:telemetry, "~> 0.3", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "53968ff238c0fbb4d7ed76ddb1af0be6f3b2f77909f6796e249e737c505a16eb"},
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"cors_plug": {:hex, :cors_plug, "2.0.3", "316f806d10316e6d10f09473f19052d20ba0a0ce2a1d910ddf57d663dac402ae", [:mix], [{:plug, "~> 1.8", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "ee4ae1418e6ce117fc42c2ba3e6cbdca4e95ecd2fe59a05ec6884ca16d469aea"},
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
"cowboy": {:hex, :cowboy, "2.10.0", "ff9ffeff91dae4ae270dd975642997afe2a1179d94b1887863e43f681a203e26", [:make, :rebar3], [{:cowlib, "2.12.1", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "3afdccb7183cc6f143cb14d3cf51fa00e53db9ec80cdcd525482f5e99bc41d6b"},
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
"cowlib": {:hex, :cowlib, "2.12.1", "a9fa9a625f1d2025fe6b462cb865881329b5caff8f1854d1cbc9f9533f00e1e1", [:make, :rebar3], [], "hexpm", "163b73f6367a7341b33c794c4e88e7dbfe6498ac42dcd69ef44c5bc5507c8db0"},
"credo": {:git, "https://github.com/rrrene/credo.git", "1c1b99ea41a457761383d81aaf6a606913996fe7", [ref: "1c1b99ea41a457761383d81aaf6a606913996fe7"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.4.3", "3b9aac9f27347ec65b271847e6baeb4443d8474289bd18c1d6f4de655b70c94d", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c127c15b0fa6cfb32eed07465e05da6c815b032508d4ed7c116122871df73c12"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"db_connection": {:hex, :db_connection, "2.5.0", "bb6d4f30d35ded97b29fe80d8bd6f928a1912ca1ff110831edcd238a1973652c", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c92d5ba26cd69ead1ff7582dbb860adeedfff39774105a4f1c92cbb654b55aa2"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"dialyxir": {:hex, :dialyxir, "1.2.0", "58344b3e87c2e7095304c81a9ae65cb68b613e28340690dfe1a5597fd08dec37", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "61072136427a851674cab81762be4dbeae7679f85b1272b6d25c3a839aff8463"},
"earmark": {:hex, :earmark, "1.4.37", "56ce845c543393aa3f9b294c818c3d783452a4a67e4ab18c4303a954a8b59363", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "d86d5e12868db86d5321b00e62a4bbcb4150346e4acc9a90a041fb188a5cb106"},
"earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"},
"dialyxir": {:hex, :dialyxir, "1.3.0", "fd1672f0922b7648ff9ce7b1b26fcf0ef56dda964a459892ad15f6b4410b5284", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "00b2a4bcd6aa8db9dcb0b38c1225b7277dca9bc370b6438715667071a304696f"},
"earmark": {:hex, :earmark, "1.4.38", "ba8fda946c259c6e8f6759d3647d448e9216e2c0afed8c6ae7f8ce1f7072a497", [:mix], [{:earmark_parser, "~> 1.4.32", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "f938e30de4167e7d8f3bf588b01dc041138278dda1e5a13fb9ec89b43dd5ec7f"},
"earmark_parser": {:hex, :earmark_parser, "1.4.32", "fa739a0ecfa34493de19426681b23f6814573faee95dfd4b4aafe15a7b5b32c6", [:mix], [], "hexpm", "b8b0dd77d60373e77a3d7e8afa598f325e49e8663a51bcc2b88ef41838cca755"},
"eblurhash": {:hex, :eblurhash, "1.2.2", "7da4255aaea984b31bb71155f673257353b0e0554d0d30dcf859547e74602582", [:rebar3], [], "hexpm", "8c20ca00904de023a835a9dcb7b7762fed32264c85a80c3cafa85288e405044c"},
"ecto": {:hex, :ecto, "3.9.5", "9f0aa7ae44a1577b651c98791c6988cd1b69b21bc724e3fd67090b97f7604263", [: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", "d4f3115d8cbacdc0bfa4b742865459fb1371d0715515842a1fb17fe31920b74c"},
"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_psql_extras": {:hex, :ecto_psql_extras, "0.7.10", "e14d400930f401ca9f541b3349212634e44027d7f919bbb71224d7ac0d0e8acd", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "505e8cd81e4f17c090be0f99e92b1b3f0fd915f98e76965130b8ccfb891e7088"},
"ecto_psql_extras": {:hex, :ecto_psql_extras, "0.7.11", "6e20144c1446dcccfcdb4c142c9d8b7992a90a569b1d5958cbea5458550b25f0", [:mix], [{:ecto_sql, "~> 3.4", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.15.7 or ~> 0.16.0 or ~> 0.17.0", [hex: :postgrex, repo: "hexpm", optional: false]}, {:table_rex, "~> 3.1.1", [hex: :table_rex, repo: "hexpm", optional: false]}], "hexpm", "def61f1f92d4f40d51c80bbae2157212d6c0a459eb604be446e47369cbd40b23"},
"ecto_sql": {:hex, :ecto_sql, "3.9.2", "34227501abe92dba10d9c3495ab6770e75e79b836d114c41108a4bf2ce200ad5", [:mix], [{:db_connection, "~> 2.4.1 or ~> 2.5", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.9.2", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.6.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.16.0 or ~> 1.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.1 or ~> 2.2", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1eb5eeb4358fdbcd42eac11c1fbd87e3affd7904e639d77903c1358b2abd3f70"},
"elasticsearch": {:git, "https://akkoma.dev/AkkomaGang/elasticsearch-elixir.git", "6cd946f75f6ab9042521a009d1d32d29a90113ca", [ref: "main"]},
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
@ -38,7 +38,7 @@
"ex_aws": {:hex, :ex_aws, "2.1.9", "dc4865ecc20a05190a34a0ac5213e3e5e2b0a75a0c2835e923ae7bfeac5e3c31", [:mix], [{:configparser_ex, "~> 4.0", [hex: :configparser_ex, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: true]}, {:jsx, "~> 3.0", [hex: :jsx, repo: "hexpm", optional: true]}, {:sweet_xml, "~> 0.6", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "3e6c776703c9076001fbe1f7c049535f042cb2afa0d2cbd3b47cbc4e92ac0d10"},
"ex_aws_s3": {:hex, :ex_aws_s3, "2.4.0", "ce8decb6b523381812798396bc0e3aaa62282e1b40520125d1f4eff4abdff0f4", [:mix], [{:ex_aws, "~> 2.0", [hex: :ex_aws, repo: "hexpm", optional: false]}, {:sweet_xml, ">= 0.0.0", [hex: :sweet_xml, repo: "hexpm", optional: true]}], "hexpm", "85dda6e27754d94582869d39cba3241d9ea60b6aa4167f9c88e309dc687e56bb"},
"ex_const": {:hex, :ex_const, "0.2.4", "d06e540c9d834865b012a17407761455efa71d0ce91e5831e86881b9c9d82448", [:mix], [], "hexpm", "96fd346610cc992b8f896ed26a98be82ac4efb065a0578f334a32d60a3ba9767"},
"ex_doc": {:hex, :ex_doc, "0.29.3", "f07444bcafb302db86e4f02d8bbcd82f2e881a0dcf4f3e4740e4b8128b9353f7", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3dc6787d7b08801ec3b51e9bd26be5e8826fbf1a17e92d1ebc252e1a1c75bfe1"},
"ex_doc": {:hex, :ex_doc, "0.29.4", "6257ecbb20c7396b1fe5accd55b7b0d23f44b6aa18017b415cb4c2b91d997729", [:mix], [{:earmark_parser, "~> 1.4.31", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "2c6699a737ae46cb61e4ed012af931b57b699643b24dabe2400a8168414bc4f5"},
"ex_machina": {:hex, :ex_machina, "2.7.0", "b792cc3127fd0680fecdb6299235b4727a4944a09ff0fa904cc639272cd92dc7", [:mix], [{:ecto, "~> 2.2 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_sql, "~> 3.0", [hex: :ecto_sql, repo: "hexpm", optional: true]}], "hexpm", "419aa7a39bde11894c87a615c4ecaa52d8f107bbdd81d810465186f783245bf8"},
"ex_syslogger": {:hex, :ex_syslogger, "1.5.2", "72b6aa2d47a236e999171f2e1ec18698740f40af0bd02c8c650bf5f1fd1bac79", [:mix], [{:poison, ">= 1.5.0", [hex: :poison, repo: "hexpm", optional: true]}, {:syslog, "~> 1.1.0", [hex: :syslog, repo: "hexpm", optional: false]}], "hexpm", "ab9fab4136dbc62651ec6f16fa4842f10cf02ab4433fa3d0976c01be99398399"},
"excoveralls": {:hex, :excoveralls, "0.15.1", "83c8cf7973dd9d1d853dce37a2fb98aaf29b564bf7d01866e409abf59dac2c0e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "f8416bd90c0082d56a2178cf46c837595a06575f70a5624f164a1ffe37de07e7"},
@ -65,7 +65,7 @@
"mail": {:hex, :mail, "0.2.3", "2c6bb5f8a5f74845fa50ecd0fb45ea16b164026f285f45104f1c4c078cd616d4", [:mix], [], "hexpm", "932b398fa9c69fdf290d7ff63175826e0f1e24414d5b0763bb00a2acfc6c6bf5"},
"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.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"},
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
"meck": {:hex, :meck, "0.9.2", "85ccbab053f1db86c7ca240e9fc718170ee5bda03810a6292b5306bf31bae5f5", [:rebar3], [], "hexpm", "81344f561357dc40a8344afa53767c32669153355b626ea9fcbc8da6b3045826"},
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
@ -77,10 +77,10 @@
"mogrify": {:hex, :mogrify, "0.9.2", "b360984adea7dd6a55f18028e6327973c58de7f548fdb86c9859848aa904d5b0", [:mix], [], "hexpm", "c18d10fd70ca20e2585301616c89f6e4f7159d92efc9cc8ee579e00c886f699d"},
"mox": {:hex, :mox, "1.0.2", "dc2057289ac478b35760ba74165b4b3f402f68803dd5aecd3bfd19c183815d64", [:mix], [], "hexpm", "f9864921b3aaf763c8741b5b8e6f908f44566f1e427b2630e89e9a73b981fef2"},
"nimble_options": {:hex, :nimble_options, "0.5.2", "42703307b924880f8c08d97719da7472673391905f528259915782bb346e0a1b", [:mix], [], "hexpm", "4da7f904b915fd71db549bcdc25f8d56f378ef7ae07dc1d372cbe72ba950dce0"},
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
"nimble_parsec": {:hex, :nimble_parsec, "1.3.1", "2c54013ecf170e249e9291ed0a62e5832f70a476c61da16f6aac6dca0189f2af", [:mix], [], "hexpm", "2682e3c0b2eb58d90c6375fc0cc30bc7be06f365bf72608804fb9cffa5e1b167"},
"nimble_pool": {:hex, :nimble_pool, "0.2.6", "91f2f4c357da4c4a0a548286c84a3a28004f68f05609b4534526871a22053cde", [:mix], [], "hexpm", "1c715055095d3f2705c4e236c18b618420a35490da94149ff8b580a2144f653f"},
"oban": {:hex, :oban, "2.12.1", "f604d7e6a8be9fda4a9b0f6cebbd633deba569f85dbff70c4d25d99a6f023177", [: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", "9b1844c2b74e0d788b73e5144b0c9d5674cb775eae29d88a36f3c3b48d42d058"},
"open_api_spex": {:hex, :open_api_spex, "3.16.1", "8137c338129d63060b4b04947c6c57429f86267045c479c703a38a6d3f98dee1", [: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", "ef6fd778ac121af866b48b75ad4ad256b6ff33949113ea4aa1629af8bfdfdbfb"},
"open_api_spex": {:hex, :open_api_spex, "3.16.3", "11bc9798890073e516a97392d5846a235925e48ecbb468cb5b1cc207d5785a3e", [: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", "1bcbe6efab88f5d001c2fc377e0bd6058180aa31b68d32962d4926e934b8ecad"},
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
"phoenix": {:hex, :phoenix, "1.6.16", "e5bdd18c7a06da5852a25c7befb72246de4ddc289182285f8685a40b7b5f5451", [: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", "e15989ff34f670a96b95ef6d1d25bad0d9c50df5df40b671d8f4a669e050ac39"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
@ -107,7 +107,7 @@
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
"statistex": {:hex, :statistex, "1.0.0", "f3dc93f3c0c6c92e5f291704cf62b99b553253d7969e9a5fa713e5481cd858a5", [:mix], [], "hexpm", "ff9d8bee7035028ab4742ff52fc80a2aa35cece833cf5319009b52f1b5a86c27"},
"sweet_xml": {:hex, :sweet_xml, "0.7.3", "debb256781c75ff6a8c5cbf7981146312b66f044a2898f453709a53e5031b45b", [:mix], [], "hexpm", "e110c867a1b3fe74bfc7dd9893aa851f0eed5518d0d7cad76d7baafd30e4f5ba"},
"swoosh": {:hex, :swoosh, "1.9.1", "0a5d7bf9954eb41d7e55525bc0940379982b090abbaef67cd8e1fd2ed7f8ca1a", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "76dffff3ffcab80f249d5937a592eaef7cc49ac6f4cdd27e622868326ed6371e"},
"swoosh": {:hex, :swoosh, "1.10.2", "77acdc1261de404b893e24224d47459d1b42deb02577c7b31514e0a720f949d6", [:mix], [{:cowboy, "~> 1.1 or ~> 2.4", [hex: :cowboy, repo: "hexpm", optional: true]}, {:ex_aws, "~> 2.1", [hex: :ex_aws, repo: "hexpm", optional: true]}, {:finch, "~> 0.6", [hex: :finch, repo: "hexpm", optional: true]}, {:gen_smtp, "~> 0.13 or ~> 1.0", [hex: :gen_smtp, repo: "hexpm", optional: true]}, {:hackney, "~> 1.9", [hex: :hackney, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:mail, "~> 0.2", [hex: :mail, repo: "hexpm", optional: true]}, {:mime, "~> 1.1 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_cowboy, ">= 1.0.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1736faf374ed49c6091845cdfd5b3a68c88c5f2bfd989447d12bffafc0dda03a"},
"syslog": {:hex, :syslog, "1.1.0", "6419a232bea84f07b56dc575225007ffe34d9fdc91abe6f1b2f254fd71d8efc2", [:rebar3], [], "hexpm", "4c6a41373c7e20587be33ef841d3de6f3beba08519809329ecc4d27b15b659e1"},
"table_rex": {:hex, :table_rex, "3.1.1", "0c67164d1714b5e806d5067c1e96ff098ba7ae79413cc075973e17c38a587caa", [:mix], [], "hexpm", "678a23aba4d670419c23c17790f9dcd635a4a89022040df7d5d772cb21012490"},
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},

View file

@ -0,0 +1,9 @@
defmodule Pleroma.Repo.Migrations.AddUnfollowedDmRestrictions do
use Ecto.Migration
def change do
alter table(:users) do
add(:accepts_direct_messages_from, :string, default: "everybody")
end
end
end

View file

@ -14,13 +14,13 @@ input {
padding: 10px;
margin-top: 5px;
margin-bottom: 10px;
background-color: var(--background-color);
color: var(--primary-text-color);
background-color: transparent;
color: inherit;
border: 0;
transition-property: border-bottom;
transition-duration: 0.35s;
border-bottom: 2px solid #2a384a;
font-size: 14px;
border-bottom: 2px solid var(--faint);
font: inherit;
width: inherit;
box-sizing: border-box;
}
@ -91,26 +91,22 @@ [type="checkbox"]:checked+label:before {
a.button,
button {
width: 100%;
background-color: #1c2a3a;
color: var(--primary-text-color);
background-color: var(--btn);
color: var(--btnText);
border-radius: 4px;
border: none;
padding: 10px 16px;
margin-top: 20px;
margin-bottom: 20px;
text-transform: uppercase;
font-size: 16px;
box-shadow: 0px 0px 2px 0px black,
0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset,
0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
box-shadow: var(--btnShadow);
font: inherit;
}
a.button:hover,
button:hover {
cursor: pointer;
box-shadow: 0px 0px 0px 1px var(--brand-color),
0px 1px 0px 0px rgba(255, 255, 255, 0.2) inset,
0px -1px 0px 0px rgba(0, 0, 0, 0.2) inset;
box-shadow: var(--btnHoverShadow);
}
.actions {
@ -155,4 +151,21 @@ .account-header__display-name {
.account-header__nickname {
font-size: 14px;
color: var(--muted-text-color);
}
}
.oauth {
/* Remote interaction /main/ostatus has such hierarchy, and its header and
* content do not pad themselves:
* (.panel.oauth (h2)
* (form (input)
* (button))) */
padding: 1px 1em;
}
.oauth .container__content {
/* Frontend selection /oauth/authorize needs an inverse because its heading
* and content have their own background and padding:
* (.panel.oauth (form (.container__content (.panel-heading)
* (.panel-content)))) */
margin: -1px -1em;
}

View file

@ -7,6 +7,7 @@ defmodule Mix.Tasks.Pleroma.DatabaseTest do
use Oban.Testing, repo: Pleroma.Repo
alias Pleroma.Activity
alias Pleroma.Bookmark
alias Pleroma.Object
alias Pleroma.Repo
alias Pleroma.User
@ -45,21 +46,25 @@ test "it replaces objects with references" do
end
describe "prune_objects" do
test "it prunes old objects from the database" do
setup do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
date =
old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
%{old_insert_date: old_insert_date}
end
test "it prunes old objects from the database", %{old_insert_date: old_insert_date} do
insert(:note)
%{id: note_remote_public_id} =
:note
|> insert()
|> Ecto.Changeset.change(%{updated_at: date})
|> Ecto.Changeset.change(%{updated_at: old_insert_date})
|> Repo.update!()
note_remote_non_public =
@ -69,7 +74,7 @@ test "it prunes old objects from the database" do
note_remote_non_public
|> Ecto.Changeset.change(%{
updated_at: date,
updated_at: old_insert_date,
data: note_remote_non_public_data |> update_in(["to"], fn _ -> [] end)
})
|> Repo.update!()
@ -83,21 +88,37 @@ test "it prunes old objects from the database" do
refute Object.get_by_id(note_remote_non_public_id)
end
test "with the --keep-non-public option it still keeps non-public posts even if they are not local" do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
test "it cleans up bookmarks", %{old_insert_date: old_insert_date} do
user = insert(:user)
{:ok, old_object_activity} = CommonAPI.post(user, %{status: "yadayada"})
date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
Repo.one(Object)
|> Ecto.Changeset.change(%{updated_at: old_insert_date})
|> Repo.update!()
{:ok, new_object_activity} = CommonAPI.post(user, %{status: "yadayada"})
{:ok, _} = Bookmark.create(user.id, old_object_activity.id)
{:ok, _} = Bookmark.create(user.id, new_object_activity.id)
assert length(Repo.all(Object)) == 2
assert length(Repo.all(Bookmark)) == 2
Mix.Tasks.Pleroma.Database.run(["prune_objects"])
assert length(Repo.all(Object)) == 1
assert length(Repo.all(Bookmark)) == 1
refute Bookmark.get(user.id, old_object_activity.id)
end
test "with the --keep-non-public option it still keeps non-public posts even if they are not local",
%{old_insert_date: old_insert_date} do
insert(:note)
%{id: note_remote_id} =
:note
|> insert()
|> Ecto.Changeset.change(%{updated_at: date})
|> Ecto.Changeset.change(%{updated_at: old_insert_date})
|> Repo.update!()
note_remote_non_public =
@ -107,7 +128,7 @@ test "with the --keep-non-public option it still keeps non-public posts even if
note_remote_non_public
|> Ecto.Changeset.change(%{
updated_at: date,
updated_at: old_insert_date,
data: note_remote_non_public_data |> update_in(["to"], fn _ -> [] end)
})
|> Repo.update!()
@ -120,16 +141,10 @@ test "with the --keep-non-public option it still keeps non-public posts even if
refute Object.get_by_id(note_remote_id)
end
test "with the --keep-threads and --keep-non-public option it keeps old threads with non-public replies even if the interaction is not local" do
test "with the --keep-threads and --keep-non-public option it keeps old threads with non-public replies even if the interaction is not local",
%{old_insert_date: old_insert_date} do
# For non-public we only check Create Activities because only these are relevant for threads
# Flags are always non-public, Announces from relays can be non-public...
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
remote_user1 = insert(:user, local: false)
remote_user2 = insert(:user, local: false)
@ -212,15 +227,9 @@ test "with the --keep-threads option it still keeps non-old threads even with no
assert length(Repo.all(Object)) == 2
end
test "with the --keep-threads option it deletes old threads with no local interaction" do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
test "with the --keep-threads option it deletes old threads with no local interaction", %{
old_insert_date: old_insert_date
} do
remote_user = insert(:user, local: false)
remote_user2 = insert(:user, local: false)
@ -261,15 +270,9 @@ test "with the --keep-threads option it deletes old threads with no local intera
assert length(Repo.all(Object)) == 0
end
test "with the --keep-threads option it keeps old threads with local interaction" do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
test "with the --keep-threads option it keeps old threads with local interaction", %{
old_insert_date: old_insert_date
} do
remote_user = insert(:user, local: false)
local_user = insert(:user, local: true)
@ -326,15 +329,9 @@ test "with the --keep-threads option it keeps old threads with local interaction
assert length(Repo.all(Object)) == 4
end
test "with the --keep-threads option it keeps old threads with bookmarked posts" do
deadline = Pleroma.Config.get([:instance, :remote_post_retention_days]) + 1
old_insert_date =
Timex.now()
|> Timex.shift(days: -deadline)
|> Timex.to_naive_datetime()
|> NaiveDateTime.truncate(:second)
test "with the --keep-threads option it keeps old threads with bookmarked posts", %{
old_insert_date: old_insert_date
} do
remote_user = insert(:user, local: false)
local_user = insert(:user, local: true)

View file

@ -114,6 +114,11 @@ test "it deduces the actor id for gotoSocial" do
{:ok, "https://example.com/users/1234"}
end
test "it deduces the actor ID for streams" do
assert Signature.key_id_to_actor_id("https://example.com/users/1234?operation=getkey") ==
{:ok, "https://example.com/users/1234"}
end
test "it calls webfinger for 'acct:' accounts" do
with_mock(Pleroma.Web.WebFinger,
finger: fn _ -> {:ok, %{"ap_id" => "https://gensokyo.2hu/users/raymoo"}} end

View file

@ -133,5 +133,20 @@ test "should gracefully handle an unsupported language" do
assert {:error, "libre_translate: request failed (code 400)"} =
LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "zoop")
end
test "should work when no detected language is received" do
Tesla.Mock.mock(fn
%{method: :post, url: "http://libre.translate/translate"} ->
%Tesla.Env{
status: 200,
body:
Jason.encode!(%{
translatedText: "I will crush you"
})
}
end)
assert {:ok, "", "I will crush you"} = LibreTranslate.translate("ギュギュ握りつぶしちゃうぞ", nil, "en")
end
end
end

View file

@ -0,0 +1,39 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.UserNoteTest do
alias Pleroma.UserNote
use Pleroma.DataCase, async: false
import Pleroma.Factory
describe "show/2" do
setup do
{:ok, users: insert_list(2, :user)}
end
test "if record does not exist, returns empty string", %{users: [user1, user2]} do
comment = UserNote.show(user1, user2)
assert comment == ""
end
test "if record exists with comment == nil, returns empty string", %{users: [user1, user2]} do
UserNote.create(user1, user2, nil)
comment = UserNote.show(user1, user2)
assert comment == ""
end
test "if record exists with non-nil comment, returns comment", %{users: [user1, user2]} do
expected_comment = "hello"
UserNote.create(user1, user2, expected_comment)
comment = UserNote.show(user1, user2)
assert comment == expected_comment
end
end
end

View file

@ -2756,4 +2756,35 @@ test "should not error when trying to unfollow a hashtag twice" do
assert user.followed_hashtags |> Enum.count() == 0
end
end
describe "accepts_direct_messages?/2" do
test "should return true if the recipient follows the sender and has set accept to :people_i_follow" do
recipient =
insert(:user, %{
accepts_direct_messages_from: :people_i_follow
})
sender = insert(:user)
refute User.accepts_direct_messages?(recipient, sender)
CommonAPI.follow(recipient, sender)
assert User.accepts_direct_messages?(recipient, sender)
end
test "should return true if the recipient has set accept to :everyone" do
recipient = insert(:user, %{accepts_direct_messages_from: :everybody})
sender = insert(:user)
assert User.accepts_direct_messages?(recipient, sender)
end
test "should return false if the receipient set accept to :nobody" do
recipient = insert(:user, %{accepts_direct_messages_from: :nobody})
sender = insert(:user)
refute User.accepts_direct_messages?(recipient, sender)
end
end
end

View file

@ -0,0 +1,52 @@
defmodule Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicyTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.ActivityPub.MRF.DirectMessageDisabledPolicy
alias Pleroma.User
describe "strips recipients" do
test "when the user denies the direct message" do
sender = insert(:user)
recipient = insert(:user, %{accepts_direct_messages_from: :nobody})
refute User.accepts_direct_messages?(recipient, sender)
message = %{
"actor" => sender.ap_id,
"to" => [recipient.ap_id],
"cc" => [],
"type" => "Create",
"object" => %{
"type" => "Note",
"to" => [recipient.ap_id]
}
}
assert {:ok, %{"to" => [], "object" => %{"to" => []}}} =
DirectMessageDisabledPolicy.filter(message)
end
test "when the user does not deny the direct message" do
sender = insert(:user)
recipient = insert(:user, %{accepts_direct_messages_from: :everybody})
assert User.accepts_direct_messages?(recipient, sender)
message = %{
"actor" => sender.ap_id,
"to" => [recipient.ap_id],
"cc" => [],
"type" => "Create",
"object" => %{
"type" => "Note",
"to" => [recipient.ap_id]
}
}
assert {:ok, message} = DirectMessageDisabledPolicy.filter(message)
assert message["to"] == [recipient.ap_id]
assert message["object"]["to"] == [recipient.ap_id]
end
end
end

View file

@ -0,0 +1,45 @@
defmodule Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicyTest do
use Pleroma.DataCase
import Pleroma.Factory
alias Pleroma.Web.ActivityPub.MRF.RejectNewlyCreatedAccountNotesPolicy
describe "reject notes from new accounts" do
test "rejects notes from accounts created more recently than `age`" do
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
sender = insert(:user, %{inserted_at: Timex.now(), local: false})
message = %{
"actor" => sender.ap_id,
"type" => "Create"
}
assert {:reject, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
end
test "does not reject notes from accounts created longer ago" do
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
a_day_ago = Timex.shift(Timex.now(), days: -1)
sender = insert(:user, %{inserted_at: a_day_ago, local: false})
message = %{
"actor" => sender.ap_id,
"type" => "Create"
}
assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
end
test "does not affect local users" do
clear_config([:mrf_reject_newly_created_account_notes, :age], 86_400)
sender = insert(:user, %{inserted_at: Timex.now(), local: true})
message = %{
"actor" => sender.ap_id,
"type" => "Create"
}
assert {:ok, _} = RejectNewlyCreatedAccountNotesPolicy.filter(message)
end
end
end

View file

@ -102,7 +102,13 @@ test "it works as expected with noop policy" do
clear_config([:mrf, :policies], [Pleroma.Web.ActivityPub.MRF.NoOpPolicy])
expected = %{
mrf_policies: ["NoOpPolicy", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"],
mrf_policies: [
"NoOpPolicy",
"HashtagPolicy",
"InlineQuotePolicy",
"NormalizeMarkup",
"DirectMessageDisabledPolicy"
],
mrf_hashtag: %{
federated_timeline_removal: [],
reject: [],
@ -118,7 +124,13 @@ test "it works as expected with mock policy" do
clear_config([:mrf, :policies], [MRFModuleMock])
expected = %{
mrf_policies: ["MRFModuleMock", "HashtagPolicy", "InlineQuotePolicy", "NormalizeMarkup"],
mrf_policies: [
"MRFModuleMock",
"HashtagPolicy",
"InlineQuotePolicy",
"NormalizeMarkup",
"DirectMessageDisabledPolicy"
],
mrf_module_mock: "some config data",
mrf_hashtag: %{
federated_timeline_removal: [],

View file

@ -316,7 +316,7 @@ test "it strips internal reactions" do
test "it correctly processes messages with non-array to field" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Jason.decode!()
|> Map.put("to", "https://www.w3.org/ns/activitystreams#Public")
|> put_in(["object", "to"], "https://www.w3.org/ns/activitystreams#Public")
@ -333,7 +333,7 @@ test "it correctly processes messages with non-array to field" do
test "it correctly processes messages with non-array cc field" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Jason.decode!()
|> Map.put("cc", "http://mastodon.example.org/users/admin/followers")
|> put_in(["object", "cc"], "http://mastodon.example.org/users/admin/followers")
@ -346,7 +346,7 @@ test "it correctly processes messages with non-array cc field" do
test "it correctly processes messages with weirdness in address fields" do
data =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Jason.decode!()
|> Map.put("cc", ["http://mastodon.example.org/users/admin/followers", ["¿"]])
|> put_in(["object", "cc"], ["http://mastodon.example.org/users/admin/followers", ["¿"]])
@ -412,7 +412,7 @@ test "does NOT schedule background fetching of `replies` beyond max thread depth
activity =
File.read!("test/fixtures/mastodon-post-activity.json")
|> Poison.decode!()
|> Jason.decode!()
|> Kernel.put_in(["object", "replies"], replies)
%{activity: activity}

View file

@ -727,4 +727,56 @@ test "actor_type field has a higher priority than bot", %{conn: conn} do
assert account["source"]["pleroma"]["actor_type"] == "Person"
end
end
describe "Updating direct message settings" do
setup do: oauth_access(["write:accounts"])
setup :request_content_type
test "changing to :everybody", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{
accepts_direct_messages_from: "everybody"
})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "everybody"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :everybody
end
test "changing to :nobody", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{accepts_direct_messages_from: "nobody"})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "nobody"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from == :nobody
end
test "changing to :people_i_follow", %{conn: conn} do
account =
conn
|> patch("/api/v1/accounts/update_credentials", %{
accepts_direct_messages_from: "people_i_follow"
})
|> json_response_and_validate_schema(200)
assert account["accepts_direct_messages_from"]
assert account["accepts_direct_messages_from"] == "people_i_follow"
assert Pleroma.User.get_by_ap_id(account["url"]).accepts_direct_messages_from ==
:people_i_follow
end
test "changing to an unsupported value", %{conn: conn} do
conn
|> patch("/api/v1/accounts/update_credentials", %{
accepts_direct_messages_from: "unsupported"
})
|> json_response(400)
end
end
end

View file

@ -129,7 +129,7 @@ test "parses twitter card" do
}}
end
test "parses OEmbed" do
test "parses OEmbed and filters HTML tags" do
assert Parser.parse("http://example.com/oembed") ==
{:ok,
%{
@ -139,7 +139,7 @@ test "parses OEmbed" do
"flickr_type" => "photo",
"height" => "768",
"html" =>
"<a data-flickr-embed=\"true\" href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"></a><script async src=\"https://embedr.flickr.com/assets/client-code.js\" charset=\"utf-8\"></script>",
"<a href=\"https://www.flickr.com/photos/bees/2362225867/\" title=\"Bacon Lollys by \u202E\u202D\u202Cbees\u202C, on Flickr\"><img src=\"https://farm4.staticflickr.com/3040/2362225867_4a87ab8baf_b.jpg\" width=\"1024\" height=\"768\" alt=\"Bacon Lollys\"/></a>",
"license" => "All Rights Reserved",
"license_id" => 0,
"provider_name" => "Flickr",