summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Tashkinov <ivantashkinov@gmail.com>2020-02-20 15:00:48 +0300
committerIvan Tashkinov <ivantashkinov@gmail.com>2020-02-20 15:00:48 +0300
commit0c65a8c3d02a5a9dc3a0a54fef3b86130cf3c0dd (patch)
tree0e0f2ad4f7317b44e11f1df4d2e5fc9a301007e1
parent343229465753ebcc59002a2dd604a910a8ce462d (diff)
parente0b2de63853e9a14b72faddf6e1180a098728205 (diff)
Merge remote-tracking branch 'remotes/origin/develop' into 1505-threads-federation
# Conflicts: # config/config.exs
-rw-r--r--CHANGELOG.md1
-rw-r--r--config/config.exs6
-rw-r--r--config/description.exs76
-rw-r--r--config/test.exs2
-rw-r--r--docs/configuration/cheatsheet.md4
-rw-r--r--docs/configuration/mrf.md45
-rw-r--r--lib/pleroma/emails/new_users_digest_email.ex32
-rw-r--r--lib/pleroma/web/mastodon_api/views/status_view.ex6
-rw-r--r--lib/pleroma/web/templates/email/new_users_digest.html.eex158
-rw-r--r--lib/pleroma/web/templates/layout/email_styled.html.eex193
-rw-r--r--lib/pleroma/web/views/email_view.ex4
-rw-r--r--lib/pleroma/workers/cron/new_users_digest_worker.ex60
-rw-r--r--test/activity_test.exs5
-rw-r--r--test/http/request_builder_test.exs1
-rw-r--r--test/object_test.exs1
-rw-r--r--test/plugs/admin_secret_authentication_plug_test.exs2
-rw-r--r--test/plugs/http_security_plug_test.exs1
-rw-r--r--test/plugs/remote_ip_test.exs4
-rw-r--r--test/plugs/user_enabled_plug_test.exs5
-rw-r--r--test/repo_test.exs12
-rw-r--r--test/support/helpers.ex6
-rw-r--r--test/user_search_test.exs6
-rw-r--r--test/user_test.exs18
-rw-r--r--test/web/activity_pub/activity_pub_test.exs7
-rw-r--r--test/web/activity_pub/mrf/hellthread_policy_test.exs2
-rw-r--r--test/web/activity_pub/mrf/keyword_policy_test.exs2
-rw-r--r--test/web/activity_pub/mrf/mention_policy_test.exs2
-rw-r--r--test/web/activity_pub/mrf/subchain_policy_test.exs2
-rw-r--r--test/web/activity_pub/transmogrifier/follow_handling_test.exs2
-rw-r--r--test/web/admin_api/admin_api_controller_test.exs2
-rw-r--r--test/web/common_api/common_api_test.exs1
-rw-r--r--test/web/mastodon_api/controllers/account_controller_test.exs10
-rw-r--r--test/web/mastodon_api/controllers/status_controller_test.exs20
-rw-r--r--test/web/media_proxy/media_proxy_controller_test.exs7
-rw-r--r--test/web/media_proxy/media_proxy_test.exs4
-rw-r--r--test/web/metadata/opengraph_test.exs2
-rw-r--r--test/web/metadata/twitter_card_test.exs2
-rw-r--r--test/web/node_info_test.exs44
-rw-r--r--test/web/oauth/oauth_controller_test.exs3
-rw-r--r--test/web/plugs/federating_plug_test.exs3
-rw-r--r--test/web/streamer/streamer_test.exs2
-rw-r--r--test/web/twitter_api/twitter_api_test.exs44
-rw-r--r--test/web/twitter_api/util_controller_test.exs1
-rw-r--r--test/workers/cron/new_users_digest_worker_test.exs32
44 files changed, 676 insertions, 166 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bdd6ec432..e0ab69d8b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -72,6 +72,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- User notification settings: Add `privacy_option` option.
- Support for custom Elixir modules (such as MRF policies)
- User settings: Add _This account is a_ option.
+- A new users admin digest email
- OAuth: admin scopes support (relevant setting: `[:auth, :enforce_oauth_admin_scope_usage]`).
- ActivityPub: support for `replies` collection (output for outgoing federation & fetching on incoming federation).
<details>
diff --git a/config/config.exs b/config/config.exs
index cb1551c2a..47b53d5af 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -483,12 +483,14 @@ config :pleroma, Oban,
background: 5,
remote_fetcher: 2,
attachments_cleanup: 5
+ new_users_digest: 1
],
crontab: [
{"0 0 * * *", Pleroma.Workers.Cron.ClearOauthTokenWorker},
{"0 * * * *", Pleroma.Workers.Cron.StatsWorker},
{"* * * * *", Pleroma.Workers.Cron.PurgeExpiredActivitiesWorker},
- {"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker}
+ {"0 0 * * 0", Pleroma.Workers.Cron.DigestEmailsWorker},
+ {"0 0 * * *", Pleroma.Workers.Cron.NewUsersDigestWorker}
]
config :pleroma, :workers,
@@ -562,6 +564,8 @@ config :pleroma, Pleroma.Emails.UserEmail,
text_muted_color: "#b9b9ba"
}
+config :pleroma, Pleroma.Emails.NewUsersDigestEmail, enabled: false
+
config :prometheus, Pleroma.Web.Endpoint.MetricsExporter, path: "/api/pleroma/app_metrics"
config :pleroma, Pleroma.ScheduledActivity,
diff --git a/config/description.exs b/config/description.exs
index 10f266555..f0d1077fd 100644
--- a/config/description.exs
+++ b/config/description.exs
@@ -101,7 +101,7 @@ config :pleroma, :config_description, [
%{
key: :versions,
type: {:list, :atom},
- description: "List of TLS version to use",
+ description: "List of TLS versions to use",
suggestions: [:tlsv1, ":tlsv1.1", ":tlsv1.2"]
}
]
@@ -534,7 +534,8 @@ config :pleroma, :config_description, [
%{
key: :description,
type: :string,
- description: "The instance's description, can be seen in nodeinfo and /api/v1/instance",
+ description:
+ "The instance's description. It can be seen in nodeinfo and `/api/v1/instance`",
suggestions: [
"Very cool instance"
]
@@ -770,7 +771,7 @@ config :pleroma, :config_description, [
key: :cleanup_attachments,
type: :boolean,
description: """
- "Enable to remove associated attachments when status is removed.
+ Enable to remove associated attachments when status is removed.
This will not affect duplicates and attachments without status.
Enabling this will increase load to database when deleting statuses on larger instances.
"""
@@ -838,7 +839,7 @@ config :pleroma, :config_description, [
%{
key: :healthcheck,
type: :boolean,
- description: "If enabled, system data will be shown on /api/pleroma/healthcheck"
+ description: "If enabled, system data will be shown on `/api/pleroma/healthcheck`"
},
%{
key: :remote_post_retention_days,
@@ -1296,14 +1297,14 @@ config :pleroma, :config_description, [
%{
key: :media_removal,
type: {:list, :string},
- description: "List of instances to remove medias from",
+ description: "List of instances to strip media attachments from",
suggestions: ["example.com", "*.example.com"]
},
%{
key: :media_nsfw,
label: "Media NSFW",
type: {:list, :string},
- description: "List of instances to put medias as NSFW (sensitive) from",
+ description: "List of instances to tag all media as NSFW (sensitive) from",
suggestions: ["example.com", "*.example.com"]
},
%{
@@ -1422,21 +1423,21 @@ config :pleroma, :config_description, [
key: :reject,
type: [:string, :regex],
description:
- "A list of patterns which result in message being rejected, each pattern can be a string or a regular expression.",
+ "A list of patterns which result in message being rejected. Each pattern can be a string or a regular expression.",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :federated_timeline_removal,
type: [:string, :regex],
description:
- "A list of patterns which result in message being removed from federated timelines (a.k.a unlisted), each pattern can be a string or a regular expression.",
+ "A list of patterns which result in message being removed from federated timelines (a.k.a unlisted). Each pattern can be a string or a regular expression.",
suggestions: ["foo", ~r/foo/iu]
},
%{
key: :replace,
type: [{:tuple, :string, :string}, {:tuple, :regex, :string}],
description:
- "A list of tuples containing {pattern, replacement}, pattern can be a string or a regular expression.",
+ "A list of tuples containing {pattern, replacement}. Each pattern can be a string or a regular expression.",
suggestions: [{"foo", "bar"}, {~r/foo/iu, "bar"}]
}
]
@@ -1451,7 +1452,7 @@ config :pleroma, :config_description, [
%{
key: :actors,
type: {:list, :string},
- description: "A list of actors, for which to drop any posts mentioning",
+ description: "A list of actors for which any post mentioning them will be dropped.",
suggestions: ["actor1", "actor2"]
}
]
@@ -1861,9 +1862,8 @@ config :pleroma, :config_description, [
type: :string,
description:
"A mailto link for the administrative contact." <>
- " It's best if this email is not a personal email address, but rather a group email so that if a person leaves an organization," <>
- " is unavailable for an extended period, or otherwise can't respond, someone else on the list can.",
- suggestions: ["Subject"]
+ " It's best if this email is not a personal email address, but rather a group email to the instance moderation team.",
+ suggestions: ["mailto:moderators@pleroma.com"]
},
%{
key: :public_key,
@@ -1930,7 +1930,7 @@ config :pleroma, :config_description, [
key: :admin_token,
type: :string,
description: "Token",
- suggestions: ["some_random_token"]
+ suggestions: ["We recommend a secure random string or UUID"]
}
]
},
@@ -1992,6 +1992,7 @@ config :pleroma, :config_description, [
"Background jobs queues (keys: queues, values: max numbers of concurrent jobs)",
suggestions: [
activity_expiration: 10,
+ attachments_cleanup: 5,
background: 5,
federator_incoming: 50,
federator_outgoing: 50,
@@ -2008,6 +2009,12 @@ config :pleroma, :config_description, [
suggestions: [10]
},
%{
+ key: :attachments_cleanup,
+ type: :integer,
+ description: "Attachment deletion queue",
+ suggestions: [5]
+ },
+ %{
key: :background,
type: :integer,
description: "Background queue",
@@ -2105,7 +2112,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enables/disables RichMedia."
+ description: "Enables RichMedia parsing of URLs."
},
%{
key: :ignore_hosts,
@@ -2151,8 +2158,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description:
- "If enabled, when a new user is federated with, fetch some of their latest posts"
+ description: "Fetch posts when a new user is federated with"
},
%{
key: :pages,
@@ -2171,13 +2177,13 @@ config :pleroma, :config_description, [
%{
key: :class,
type: [:string, false],
- description: "Specify the class to be added to the generated link. `False` to clear",
+ description: "Specify the class to be added to the generated link. Disable to clear",
suggestions: ["auto-linker", false]
},
%{
key: :rel,
type: [:string, false],
- description: "Override the rel attribute. `False` to clear",
+ description: "Override the rel attribute. Disable to clear",
suggestions: ["ugc", "noopener noreferrer", false]
},
%{
@@ -2287,7 +2293,7 @@ config :pleroma, :config_description, [
key: :ssl,
label: "SSL",
type: :boolean,
- description: "`True` to use SSL, usually implies the port 636"
+ description: "Enable to use SSL, usually implies the port 636"
},
%{
key: :sslopts,
@@ -2314,7 +2320,7 @@ config :pleroma, :config_description, [
key: :tls,
label: "TLS",
type: :boolean,
- description: "`True` to start TLS, usually implies the port 389"
+ description: "Enable to use STARTTLS, usually implies the port 389"
},
%{
key: :tlsopts,
@@ -2364,7 +2370,7 @@ config :pleroma, :config_description, [
description:
"OAuth admin scope requirement toggle. " <>
"If enabled, admin actions explicitly demand admin OAuth scope(s) presence in OAuth token " <>
- "(client app must support admin scopes). If `false` and token doesn't have admin scope(s)," <>
+ "(client app must support admin scopes). If disabled and token doesn't have admin scope(s)," <>
"`is_admin` user flag grants access to admin-specific actions."
},
%{
@@ -2386,7 +2392,7 @@ config :pleroma, :config_description, [
key: :oauth_consumer_strategies,
type: {:list, :string},
description:
- "The list of enabled OAuth consumer strategies; by default it's set by OAUTH_CONSUMER_STRATEGIES environment variable." <>
+ "The list of enabled OAuth consumer strategies. By default it's set by OAUTH_CONSUMER_STRATEGIES environment variable." <>
" Each entry in this space-delimited string should be of format \"strategy\" or \"strategy:dependency\"" <>
" (e.g. twitter or keycloak:ueberauth_keycloak_strategy in case dependency is named differently than ueberauth_<strategy>).",
suggestions: ["twitter", "keycloak:ueberauth_keycloak_strategy"]
@@ -2504,6 +2510,20 @@ config :pleroma, :config_description, [
},
%{
group: :pleroma,
+ key: Pleroma.Emails.NewUsersDigestEmail,
+ type: :group,
+ description: "New users admin email digest",
+ children: [
+ %{
+ key: :enabled,
+ type: :boolean,
+ description: "enables new users admin digest email when `true`",
+ suggestions: [false]
+ }
+ ]
+ },
+ %{
+ group: :pleroma,
key: :oauth2,
type: :group,
description: "Configure OAuth 2 provider capabilities",
@@ -2523,7 +2543,7 @@ config :pleroma, :config_description, [
%{
key: :clean_expired_tokens,
type: :boolean,
- description: "Enable a background job to clean expired oauth tokens. Default: `false`."
+ description: "Enable a background job to clean expired oauth tokens. Default: disabled."
}
]
},
@@ -2583,7 +2603,7 @@ config :pleroma, :config_description, [
%{
key: :rum_enabled,
type: :boolean,
- description: "If RUM indexes should be used. Default: `false`"
+ description: "If RUM indexes should be used. Default: disabled"
}
]
},
@@ -2969,7 +2989,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enable/disable the plug. Default: `false`."
+ description: "Enable/disable the plug. Default: disabled."
},
%{
key: :headers,
@@ -3023,7 +3043,7 @@ config :pleroma, :config_description, [
%{
key: :enabled,
type: :boolean,
- description: "Enables the rendering of static HTML. Defaults to `false`."
+ description: "Enables the rendering of static HTML. Default: disabled."
}
]
},
@@ -3099,7 +3119,7 @@ config :pleroma, :config_description, [
key: :configurable_from_database,
type: :boolean,
description:
- "Allow transferring configuration to DB with the subsequent customization from Admin api. Defaults to `false`"
+ "Allow transferring configuration to DB with the subsequent customization from Admin api. Default: disabled"
}
]
}
diff --git a/config/test.exs b/config/test.exs
index 078c46205..6bea09380 100644
--- a/config/test.exs
+++ b/config/test.exs
@@ -94,6 +94,8 @@ config :pleroma, Pleroma.ReverseProxy.Client, Pleroma.ReverseProxy.ClientMock
config :pleroma, :modules, runtime_dir: "test/fixtures/modules"
+config :pleroma, Pleroma.Emails.NewUsersDigestEmail, enabled: true
+
if File.exists?("./config/test.secret.exs") do
import_config "test.secret.exs"
else
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
index 2bd935983..c9559fe85 100644
--- a/docs/configuration/cheatsheet.md
+++ b/docs/configuration/cheatsheet.md
@@ -501,6 +501,10 @@ Email notifications settings.
- `:logo` - a path to a custom logo. Set it to `nil` to use the default Pleroma logo.
- `:styling` - a map with color settings for email templates.
+### Pleroma.Emails.NewUsersDigestEmail
+
+- `:enabled` - a boolean, enables new users admin digest email when `true`. Defaults to `false`.
+
## Background jobs
### Oban
diff --git a/docs/configuration/mrf.md b/docs/configuration/mrf.md
index 45be18fc5..c3957c255 100644
--- a/docs/configuration/mrf.md
+++ b/docs/configuration/mrf.md
@@ -1,4 +1,5 @@
# Message Rewrite Facility
+
The Message Rewrite Facility (MRF) is a subsystem that is implemented as a series of hooks that allows the administrator to rewrite or discard messages.
Possible uses include:
@@ -10,7 +11,8 @@ Possible uses include:
* removing media from messages
* sending only public messages to a specific instance
-The MRF provides user-configurable policies. The default policy is `NoOpPolicy`, which disables the MRF functionality. Pleroma also includes an easy to use policy called `SimplePolicy` which maps messages matching certain pre-defined criterion to actions built into the policy module.
+The MRF provides user-configurable policies. The default policy is `NoOpPolicy`, which disables the MRF functionality. Pleroma also includes an easy to use policy called `SimplePolicy` which maps messages matching certain pre-defined criterion to actions built into the policy module.
+
It is possible to use multiple, active MRF policies at the same time.
## Quarantine Instances
@@ -18,7 +20,8 @@ It is possible to use multiple, active MRF policies at the same time.
You have the ability to prevent from private / followers-only messages from federating with specific instances. Which means they will only get the public or unlisted messages from your instance.
If, for example, you're using `MIX_ENV=prod` aka using production mode, you would open your configuration file located in `config/prod.secret.exs` and edit or add the option under your `:instance` config object. Then you would specify the instance within quotes.
-```
+
+```elixir
config :pleroma, :instance,
[...]
quarantined_instances: ["instance.example", "other.example"]
@@ -28,15 +31,15 @@ config :pleroma, :instance,
`SimplePolicy` is capable of handling most common admin tasks.
-To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this:
+To use `SimplePolicy`, you must enable it. Do so by adding the following to your `:instance` config object, so that it looks like this:
-```
+```elixir
config :pleroma, :instance,
[...]
rewrite_policy: Pleroma.Web.ActivityPub.MRF.SimplePolicy
```
-Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
+Once `SimplePolicy` is enabled, you can configure various groups in the `:mrf_simple` config object. These groups are:
* `media_removal`: Servers in this group will have media stripped from incoming messages.
* `media_nsfw`: Servers in this group will have the #nsfw tag and sensitive setting injected into incoming messages which contain media.
@@ -50,7 +53,7 @@ Servers should be configured as lists.
This example will enable `SimplePolicy`, block media from `illegalporn.biz`, mark media as NSFW from `porn.biz` and `porn.business`, reject messages from `spam.com`, remove messages from `spam.university` from the federated timeline and block reports (flags) from `whiny.whiner`:
-```
+```elixir
config :pleroma, :instance,
rewrite_policy: [Pleroma.Web.ActivityPub.MRF.SimplePolicy]
@@ -60,30 +63,31 @@ config :pleroma, :mrf_simple,
reject: ["spam.com"],
federated_timeline_removal: ["spam.university"],
report_removal: ["whiny.whiner"]
-
```
### Use with Care
-The effects of MRF policies can be very drastic. It is important to use this functionality carefully. Always try to talk to an admin before writing an MRF policy concerning their instance.
+The effects of MRF policies can be very drastic. It is important to use this functionality carefully. Always try to talk to an admin before writing an MRF policy concerning their instance.
## Writing your own MRF Policy
-As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting.
+As discussed above, the MRF system is a modular system that supports pluggable policies. This means that an admin may write a custom MRF policy in Elixir or any other language that runs on the Erlang VM, by specifying the module name in the `rewrite_policy` config setting.
For example, here is a sample policy module which rewrites all messages to "new message content":
```elixir
-# This is a sample MRF policy which rewrites all Notes to have "new message
-# content."
-defmodule Site.RewritePolicy do
- @behavior Pleroma.Web.ActivityPub.MRF
+defmodule Pleroma.Web.ActivityPub.MRF.RewritePolicy do
+ @moduledoc "MRF policy which rewrites all Notes to have 'new message content'."
+ @behaviour Pleroma.Web.ActivityPub.MRF
# Catch messages which contain Note objects with actual data to filter.
# Capture the object as `object`, the message content as `content` and the
# message itself as `message`.
@impl true
- def filter(%{"type" => Create", "object" => {"type" => "Note", "content" => content} = object} = message)
+ def filter(
+ %{"type" => "Create", "object" => %{"type" => "Note", "content" => content} = object} =
+ message
+ )
when is_binary(content) do
# Subject / CW is stored as summary instead of `name` like other AS2 objects
# because of Mastodon doing it that way.
@@ -106,17 +110,22 @@ defmodule Site.RewritePolicy do
# Let all other messages through without modifying them.
@impl true
def filter(message), do: {:ok, message}
+
+ @impl true
+ def describe do
+ {:ok, %{mrf_sample: %{content: "new message content"}}}`
+ end
end
```
-If you save this file as `lib/site/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so:
+If you save this file as `lib/pleroma/web/activity_pub/mrf/rewrite_policy.ex`, it will be included when you next rebuild Pleroma. You can enable it in the configuration like so:
-```
+```elixir
config :pleroma, :instance,
rewrite_policy: [
Pleroma.Web.ActivityPub.MRF.SimplePolicy,
- Site.RewritePolicy
+ Pleroma.Web.ActivityPub.MRF.RewritePolicy
]
```
-Please note that the Pleroma developers consider custom MRF policy modules to fall under the purview of the AGPL. As such, you are obligated to release the sources to your custom MRF policy modules upon request.
+Please note that the Pleroma developers consider custom MRF policy modules to fall under the purview of the AGPL. As such, you are obligated to release the sources to your custom MRF policy modules upon request.
diff --git a/lib/pleroma/emails/new_users_digest_email.ex b/lib/pleroma/emails/new_users_digest_email.ex
new file mode 100644
index 000000000..7d16b807f
--- /dev/null
+++ b/lib/pleroma/emails/new_users_digest_email.ex
@@ -0,0 +1,32 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Emails.NewUsersDigestEmail do
+ use Phoenix.Swoosh, view: Pleroma.Web.EmailView, layout: {Pleroma.Web.LayoutView, :email_styled}
+
+ defp instance_notify_email do
+ Pleroma.Config.get([:instance, :notify_email]) || Pleroma.Config.get([:instance, :email])
+ end
+
+ def new_users(to, users_and_statuses) do
+ instance_name = Pleroma.Config.get([:instance, :name])
+ styling = Pleroma.Config.get([Pleroma.Emails.UserEmail, :styling])
+
+ logo_url =
+ Pleroma.Web.Endpoint.url() <>
+ Pleroma.Config.get([:frontend_configurations, :pleroma_fe, :logo])
+
+ new()
+ |> to({to.name, to.email})
+ |> from({instance_name, instance_notify_email()})
+ |> subject("#{instance_name} New Users")
+ |> render_body("new_users_digest.html", %{
+ title: "New Users",
+ users_and_statuses: users_and_statuses,
+ instance: instance_name,
+ styling: styling,
+ logo_url: logo_url
+ })
+ end
+end
diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex
index d4695c1c6..6b0fe9215 100644
--- a/lib/pleroma/web/mastodon_api/views/status_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/status_view.ex
@@ -175,9 +175,11 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
expires_at =
with true <- client_posted_this_activity,
- expiration when not is_nil(expiration) <-
+ %ActivityExpiration{scheduled_at: scheduled_at} <-
ActivityExpiration.get_by_activity_id(activity.id) do
- expiration.scheduled_at
+ scheduled_at
+ else
+ _ -> nil
end
thread_muted? =
diff --git a/lib/pleroma/web/templates/email/new_users_digest.html.eex b/lib/pleroma/web/templates/email/new_users_digest.html.eex
new file mode 100644
index 000000000..40d9b8381
--- /dev/null
+++ b/lib/pleroma/web/templates/email/new_users_digest.html.eex
@@ -0,0 +1,158 @@
+<%= for {user, total_statuses, latest_status} <- @users_and_statuses do %>
+ <%# user card START %>
+ <div style="background-color:transparent;">
+ <div class="block-grid mixed-two-up no-stack"
+ style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
+ <div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
+ <!--[if (mso)|(IE)]><td align="center" width="147" style="background-color:<%= @styling.content_background_color%>;width:76px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 20px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num3"
+ style="display: table-cell; vertical-align: top; max-width: 320px; min-width: 76px; width: 76px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 20px;">
+ <!--<![endif]-->
+ <div align="left" class="img-container left "
+ style="padding-right: 0px;padding-left: 0px;">
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr style="line-height:0px"><td style="padding-right: 0px;padding-left: 0px;" align="left"><![endif]--><img
+ alt="<%= user.name %>" border="0" class="left " src="<%= avatar_url(user) %>"
+ style="text-decoration: none; -ms-interpolation-mode: bicubic; border: 0; height: auto; width: 100%; max-width: 76px; display: block;"
+ title="<%= user.name %>" width="76" />
+ <!--[if mso]></td></tr></table><![endif]-->
+ </div>
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td><td align="center" width="442" style="background-color:<%= @styling.content_background_color%>;width:442px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num9"
+ style="display: table-cell; vertical-align: top; min-width: 320px; max-width: 441px; width: 442px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
+ <!--<![endif]-->
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
+ <div
+ style="color:<%= @styling.text_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
+ <div
+ style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_color %>;">
+ <p style="font-size: 14px; line-height: 19px; margin: 0;"><span
+ style="font-size: 16px; color: <%= @styling.text_color %>;"><%= user.name %></span></p>
+ <p style="font-size: 14px; line-height: 19px; margin: 0;"><span
+ style="font-size: 16px;"><%= link "@" <> user.nickname, style: "color: #{@styling.link_color};text-decoration: none;", to: admin_user_url(user) %></span></p>
+ <p style="font-size: 14px; line-height: 19px; margin: 0;"><span
+ style="font-size: 16px;">Total: <%= total_statuses %></span></p>
+ </div>
+ </div>
+ <!--[if mso]></td></tr></table><![endif]-->
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
+ </div>
+ </div>
+ </div>
+ <%# user card END %>
+
+ <%= if latest_status do %>
+ <div style="background-color:transparent;">
+ <div class="block-grid"
+ style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
+ <div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
+ <!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 15px; padding-left: 15px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num12"
+ style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 15px; padding-left: 15px;">
+ <!--<![endif]-->
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
+ <div
+ style="color:<%= @styling.text_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
+ <div
+ style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_color %>;">
+ <span style="font-size: 16px; line-height: 19px;"><%= raw latest_status.object.data["content"] %></span></div>
+ </div>
+ <!--[if mso]></td></tr></table><![endif]-->
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 15px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
+ <div
+ style="color:<%= @styling.text_muted_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:15px;">
+ <div
+ style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_muted_color %>;">
+ <p style="font-size: 14px; line-height: 16px; margin: 0;"><%= format_date latest_status.object.data["published"] %></p>
+ </div>
+ </div>
+ <!--[if mso]></td></tr></table><![endif]-->
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
+ </div>
+ </div>
+ </div>
+ <% end %>
+ <%# divider start %>
+ <div style="background-color:transparent;">
+ <div class="block-grid"
+ style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
+ <div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
+ <!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num12"
+ style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
+ <!--<![endif]-->
+ <table border="0" cellpadding="0" cellspacing="0" class="divider" role="presentation"
+ style="table-layout: fixed; vertical-align: top; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; min-width: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"
+ valign="top" width="100%">
+ <tbody>
+ <tr style="vertical-align: top;" valign="top">
+ <td class="divider_inner"
+ style="word-break: break-word; vertical-align: top; min-width: 100%; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; padding-top: 10px; padding-right: 10px; padding-bottom: 10px; padding-left: 10px;"
+ valign="top">
+ <table align="center" border="0" cellpadding="0" cellspacing="0" class="divider_content"
+ height="0" role="presentation"
+ style="table-layout: fixed; vertical-align: top; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; width: 100%; border-top: 1px solid <%= @styling.text_color %>; height: 0px;"
+ valign="top" width="100%">
+ <tbody>
+ <tr style="vertical-align: top;" valign="top">
+ <td height="0"
+ style="word-break: break-word; vertical-align: top; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%;"
+ valign="top"><span></span></td>
+ </tr>
+ </tbody>
+ </table>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
+ </div>
+ </div>
+ </div>
+
+ <%# divider end %>
+ <%# user card END %>
+<% end %>
diff --git a/lib/pleroma/web/templates/layout/email_styled.html.eex b/lib/pleroma/web/templates/layout/email_styled.html.eex
new file mode 100644
index 000000000..ca2caaf4d
--- /dev/null
+++ b/lib/pleroma/web/templates/layout/email_styled.html.eex
@@ -0,0 +1,193 @@
+<!DOCTYPE html
+ PUBLIC "-//W3C//DTD XHTML 1.0 Transitional //EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+
+<html xmlns="http://www.w3.org/1999/xhtml" xmlns:o="urn:schemas-microsoft-com:office:office"
+ xmlns:v="urn:schemas-microsoft-com:vml">
+
+<head>
+ <!--[if gte mso 9]><xml><o:OfficeDocumentSettings><o:AllowPNG/><o:PixelsPerInch>96</o:PixelsPerInch></o:OfficeDocumentSettings></xml><![endif]-->
+ <meta content="text/html; charset=utf-8" http-equiv="Content-Type" />
+ <meta content="width=device-width" name="viewport" />
+ <!--[if !mso]><!-->
+ <meta content="IE=edge" http-equiv="X-UA-Compatible" />
+ <!--<![endif]-->
+ <title><%= @email.subject %></title>
+ <!--[if !mso]><!-->
+ <!--<![endif]-->
+ <style type="text/css">
+ body {
+ margin: 0;
+ padding: 0;
+ }
+
+ a {
+
+ color: <%= @styling.link_color %>;
+ text-decoration: none;
+ }
+
+ table,
+ td,
+ tr {
+ vertical-align: top;
+ border-collapse: collapse;
+ }
+
+ * {
+ line-height: inherit;
+ }
+
+ a[x-apple-data-detectors=true] {
+ color: inherit !important;
+ text-decoration: none !important;
+ }
+ </style>
+ <style id="media-query" type="text/css">
+ @media (max-width: 610px) {
+
+ .block-grid,
+ .col {
+ min-width: 320px !important;
+ max-width: 100% !important;
+ display: block !important;
+ }
+
+ .block-grid {
+ width: 100% !important;
+ }
+
+ .col {
+ width: 100% !important;
+ }
+
+ .col>div {
+ margin: 0 auto;
+ }
+
+ .no-stack .col {
+ min-width: 0 !important;
+ display: table-cell !important;
+ }
+
+ .no-stack.two-up .col {
+ width: 50% !important;
+ }
+
+ .no-stack .col.num4 {
+ width: 33% !important;
+ }
+
+ .no-stack .col.num8 {
+ width: 66% !important;
+ }
+
+ .no-stack .col.num4 {
+ width: 33% !important;
+ }
+
+ .no-stack .col.num3 {
+ width: 25% !important;
+ }
+
+ .no-stack .col.num6 {
+ width: 50% !important;
+ }
+
+ .no-stack .col.num9 {
+ width: 75% !important;
+ }
+
+ }
+ </style>
+</head>
+
+<body class="clean-body" style="margin: 0; padding: 0; -webkit-text-size-adjust: 100%; background-color: <%= @styling.background_color %>;">
+ <!--[if IE]><div class="ie-browser"><![endif]-->
+ <table bgcolor="<%= @styling.background_color %>" cellpadding="0" cellspacing="0" class="nl-container" role="presentation"
+ style="table-layout: fixed; vertical-align: top; min-width: 320px; Margin: 0 auto; border-spacing: 0; border-collapse: collapse; mso-table-lspace: 0pt; mso-table-rspace: 0pt; background-color: <%= @styling.background_color %>; width: 100%;"
+ valign="top" width="100%">
+ <tbody>
+ <tr style="vertical-align: top;" valign="top">
+ <td style="word-break: break-word; vertical-align: top;" valign="top">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center" style="background-color:<%= @styling.background_color %>"><![endif]-->
+
+ <%# header %>
+ <div style="background-color:transparent;">
+ <div class="block-grid"
+ style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
+ <div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
+ <!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num12"
+ style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
+ <!--<![endif]-->
+ <div align="center" class="img-container center"
+ style="padding-right: 0px;padding-left: 0px;">
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr style="line-height:0px"><td style="padding-right: 0px;padding-left: 0px;" align="center"><![endif]--><img
+ align="center" alt="Image" border="0" class="center" src="<%= @logo_url %>"
+ style="text-decoration: none; -ms-interpolation-mode: bicubic; border: 0; height: 80px; width: auto; max-height: 80px; display: block;"
+ title="Image" height="80" />
+ <!--[if mso]></td></tr></table><![endif]-->
+ </div>
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
+ </div>
+ </div>
+ </div>
+
+
+ <%# title %>
+ <%= if @title do %>
+ <div style="background-color:transparent;">
+ <div class="block-grid"
+ style="Margin: 0 auto; min-width: 320px; max-width: 590px; overflow-wrap: break-word; word-wrap: break-word; word-break: break-word; background-color: <%= @styling.content_background_color%>;">
+ <div style="border-collapse: collapse;display: table;width: 100%;background-color:<%= @styling.content_background_color%>;">
+ <!--[if (mso)|(IE)]><table width="100%" cellpadding="0" cellspacing="0" border="0" style="background-color:transparent;"><tr><td align="center"><table cellpadding="0" cellspacing="0" border="0" style="width:590px"><tr class="layout-full-width" style="background-color:<%= @styling.content_background_color%>"><![endif]-->
+ <!--[if (mso)|(IE)]><td align="center" width="590" style="background-color:<%= @styling.content_background_color%>;width:590px; border-top: 0px solid transparent; border-left: 0px solid transparent; border-bottom: 0px solid transparent; border-right: 0px solid transparent;" valign="top"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 0px; padding-left: 0px; padding-top:5px; padding-bottom:5px;"><![endif]-->
+ <div class="col num12"
+ style="min-width: 320px; max-width: 590px; display: table-cell; vertical-align: top; width: 590px;">
+ <div style="width:100% !important;">
+ <!--[if (!mso)&(!IE)]><!-->
+ <div
+ style="border-top:0px solid transparent; border-left:0px solid transparent; border-bottom:0px solid transparent; border-right:0px solid transparent; padding-top:5px; padding-bottom:5px; padding-right: 0px; padding-left: 0px;">
+ <!--<![endif]-->
+ <!--[if mso]><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding-right: 10px; padding-left: 10px; padding-top: 10px; padding-bottom: 10px; font-family: Arial, sans-serif"><![endif]-->
+ <div
+ style="line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">
+ <div
+ style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height: 14px; color: <%= @styling.header_color %>;">
+ <p style="line-height: 36px; text-align: center; margin: 0;"><span
+ style="font-size: 30px; color: <%= @styling.header_color %>;"><%= @title %></span></p>
+ </div>
+ </div>
+ <!--[if mso]></td></tr></table><![endif]-->
+ <!--[if (!mso)&(!IE)]><!-->
+ </div>
+ <!--<![endif]-->
+ </div>
+ </div>
+ <!--[if (mso)|(IE)]></td></tr></table><![endif]-->
+ <!--[if (mso)|(IE)]></td></tr></table></td></tr></table><![endif]-->
+ </div>
+ </div>
+ </div>
+ <% end %>
+ <%= render @view_module, @view_template, assigns %>
+
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <!--[if (IE)]></div><![endif]-->
+</body>
+
+</html>
diff --git a/lib/pleroma/web/views/email_view.ex b/lib/pleroma/web/views/email_view.ex
index b506a234b..6b0fbe61e 100644
--- a/lib/pleroma/web/views/email_view.ex
+++ b/lib/pleroma/web/views/email_view.ex
@@ -12,4 +12,8 @@ defmodule Pleroma.Web.EmailView do
|> Timex.parse!("{ISO:Extended:Z}")
|> Timex.format!("{Mshort} {D}, {YYYY} {h24}:{m}")
end
+
+ def admin_user_url(%{id: id}) do
+ Pleroma.Web.Endpoint.url() <> "/pleroma/admin/#/users/" <> id
+ end
end
diff --git a/lib/pleroma/workers/cron/new_users_digest_worker.ex b/lib/pleroma/workers/cron/new_users_digest_worker.ex
new file mode 100644
index 000000000..951c2c054
--- /dev/null
+++ b/lib/pleroma/workers/cron/new_users_digest_worker.ex
@@ -0,0 +1,60 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.Cron.NewUsersDigestWorker do
+ alias Pleroma.Activity
+ alias Pleroma.Repo
+ alias Pleroma.User
+
+ import Ecto.Query
+
+ use Pleroma.Workers.WorkerHelper, queue: "new_users_digest"
+
+ @impl Oban.Worker
+ def perform(_args, _job) do
+ if Pleroma.Config.get([Pleroma.Emails.NewUsersDigestEmail, :enabled]) do
+ today = NaiveDateTime.utc_now() |> Timex.beginning_of_day()
+
+ a_day_ago =
+ today
+ |> Timex.shift(days: -1)
+ |> Timex.beginning_of_day()
+
+ users_and_statuses =
+ %{
+ local: true,
+ order_by: :inserted_at
+ }
+ |> User.Query.build()
+ |> where([u], u.inserted_at >= ^a_day_ago and u.inserted_at < ^today)
+ |> Repo.all()
+ |> Enum.map(fn user ->
+ latest_status =
+ Activity
+ |> Activity.Queries.by_actor(user.ap_id)
+ |> Activity.Queries.by_type("Create")
+ |> Activity.with_preloaded_object()
+ |> order_by(desc: :inserted_at)
+ |> limit(1)
+ |> Repo.one()
+
+ total_statuses =
+ Activity
+ |> Activity.Queries.by_actor(user.ap_id)
+ |> Activity.Queries.by_type("Create")
+ |> Repo.aggregate(:count, :id)
+
+ {user, total_statuses, latest_status}
+ end)
+
+ if users_and_statuses != [] do
+ %{is_admin: true}
+ |> User.Query.build()
+ |> Repo.all()
+ |> Enum.map(&Pleroma.Emails.NewUsersDigestEmail.new_users(&1, users_and_statuses))
+ |> Enum.each(&Pleroma.Emails.Mailer.deliver/1)
+ end
+ end
+ end
+end
diff --git a/test/activity_test.exs b/test/activity_test.exs
index e7ea2bd5e..8aeece96d 100644
--- a/test/activity_test.exs
+++ b/test/activity_test.exs
@@ -138,6 +138,8 @@ defmodule Pleroma.ActivityTest do
}
end
+ clear_config([:instance, :limit_to_local_content])
+
test "finds utf8 text in statuses", %{
japanese_activity: japanese_activity,
user: user
@@ -165,7 +167,6 @@ defmodule Pleroma.ActivityTest do
%{local_activity: local_activity} do
Pleroma.Config.put([:instance, :limit_to_local_content], :all)
assert [^local_activity] = Activity.search(nil, "find me")
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
end
test "find all statuses for unauthenticated users when `limit_to_local_content` is `false`",
@@ -178,8 +179,6 @@ defmodule Pleroma.ActivityTest do
activities = Enum.sort_by(Activity.search(nil, "find me"), & &1.id)
assert [^local_activity, ^remote_activity] = activities
-
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
end
end
diff --git a/test/http/request_builder_test.exs b/test/http/request_builder_test.exs
index 80ef25d7b..113158c9f 100644
--- a/test/http/request_builder_test.exs
+++ b/test/http/request_builder_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.HTTP.RequestBuilderTest do
describe "headers/2" do
clear_config([:http, :send_user_agent])
+ clear_config([:http, :user_agent])
test "don't send pleroma user agent" do
assert RequestBuilder.headers(%{}, []) == %{headers: []}
diff --git a/test/object_test.exs b/test/object_test.exs
index 5690bedec..75f192da2 100644
--- a/test/object_test.exs
+++ b/test/object_test.exs
@@ -75,6 +75,7 @@ defmodule Pleroma.ObjectTest do
describe "delete attachments" do
clear_config([Pleroma.Upload])
+ clear_config([:instance, :cleanup_attachments])
test "Disabled via config" do
Pleroma.Config.put([Pleroma.Upload, :uploader], Pleroma.Uploaders.Local)
diff --git a/test/plugs/admin_secret_authentication_plug_test.exs b/test/plugs/admin_secret_authentication_plug_test.exs
index 506b1f609..e41ce1825 100644
--- a/test/plugs/admin_secret_authentication_plug_test.exs
+++ b/test/plugs/admin_secret_authentication_plug_test.exs
@@ -23,6 +23,8 @@ defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
end
describe "when secret set it assigns an admin user" do
+ clear_config([:admin_token])
+
test "with `admin_token` query parameter", %{conn: conn} do
Pleroma.Config.put(:admin_token, "password123")
diff --git a/test/plugs/http_security_plug_test.exs b/test/plugs/http_security_plug_test.exs
index 9c1c20541..aa285d827 100644
--- a/test/plugs/http_security_plug_test.exs
+++ b/test/plugs/http_security_plug_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.Plugs.HTTPSecurityPlugTest do
clear_config([:http_securiy, :enabled])
clear_config([:http_security, :sts])
+ clear_config([:http_security, :referrer_policy])
describe "http security enabled" do
setup do
diff --git a/test/plugs/remote_ip_test.exs b/test/plugs/remote_ip_test.exs
index d120c588b..93e276454 100644
--- a/test/plugs/remote_ip_test.exs
+++ b/test/plugs/remote_ip_test.exs
@@ -8,6 +8,10 @@ defmodule Pleroma.Plugs.RemoteIpTest do
alias Pleroma.Plugs.RemoteIp
+ import Pleroma.Tests.Helpers, only: [clear_config: 1, clear_config: 2]
+
+ clear_config(RemoteIp)
+
test "disabled" do
Pleroma.Config.put(RemoteIp, enabled: false)
diff --git a/test/plugs/user_enabled_plug_test.exs b/test/plugs/user_enabled_plug_test.exs
index a4035bf0e..b6f297552 100644
--- a/test/plugs/user_enabled_plug_test.exs
+++ b/test/plugs/user_enabled_plug_test.exs
@@ -8,6 +8,8 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do
alias Pleroma.Plugs.UserEnabledPlug
import Pleroma.Factory
+ clear_config([:instance, :account_activation_required])
+
test "doesn't do anything if the user isn't set", %{conn: conn} do
ret_conn =
conn
@@ -18,7 +20,6 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do
test "with a user that's not confirmed and a config requiring confirmation, it removes that user",
%{conn: conn} do
- old = Pleroma.Config.get([:instance, :account_activation_required])
Pleroma.Config.put([:instance, :account_activation_required], true)
user = insert(:user, confirmation_pending: true)
@@ -29,8 +30,6 @@ defmodule Pleroma.Plugs.UserEnabledPlugTest do
|> UserEnabledPlug.call(%{})
assert conn.assigns.user == nil
-
- Pleroma.Config.put([:instance, :account_activation_required], old)
end
test "with a user that is deactivated, it removes that user", %{conn: conn} do
diff --git a/test/repo_test.exs b/test/repo_test.exs
index 5526b0327..2224a6b2b 100644
--- a/test/repo_test.exs
+++ b/test/repo_test.exs
@@ -67,6 +67,8 @@ defmodule Pleroma.RepoTest do
:ok
end
+ clear_config([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
+
test "raises if it detects unapplied migrations" do
assert_raise Pleroma.Repo.UnappliedMigrationsError, fn ->
capture_log(&Repo.check_migrations_applied!/0)
@@ -74,18 +76,8 @@ defmodule Pleroma.RepoTest do
end
test "doesn't do anything if disabled" do
- disable_migration_check =
- Pleroma.Config.get([:i_am_aware_this_may_cause_data_loss, :disable_migration_check])
-
Pleroma.Config.put([:i_am_aware_this_may_cause_data_loss, :disable_migration_check], true)
- on_exit(fn ->
- Pleroma.Config.put(
- [:i_am_aware_this_may_cause_data_loss, :disable_migration_check],
- disable_migration_check
- )
- end)
-
assert :ok == Repo.check_migrations_applied!()
end
end
diff --git a/test/support/helpers.ex b/test/support/helpers.ex
index d36c29cef..db2f08c81 100644
--- a/test/support/helpers.ex
+++ b/test/support/helpers.ex
@@ -26,6 +26,7 @@ defmodule Pleroma.Tests.Helpers do
end
end
+ @doc "Stores initial config value and restores it after *all* test examples are executed."
defmacro clear_config_all(config_path) do
quote do
clear_config_all(unquote(config_path)) do
@@ -33,6 +34,11 @@ defmodule Pleroma.Tests.Helpers do
end
end
+ @doc """
+ Stores initial config value and restores it after *all* test examples are executed.
+ Only use if *all* test examples should work with the same stubbed value
+ (*no* examples set a different value).
+ """
defmacro clear_config_all(config_path, do: yield) do
quote do
setup_all do
diff --git a/test/user_search_test.exs b/test/user_search_test.exs
index 821858476..fe52cc7a1 100644
--- a/test/user_search_test.exs
+++ b/test/user_search_test.exs
@@ -15,6 +15,8 @@ defmodule Pleroma.UserSearchTest do
end
describe "User.search" do
+ clear_config([:instance, :limit_to_local_content])
+
test "excluded invisible users from results" do
user = insert(:user, %{nickname: "john t1000"})
insert(:user, %{invisible: true, nickname: "john t800"})
@@ -127,8 +129,6 @@ defmodule Pleroma.UserSearchTest do
insert(:user, %{nickname: "lain@pleroma.soykaf.com", local: false})
assert [%{id: ^id}] = User.search("lain")
-
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
end
test "find all users for unauthenticated users when `limit_to_local_content` is `false`" do
@@ -145,8 +145,6 @@ defmodule Pleroma.UserSearchTest do
|> Enum.sort()
assert [u1.id, u2.id, u3.id] == results
-
- Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
end
test "does not yield false-positive matches" do
diff --git a/test/user_test.exs b/test/user_test.exs
index 1b5e63bd4..2fc42a90d 100644
--- a/test/user_test.exs
+++ b/test/user_test.exs
@@ -297,15 +297,7 @@ defmodule Pleroma.UserTest do
end
describe "unfollow/2" do
- setup do
- setting = Pleroma.Config.get([:instance, :external_user_synchronization])
-
- on_exit(fn ->
- Pleroma.Config.put([:instance, :external_user_synchronization], setting)
- end)
-
- :ok
- end
+ clear_config([:instance, :external_user_synchronization])
test "unfollow with syncronizes external user" do
Pleroma.Config.put([:instance, :external_user_synchronization], true)
@@ -383,6 +375,7 @@ defmodule Pleroma.UserTest do
password_confirmation: "test",
email: "email@example.com"
}
+
clear_config([:instance, :autofollowed_nicknames])
clear_config([:instance, :welcome_message])
clear_config([:instance, :welcome_user_nickname])
@@ -1754,17 +1747,14 @@ defmodule Pleroma.UserTest do
describe "get_cached_by_nickname_or_id" do
setup do
- limit_to_local_content = Pleroma.Config.get([:instance, :limit_to_local_content])
local_user = insert(:user)
remote_user = insert(:user, nickname: "nickname@example.com", local: false)
- on_exit(fn ->
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local_content)
- end)
-
[local_user: local_user, remote_user: remote_user]
end
+ clear_config([:instance, :limit_to_local_content])
+
test "allows getting remote users by id no matter what :limit_to_local_content is set to", %{
remote_user: remote_user
} do
diff --git a/test/web/activity_pub/activity_pub_test.exs b/test/web/activity_pub/activity_pub_test.exs
index ce68e7d0e..9b7cfee63 100644
--- a/test/web/activity_pub/activity_pub_test.exs
+++ b/test/web/activity_pub/activity_pub_test.exs
@@ -1224,6 +1224,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "deletion" do
+ clear_config([:instance, :rewrite_policy])
+
test "it creates a delete activity and deletes the original object" do
note = insert(:note_activity)
object = Object.normalize(note)
@@ -1327,11 +1329,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
test "it passes delete activity through MRF before deleting the object" do
- rewrite_policy = Pleroma.Config.get([:instance, :rewrite_policy])
Pleroma.Config.put([:instance, :rewrite_policy], Pleroma.Web.ActivityPub.MRF.DropPolicy)
- on_exit(fn -> Pleroma.Config.put([:instance, :rewrite_policy], rewrite_policy) end)
-
note = insert(:note_activity)
object = Object.normalize(note)
@@ -1396,6 +1395,8 @@ defmodule Pleroma.Web.ActivityPub.ActivityPubTest do
end
describe "update" do
+ clear_config([:instance, :max_pinned_statuses])
+
test "it creates an update activity with the new user data" do
user = insert(:user)
{:ok, user} = User.ensure_keys_present(user)
diff --git a/test/web/activity_pub/mrf/hellthread_policy_test.exs b/test/web/activity_pub/mrf/hellthread_policy_test.exs
index eb6ee4d04..a78752a12 100644
--- a/test/web/activity_pub/mrf/hellthread_policy_test.exs
+++ b/test/web/activity_pub/mrf/hellthread_policy_test.exs
@@ -26,6 +26,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.HellthreadPolicyTest do
[user: user, message: message]
end
+ clear_config(:mrf_hellthread)
+
describe "reject" do
test "rejects the message if the recipient count is above reject_threshold", %{
message: message
diff --git a/test/web/activity_pub/mrf/keyword_policy_test.exs b/test/web/activity_pub/mrf/keyword_policy_test.exs
index 602892a37..d950ddd56 100644
--- a/test/web/activity_pub/mrf/keyword_policy_test.exs
+++ b/test/web/activity_pub/mrf/keyword_policy_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.KeywordPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.KeywordPolicy
+ clear_config(:mrf_keyword)
+
setup do
Pleroma.Config.put([:mrf_keyword], %{reject: [], federated_timeline_removal: [], replace: []})
end
diff --git a/test/web/activity_pub/mrf/mention_policy_test.exs b/test/web/activity_pub/mrf/mention_policy_test.exs
index 9fd9c31df..93a55850f 100644
--- a/test/web/activity_pub/mrf/mention_policy_test.exs
+++ b/test/web/activity_pub/mrf/mention_policy_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.MentionPolicyTest do
alias Pleroma.Web.ActivityPub.MRF.MentionPolicy
+ clear_config(:mrf_mention)
+
test "pass filter if allow list is empty" do
Pleroma.Config.delete([:mrf_mention])
diff --git a/test/web/activity_pub/mrf/subchain_policy_test.exs b/test/web/activity_pub/mrf/subchain_policy_test.exs
index f7cbcad48..29065f612 100644
--- a/test/web/activity_pub/mrf/subchain_policy_test.exs
+++ b/test/web/activity_pub/mrf/subchain_policy_test.exs
@@ -14,6 +14,8 @@ defmodule Pleroma.Web.ActivityPub.MRF.SubchainPolicyTest do
"object" => %{"content" => "hi"}
}
+ clear_config([:mrf_subchain, :match_actor])
+
test "it matches and processes subchains when the actor matches a configured target" do
Pleroma.Config.put([:mrf_subchain, :match_actor], %{
~r/^https:\/\/banned.com/s => [DropPolicy]
diff --git a/test/web/activity_pub/transmogrifier/follow_handling_test.exs b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
index 1c88b05c2..fd771ac54 100644
--- a/test/web/activity_pub/transmogrifier/follow_handling_test.exs
+++ b/test/web/activity_pub/transmogrifier/follow_handling_test.exs
@@ -19,6 +19,8 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier.FollowHandlingTest do
end
describe "handle_incoming" do
+ clear_config([:user, :deny_follow_blocked])
+
test "it works for osada follow request" do
user = insert(:user)
diff --git a/test/web/admin_api/admin_api_controller_test.exs b/test/web/admin_api/admin_api_controller_test.exs
index 60db58144..908ef4d37 100644
--- a/test/web/admin_api/admin_api_controller_test.exs
+++ b/test/web/admin_api/admin_api_controller_test.exs
@@ -1893,9 +1893,7 @@ defmodule Pleroma.Web.AdminAPI.AdminAPIControllerTest do
end
test "when configuration from database is off", %{conn: conn} do
- initial = Config.get(:configurable_from_database)
Config.put(:configurable_from_database, false)
- on_exit(fn -> Config.put(:configurable_from_database, initial) end)
conn = get(conn, "/api/pleroma/admin/config")
assert json_response(conn, 400) ==
diff --git a/test/web/common_api/common_api_test.exs b/test/web/common_api/common_api_test.exs
index 11f7c068f..601c32954 100644
--- a/test/web/common_api/common_api_test.exs
+++ b/test/web/common_api/common_api_test.exs
@@ -68,6 +68,7 @@ defmodule Pleroma.Web.CommonAPITest do
har = insert(:user)
jafnhar = insert(:user)
tridi = insert(:user)
+
Pleroma.Config.put([:instance, :safe_dm_mentions], true)
{:ok, activity} =
diff --git a/test/web/mastodon_api/controllers/account_controller_test.exs b/test/web/mastodon_api/controllers/account_controller_test.exs
index e2abcd7c5..8625bb9cf 100644
--- a/test/web/mastodon_api/controllers/account_controller_test.exs
+++ b/test/web/mastodon_api/controllers/account_controller_test.exs
@@ -15,6 +15,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
import Pleroma.Factory
describe "account fetching" do
+ clear_config([:instance, :limit_to_local_content])
+
test "works by id" do
user = insert(:user)
@@ -44,7 +46,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
end
test "works by nickname for remote users" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], false)
user = insert(:user, nickname: "user@example.com", local: false)
@@ -52,13 +53,11 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
test "respects limit_to_local_content == :all for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], :all)
user = insert(:user, nickname: "user@example.com", local: false)
@@ -67,12 +66,10 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
build_conn()
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert json_response(conn, 404)
end
test "respects limit_to_local_content == :unauthenticated for remote user nicknames" do
- limit_to_local = Pleroma.Config.get([:instance, :limit_to_local_content])
Pleroma.Config.put([:instance, :limit_to_local_content], :unauthenticated)
user = insert(:user, nickname: "user@example.com", local: false)
@@ -90,7 +87,6 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
|> assign(:token, insert(:oauth_token, user: reading_user, scopes: ["read:accounts"]))
|> get("/api/v1/accounts/#{user.nickname}")
- Pleroma.Config.put([:instance, :limit_to_local_content], limit_to_local)
assert %{"id" => id} = json_response(conn, 200)
assert id == user.id
end
@@ -677,6 +673,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountControllerTest do
assert json_response(res, 400) == %{"error" => "{\"email\":[\"has already been taken\"]}"}
end
+ clear_config([Pleroma.Plugs.RemoteIp, :enabled])
+
test "rate limit", %{conn: conn} do
Pleroma.Config.put([Pleroma.Plugs.RemoteIp, :enabled], true)
app_token = insert(:oauth_token, user: nil)
diff --git a/test/web/mastodon_api/controllers/status_controller_test.exs b/test/web/mastodon_api/controllers/status_controller_test.exs
index 810f371cb..781c3f7dc 100644
--- a/test/web/mastodon_api/controllers/status_controller_test.exs
+++ b/test/web/mastodon_api/controllers/status_controller_test.exs
@@ -21,6 +21,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
clear_config([:instance, :federating])
clear_config([:instance, :allow_relay])
+ clear_config([:rich_media, :enabled])
describe "posting statuses" do
setup do: oauth_access(["write:statuses"])
@@ -1254,4 +1255,23 @@ defmodule Pleroma.Web.MastodonAPI.StatusControllerTest do
assert [] = json_response(third_conn, 200)
end
+
+ test "expires_at is nil for another user" do
+ %{conn: conn, user: user} = oauth_access(["read:statuses"])
+ {:ok, activity} = CommonAPI.post(user, %{"status" => "foobar", "expires_in" => 1_000_000})
+
+ expires_at =
+ activity.id
+ |> ActivityExpiration.get_by_activity_id()
+ |> Map.get(:scheduled_at)
+ |> NaiveDateTime.to_iso8601()
+
+ assert %{"pleroma" => %{"expires_at" => ^expires_at}} =
+ conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok)
+
+ %{conn: conn} = oauth_access(["read:statuses"])
+
+ assert %{"pleroma" => %{"expires_at" => nil}} =
+ conn |> get("/api/v1/statuses/#{activity.id}") |> json_response(:ok)
+ end
end
diff --git a/test/web/media_proxy/media_proxy_controller_test.exs b/test/web/media_proxy/media_proxy_controller_test.exs
index fdfdb5ec6..8c0c2a0e2 100644
--- a/test/web/media_proxy/media_proxy_controller_test.exs
+++ b/test/web/media_proxy/media_proxy_controller_test.exs
@@ -7,11 +7,8 @@ defmodule Pleroma.Web.MediaProxy.MediaProxyControllerTest do
import Mock
alias Pleroma.Config
- setup do
- media_proxy_config = Config.get([:media_proxy]) || []
- on_exit(fn -> Config.put([:media_proxy], media_proxy_config) end)
- :ok
- end
+ clear_config(:media_proxy)
+ clear_config([Pleroma.Web.Endpoint, :secret_key_base])
test "it returns 404 when MediaProxy disabled", %{conn: conn} do
Config.put([:media_proxy, :enabled], false)
diff --git a/test/web/media_proxy/media_proxy_test.exs b/test/web/media_proxy/media_proxy_test.exs
index 96bdde219..2be5c9de0 100644
--- a/test/web/media_proxy/media_proxy_test.exs
+++ b/test/web/media_proxy/media_proxy_test.exs
@@ -9,6 +9,7 @@ defmodule Pleroma.Web.MediaProxyTest do
alias Pleroma.Web.MediaProxy.MediaProxyController
clear_config([:media_proxy, :enabled])
+ clear_config(Pleroma.Upload)
describe "when enabled" do
setup do
@@ -224,7 +225,6 @@ defmodule Pleroma.Web.MediaProxyTest do
end
test "ensure Pleroma.Upload base_url is always whitelisted" do
- upload_config = Pleroma.Config.get([Pleroma.Upload])
media_url = "https://media.pleroma.social"
Pleroma.Config.put([Pleroma.Upload, :base_url], media_url)
@@ -232,8 +232,6 @@ defmodule Pleroma.Web.MediaProxyTest do
encoded = url(url)
assert String.starts_with?(encoded, media_url)
-
- Pleroma.Config.put([Pleroma.Upload], upload_config)
end
end
end
diff --git a/test/web/metadata/opengraph_test.exs b/test/web/metadata/opengraph_test.exs
index 4283f72cd..0d47b1cb8 100644
--- a/test/web/metadata/opengraph_test.exs
+++ b/test/web/metadata/opengraph_test.exs
@@ -7,6 +7,8 @@ defmodule Pleroma.Web.Metadata.Providers.OpenGraphTest do
import Pleroma.Factory
alias Pleroma.Web.Metadata.Providers.OpenGraph
+ clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
+
test "it renders all supported types of attachments and skips unknown types" do
user = insert(:user)
diff --git a/test/web/metadata/twitter_card_test.exs b/test/web/metadata/twitter_card_test.exs
index 85a654f52..faf347cc6 100644
--- a/test/web/metadata/twitter_card_test.exs
+++ b/test/web/metadata/twitter_card_test.exs
@@ -13,6 +13,8 @@ defmodule Pleroma.Web.Metadata.Providers.TwitterCardTest do
alias Pleroma.Web.Metadata.Utils
alias Pleroma.Web.Router
+ clear_config([Pleroma.Web.Metadata, :unfurl_nsfw])
+
test "it renders twitter card for user info" do
user = insert(:user, name: "Jimmy Hendriks", bio: "born 19 March 1994")
avatar_url = Utils.attachment_url(User.avatar_url(user))
diff --git a/test/web/node_info_test.exs b/test/web/node_info_test.exs
index 39dd72cec..d1d7a3ce8 100644
--- a/test/web/node_info_test.exs
+++ b/test/web/node_info_test.exs
@@ -6,7 +6,9 @@ defmodule Pleroma.Web.NodeInfoTest do
use Pleroma.Web.ConnCase
import Pleroma.Factory
+
clear_config([:mrf_simple])
+ clear_config(:instance)
test "GET /.well-known/nodeinfo", %{conn: conn} do
links =
@@ -63,11 +65,6 @@ defmodule Pleroma.Web.NodeInfoTest do
end
test "returns fieldsLimits field", %{conn: conn} do
- max_account_fields = Pleroma.Config.get([:instance, :max_account_fields])
- max_remote_account_fields = Pleroma.Config.get([:instance, :max_remote_account_fields])
- account_field_name_length = Pleroma.Config.get([:instance, :account_field_name_length])
- account_field_value_length = Pleroma.Config.get([:instance, :account_field_value_length])
-
Pleroma.Config.put([:instance, :max_account_fields], 10)
Pleroma.Config.put([:instance, :max_remote_account_fields], 15)
Pleroma.Config.put([:instance, :account_field_name_length], 255)
@@ -82,11 +79,6 @@ defmodule Pleroma.Web.NodeInfoTest do
assert response["metadata"]["fieldsLimits"]["maxRemoteFields"] == 15
assert response["metadata"]["fieldsLimits"]["nameLength"] == 255
assert response["metadata"]["fieldsLimits"]["valueLength"] == 2048
-
- Pleroma.Config.put([:instance, :max_account_fields], max_account_fields)
- Pleroma.Config.put([:instance, :max_remote_account_fields], max_remote_account_fields)
- Pleroma.Config.put([:instance, :account_field_name_length], account_field_name_length)
- Pleroma.Config.put([:instance, :account_field_value_length], account_field_value_length)
end
test "it returns the safe_dm_mentions feature if enabled", %{conn: conn} do
@@ -112,28 +104,28 @@ defmodule Pleroma.Web.NodeInfoTest do
Pleroma.Config.put([:instance, :safe_dm_mentions], option)
end
- test "it shows if federation is enabled/disabled", %{conn: conn} do
- original = Pleroma.Config.get([:instance, :federating])
+ describe "`metadata/federation/enabled`" do
+ clear_config([:instance, :federating])
- Pleroma.Config.put([:instance, :federating], true)
-
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
+ test "it shows if federation is enabled/disabled", %{conn: conn} do
+ Pleroma.Config.put([:instance, :federating], true)
- assert response["metadata"]["federation"]["enabled"] == true
+ response =
+ conn
+ |> get("/nodeinfo/2.1.json")
+ |> json_response(:ok)
- Pleroma.Config.put([:instance, :federating], false)
+ assert response["metadata"]["federation"]["enabled"] == true
- response =
- conn
- |> get("/nodeinfo/2.1.json")
- |> json_response(:ok)
+ Pleroma.Config.put([:instance, :federating], false)
- assert response["metadata"]["federation"]["enabled"] == false
+ response =
+ conn
+ |> get("/nodeinfo/2.1.json")
+ |> json_response(:ok)
- Pleroma.Config.put([:instance, :federating], original)
+ assert response["metadata"]["federation"]["enabled"] == false
+ end
end
test "it shows MRF transparency data if enabled", %{conn: conn} do
diff --git a/test/web/oauth/oauth_controller_test.exs b/test/web/oauth/oauth_controller_test.exs
index adeff8e25..89fcf8c36 100644
--- a/test/web/oauth/oauth_controller_test.exs
+++ b/test/web/oauth/oauth_controller_test.exs
@@ -17,7 +17,8 @@ defmodule Pleroma.Web.OAuth.OAuthControllerTest do
key: "_test",
signing_salt: "cooldude"
]
- clear_config_all([:instance, :account_activation_required])
+
+ clear_config([:instance, :account_activation_required])
describe "in OAuth consumer mode, " do
setup do
diff --git a/test/web/plugs/federating_plug_test.exs b/test/web/plugs/federating_plug_test.exs
index 9dcab93da..c26b487d9 100644
--- a/test/web/plugs/federating_plug_test.exs
+++ b/test/web/plugs/federating_plug_test.exs
@@ -4,7 +4,8 @@
defmodule Pleroma.Web.FederatingPlugTest do
use Pleroma.Web.ConnCase
- clear_config_all([:instance, :federating])
+
+ clear_config([:instance, :federating])
test "returns and halt the conn when federating is disabled" do
Pleroma.Config.put([:instance, :federating], false)
diff --git a/test/web/streamer/streamer_test.exs b/test/web/streamer/streamer_test.exs
index 2a7550551..1cf20f1c2 100644
--- a/test/web/streamer/streamer_test.exs
+++ b/test/web/streamer/streamer_test.exs
@@ -20,7 +20,7 @@ defmodule Pleroma.Web.StreamerTest do
@streamer_timeout 150
@streamer_start_wait 10
- clear_config_all([:instance, :skip_thread_containment])
+ clear_config([:instance, :skip_thread_containment])
describe "user streams" do
setup do
diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs
index 85a9be3e0..7650238f2 100644
--- a/test/web/twitter_api/twitter_api_test.exs
+++ b/test/web/twitter_api/twitter_api_test.exs
@@ -117,15 +117,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end
describe "register with one time token" do
- setup do
- setting = Pleroma.Config.get([:instance, :registrations_open])
-
- if setting do
- Pleroma.Config.put([:instance, :registrations_open], false)
- on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end)
- end
-
- :ok
+ clear_config([:instance, :registrations_open]) do
+ Pleroma.Config.put([:instance, :registrations_open], false)
end
test "returns user on success" do
@@ -191,14 +184,11 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end
describe "registers with date limited token" do
- setup do
- setting = Pleroma.Config.get([:instance, :registrations_open])
-
- if setting do
- Pleroma.Config.put([:instance, :registrations_open], false)
- on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end)
- end
+ clear_config([:instance, :registrations_open]) do
+ Pleroma.Config.put([:instance, :registrations_open], false)
+ end
+ setup do
data = %{
"nickname" => "vinny",
"email" => "pasta@pizza.vs",
@@ -256,15 +246,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end
describe "registers with reusable token" do
- setup do
- setting = Pleroma.Config.get([:instance, :registrations_open])
-
- if setting do
- Pleroma.Config.put([:instance, :registrations_open], false)
- on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end)
- end
-
- :ok
+ clear_config([:instance, :registrations_open]) do
+ Pleroma.Config.put([:instance, :registrations_open], false)
end
test "returns user on success, after him registration fails" do
@@ -309,15 +292,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPITest do
end
describe "registers with reusable date limited token" do
- setup do
- setting = Pleroma.Config.get([:instance, :registrations_open])
-
- if setting do
- Pleroma.Config.put([:instance, :registrations_open], false)
- on_exit(fn -> Pleroma.Config.put([:instance, :registrations_open], setting) end)
- end
-
- :ok
+ clear_config([:instance, :registrations_open]) do
+ Pleroma.Config.put([:instance, :registrations_open], false)
end
test "returns user on success" do
diff --git a/test/web/twitter_api/util_controller_test.exs b/test/web/twitter_api/util_controller_test.exs
index 5d60c0d51..56633ffce 100644
--- a/test/web/twitter_api/util_controller_test.exs
+++ b/test/web/twitter_api/util_controller_test.exs
@@ -19,7 +19,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilControllerTest do
clear_config([:instance])
clear_config([:frontend_configurations, :pleroma_fe])
- clear_config([:user, :deny_follow_blocked])
describe "POST /api/pleroma/follow_import" do
setup do: oauth_access(["follow"])
diff --git a/test/workers/cron/new_users_digest_worker_test.exs b/test/workers/cron/new_users_digest_worker_test.exs
new file mode 100644
index 000000000..2f439c1fe
--- /dev/null
+++ b/test/workers/cron/new_users_digest_worker_test.exs
@@ -0,0 +1,32 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Workers.Cron.NewUsersDigestWorkerTest do
+ use Pleroma.DataCase
+ import Pleroma.Factory
+
+ alias Pleroma.Tests.ObanHelpers
+ alias Pleroma.Web.CommonAPI
+ alias Pleroma.Workers.Cron.NewUsersDigestWorker
+
+ test "it sends new users digest emails" do
+ yesterday = NaiveDateTime.utc_now() |> Timex.shift(days: -1)
+ admin = insert(:user, %{is_admin: true})
+ user = insert(:user, %{inserted_at: yesterday})
+ user2 = insert(:user, %{inserted_at: yesterday})
+ CommonAPI.post(user, %{"status" => "cofe"})
+
+ NewUsersDigestWorker.perform(nil, nil)
+ ObanHelpers.perform_all()
+
+ assert_received {:email, email}
+ assert email.to == [{admin.name, admin.email}]
+ assert email.subject == "#{Pleroma.Config.get([:instance, :name])} New Users"
+
+ refute email.html_body =~ admin.nickname
+ assert email.html_body =~ user.nickname
+ assert email.html_body =~ user2.nickname
+ assert email.html_body =~ "cofe"
+ end
+end