summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Gleason <alex@alexgleason.me>2021-12-19 11:33:10 -0600
committerAlex Gleason <alex@alexgleason.me>2021-12-19 11:33:10 -0600
commite4f9cb1c1b3969164c03a219d5a760df07d2b3cd (patch)
treed9549feae7691be9988106f2a92ea387b3fdeaf2 /lib
parent720198d56950ca98f4d947dd630b0e170eda569b (diff)
parentbd853199d93e03fedf43397455939c6d633fa36b (diff)
Merge remote-tracking branch 'origin/develop' into manifest
Diffstat (limited to 'lib')
-rw-r--r--lib/pleroma/activity.ex6
-rw-r--r--lib/pleroma/ecto_enums.ex3
-rw-r--r--lib/pleroma/emoji/loader.ex2
-rw-r--r--lib/pleroma/moderation_log.ex20
-rw-r--r--lib/pleroma/user.ex21
-rw-r--r--lib/pleroma/user/query.ex5
-rw-r--r--lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex10
-rw-r--r--lib/pleroma/web/activity_pub/publisher.ex23
-rw-r--r--lib/pleroma/web/admin_api/controllers/user_controller.ex30
-rw-r--r--lib/pleroma/web/admin_api/views/account_view.ex1
-rw-r--r--lib/pleroma/web/api_spec/operations/admin/user_operation.ex66
-rw-r--r--lib/pleroma/web/api_spec/operations/twitter_util_operation.ex19
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/search_controller.ex4
-rw-r--r--lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex90
-rw-r--r--lib/pleroma/web/mastodon_api/views/account_view.ex1
-rw-r--r--lib/pleroma/web/mastodon_api/views/instance_view.ex1
-rw-r--r--lib/pleroma/web/mastodon_api/views/suggestion_view.ex28
-rw-r--r--lib/pleroma/web/nodeinfo/nodeinfo.ex4
-rw-r--r--lib/pleroma/web/router.ex12
-rw-r--r--lib/pleroma/web/twitter_api/controllers/password_controller.ex14
-rw-r--r--lib/pleroma/web/twitter_api/controllers/util_controller.ex6
21 files changed, 336 insertions, 30 deletions
diff --git a/lib/pleroma/activity.ex b/lib/pleroma/activity.ex
index b88f74f47..4106feef6 100644
--- a/lib/pleroma/activity.ex
+++ b/lib/pleroma/activity.ex
@@ -362,11 +362,9 @@ defmodule Pleroma.Activity do
end
def restrict_deactivated_users(query) do
- deactivated_users =
- from(u in User.Query.build(%{deactivated: true}), select: u.ap_id)
- |> Repo.all()
+ deactivated_users_query = from(u in User.Query.build(%{deactivated: true}), select: u.ap_id)
- Activity.Queries.exclude_authors(query, deactivated_users)
+ from(activity in query, where: activity.actor not in subquery(deactivated_users_query))
end
defdelegate search(user, query, options \\ []), to: Pleroma.Activity.Search
diff --git a/lib/pleroma/ecto_enums.ex b/lib/pleroma/ecto_enums.ex
index 2a9addabc..0e3e1e5de 100644
--- a/lib/pleroma/ecto_enums.ex
+++ b/lib/pleroma/ecto_enums.ex
@@ -9,7 +9,8 @@ defenum(Pleroma.UserRelationship.Type,
mute: 2,
reblog_mute: 3,
notification_mute: 4,
- inverse_subscription: 5
+ inverse_subscription: 5,
+ suggestion_dismiss: 6
)
defenum(Pleroma.FollowingRelationship.State,
diff --git a/lib/pleroma/emoji/loader.ex b/lib/pleroma/emoji/loader.ex
index 95937a892..abc95d902 100644
--- a/lib/pleroma/emoji/loader.ex
+++ b/lib/pleroma/emoji/loader.ex
@@ -103,6 +103,7 @@ defmodule Pleroma.Emoji.Loader do
pack_file = Path.join(pack_dir, "pack.json")
if File.exists?(pack_file) do
+ Logger.info("Loading emoji pack from JSON: #{pack_file}")
contents = Jason.decode!(File.read!(pack_file))
contents["files"]
@@ -115,6 +116,7 @@ defmodule Pleroma.Emoji.Loader do
emoji_txt = Path.join(pack_dir, "emoji.txt")
if File.exists?(emoji_txt) do
+ Logger.info("Loading emoji pack from emoji.txt: #{emoji_txt}")
load_from_file(emoji_txt, emoji_groups)
else
extensions = Config.get([:emoji, :pack_extensions])
diff --git a/lib/pleroma/moderation_log.ex b/lib/pleroma/moderation_log.ex
index 993cff09b..adb51d33a 100644
--- a/lib/pleroma/moderation_log.ex
+++ b/lib/pleroma/moderation_log.ex
@@ -341,6 +341,26 @@ defmodule Pleroma.ModerationLog do
def get_log_entry_message(%ModerationLog{
data: %{
"actor" => %{"nickname" => actor_nickname},
+ "action" => "add_suggestion",
+ "subject" => users
+ }
+ }) do
+ "@#{actor_nickname} added suggested users: #{users_to_nicknames_string(users)}"
+ end
+
+ def get_log_entry_message(%ModerationLog{
+ data: %{
+ "actor" => %{"nickname" => actor_nickname},
+ "action" => "remove_suggestion",
+ "subject" => users
+ }
+ }) do
+ "@#{actor_nickname} removed suggested users: #{users_to_nicknames_string(users)}"
+ end
+
+ def get_log_entry_message(%ModerationLog{
+ data: %{
+ "actor" => %{"nickname" => actor_nickname},
"nicknames" => nicknames,
"tags" => tags,
"action" => "tag"
diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex
index 3b4e49176..c25023dc1 100644
--- a/lib/pleroma/user.ex
+++ b/lib/pleroma/user.ex
@@ -148,6 +148,7 @@ defmodule Pleroma.User do
field(:last_active_at, :naive_datetime)
field(:disclose_client, :boolean, default: true)
field(:pinned_objects, :map, default: %{})
+ field(:is_suggested, :boolean, default: false)
embeds_one(
:notification_settings,
@@ -1676,6 +1677,22 @@ defmodule Pleroma.User do
def confirm(%User{} = user), do: {:ok, user}
+ def set_suggestion(users, is_suggested) when is_list(users) do
+ Repo.transaction(fn ->
+ Enum.map(users, fn user ->
+ with {:ok, user} <- set_suggestion(user, is_suggested), do: user
+ end)
+ end)
+ end
+
+ def set_suggestion(%User{is_suggested: is_suggested} = user, is_suggested), do: {:ok, user}
+
+ def set_suggestion(%User{} = user, is_suggested) when is_boolean(is_suggested) do
+ user
+ |> change(is_suggested: is_suggested)
+ |> update_and_set_cache()
+ end
+
def update_notification_settings(%User{} = user, settings) do
user
|> cast(%{notification_settings: settings}, [])
@@ -2474,8 +2491,8 @@ defmodule Pleroma.User do
|> update_and_set_cache()
end
- def active_user_count(weeks \\ 4) do
- active_after = Timex.shift(NaiveDateTime.utc_now(), weeks: -weeks)
+ def active_user_count(days \\ 30) do
+ active_after = Timex.shift(NaiveDateTime.utc_now(), days: -days)
__MODULE__
|> where([u], u.last_active_at >= ^active_after)
diff --git a/lib/pleroma/user/query.ex b/lib/pleroma/user/query.ex
index ac807fc79..6d4a4ead6 100644
--- a/lib/pleroma/user/query.ex
+++ b/lib/pleroma/user/query.ex
@@ -46,6 +46,7 @@ defmodule Pleroma.User.Query do
unconfirmed: boolean(),
is_admin: boolean(),
is_moderator: boolean(),
+ is_suggested: boolean(),
super_users: boolean(),
invisible: boolean(),
internal: boolean(),
@@ -167,6 +168,10 @@ defmodule Pleroma.User.Query do
where(query, [u], u.is_confirmed == false)
end
+ defp compose_query({:is_suggested, bool}, query) do
+ where(query, [u], u.is_suggested == ^bool)
+ end
+
defp compose_query({:followers, %User{id: id}}, query) do
query
|> where([u], u.id != ^id)
diff --git a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
index 837787b9f..59fef42d6 100644
--- a/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
+++ b/lib/pleroma/web/activity_pub/object_validators/attachment_validator.ex
@@ -68,12 +68,14 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
end
end
- defp handle_href(href, mediaType) do
+ defp handle_href(href, mediaType, data) do
[
%{
"href" => href,
"type" => "Link",
- "mediaType" => mediaType
+ "mediaType" => mediaType,
+ "width" => data["width"],
+ "height" => data["height"]
}
]
end
@@ -81,10 +83,10 @@ defmodule Pleroma.Web.ActivityPub.ObjectValidators.AttachmentValidator do
defp fix_url(data) do
cond do
is_binary(data["url"]) ->
- Map.put(data, "url", handle_href(data["url"], data["mediaType"]))
+ Map.put(data, "url", handle_href(data["url"], data["mediaType"], data))
is_binary(data["href"]) and data["url"] == nil ->
- Map.put(data, "url", handle_href(data["href"], data["mediaType"]))
+ Map.put(data, "url", handle_href(data["href"], data["mediaType"], data))
true ->
data
diff --git a/lib/pleroma/web/activity_pub/publisher.ex b/lib/pleroma/web/activity_pub/publisher.ex
index 4f29a4411..ed99079e2 100644
--- a/lib/pleroma/web/activity_pub/publisher.ex
+++ b/lib/pleroma/web/activity_pub/publisher.ex
@@ -63,18 +63,17 @@ defmodule Pleroma.Web.ActivityPub.Publisher do
date: date
})
- with {:ok, %{status: code}} when code in 200..299 <-
- result =
- HTTP.post(
- inbox,
- json,
- [
- {"Content-Type", "application/activity+json"},
- {"Date", date},
- {"signature", signature},
- {"digest", digest}
- ]
- ) do
+ with {:ok, %{status: code}} = result when code in 200..299 <-
+ HTTP.post(
+ inbox,
+ json,
+ [
+ {"Content-Type", "application/activity+json"},
+ {"Date", date},
+ {"signature", signature},
+ {"digest", digest}
+ ]
+ ) do
if not Map.has_key?(params, :unreachable_since) || params[:unreachable_since] do
Instances.set_reachable(inbox)
end
diff --git a/lib/pleroma/web/admin_api/controllers/user_controller.ex b/lib/pleroma/web/admin_api/controllers/user_controller.ex
index 637a0e702..50208a8b7 100644
--- a/lib/pleroma/web/admin_api/controllers/user_controller.ex
+++ b/lib/pleroma/web/admin_api/controllers/user_controller.ex
@@ -35,7 +35,9 @@ defmodule Pleroma.Web.AdminAPI.UserController do
:toggle_activation,
:activate,
:deactivate,
- :approve
+ :approve,
+ :suggest,
+ :unsuggest
]
)
@@ -239,6 +241,32 @@ defmodule Pleroma.Web.AdminAPI.UserController do
render(conn, "index.json", users: updated_users)
end
+ def suggest(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
+ users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
+ {:ok, updated_users} = User.set_suggestion(users, true)
+
+ ModerationLog.insert_log(%{
+ actor: admin,
+ subject: users,
+ action: "add_suggestion"
+ })
+
+ render(conn, "index.json", users: updated_users)
+ end
+
+ def unsuggest(%{assigns: %{user: admin}, body_params: %{nicknames: nicknames}} = conn, _) do
+ users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
+ {:ok, updated_users} = User.set_suggestion(users, false)
+
+ ModerationLog.insert_log(%{
+ actor: admin,
+ subject: users,
+ action: "remove_suggestion"
+ })
+
+ render(conn, "index.json", users: updated_users)
+ end
+
def index(conn, params) do
{page, page_size} = page_params(params)
filters = maybe_parse_filters(params[:filters])
diff --git a/lib/pleroma/web/admin_api/views/account_view.ex b/lib/pleroma/web/admin_api/views/account_view.ex
index fae0c07f0..2f1f7e627 100644
--- a/lib/pleroma/web/admin_api/views/account_view.ex
+++ b/lib/pleroma/web/admin_api/views/account_view.ex
@@ -80,6 +80,7 @@ defmodule Pleroma.Web.AdminAPI.AccountView do
"tags" => user.tags || [],
"is_confirmed" => user.is_confirmed,
"is_approved" => user.is_approved,
+ "is_suggested" => user.is_suggested,
"url" => user.uri || user.ap_id,
"registration_reason" => user.registration_reason,
"actor_type" => user.actor_type,
diff --git a/lib/pleroma/web/api_spec/operations/admin/user_operation.ex b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
index c9d0bfd7c..57fb1ad65 100644
--- a/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/admin/user_operation.ex
@@ -216,7 +216,71 @@ defmodule Pleroma.Web.ApiSpec.Admin.UserOperation do
request_body(
"Parameters",
%Schema{
- description: "POST body for deleting multiple users",
+ description: "POST body for approving multiple users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def suggest_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Suggest multiple users",
+ operationId: "AdminAPI.UserController.suggest",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for adding multiple suggested users",
+ type: :object,
+ properties: %{
+ nicknames: %Schema{
+ type: :array,
+ items: %Schema{type: :string}
+ }
+ }
+ }
+ ),
+ responses: %{
+ 200 =>
+ Operation.response("Response", "application/json", %Schema{
+ type: :object,
+ properties: %{user: %Schema{type: :array, items: user()}}
+ }),
+ 403 => Operation.response("Forbidden", "application/json", ApiError)
+ }
+ }
+ end
+
+ def unsuggest_operation do
+ %Operation{
+ tags: ["User administration"],
+ summary: "Unsuggest multiple users",
+ operationId: "AdminAPI.UserController.unsuggest",
+ security: [%{"oAuth" => ["admin:write:accounts"]}],
+ parameters: admin_api_params(),
+ requestBody:
+ request_body(
+ "Parameters",
+ %Schema{
+ description: "POST body for removing multiple suggested users",
type: :object,
properties: %{
nicknames: %Schema{
diff --git a/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex
index ebcfd3be2..5a2b0bc49 100644
--- a/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex
+++ b/lib/pleroma/web/api_spec/operations/twitter_util_operation.ex
@@ -191,6 +191,7 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
parameters: [
Operation.parameter(:password, :query, :string, "Password")
],
+ requestBody: request_body("Parameters", delete_account_request(), required: false),
responses: %{
200 =>
Operation.response("Success", "application/json", %Schema{
@@ -237,4 +238,22 @@ defmodule Pleroma.Web.ApiSpec.TwitterUtilOperation do
responses: %{200 => Operation.response("Web Page", "test/html", %Schema{type: :string})}
}
end
+
+ defp delete_account_request do
+ %Schema{
+ title: "AccountDeleteRequest",
+ description: "POST body for deleting one's own account",
+ type: :object,
+ properties: %{
+ password: %Schema{
+ type: :string,
+ description: "The user's own password for confirmation.",
+ format: :password
+ }
+ },
+ example: %{
+ "password" => "prettyp0ony1313"
+ }
+ }
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
index 64b177eb3..1459fc492 100644
--- a/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/search_controller.ex
@@ -17,6 +17,8 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
require Logger
+ @search_limit 40
+
plug(Pleroma.Web.ApiSpec.CastAndValidate)
# Note: Mastodon doesn't allow unauthenticated access (requires read:accounts / read:search)
@@ -77,7 +79,7 @@ defmodule Pleroma.Web.MastodonAPI.SearchController do
[
resolve: params[:resolve],
following: params[:following],
- limit: params[:limit],
+ limit: min(params[:limit], @search_limit),
offset: params[:offset],
type: params[:type],
author: get_author(params),
diff --git a/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex b/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex
index 01e122dd9..e913fcf4b 100644
--- a/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex
+++ b/lib/pleroma/web/mastodon_api/controllers/suggestion_controller.ex
@@ -4,11 +4,16 @@
defmodule Pleroma.Web.MastodonAPI.SuggestionController do
use Pleroma.Web, :controller
+ import Ecto.Query
+ alias Pleroma.FollowingRelationship
+ alias Pleroma.User
+ alias Pleroma.UserRelationship
require Logger
plug(Pleroma.Web.ApiSpec.CastAndValidate)
- plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read"]} when action == :index)
+ plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["read"]} when action in [:index, :index2])
+ plug(Pleroma.Web.Plugs.OAuthScopesPlug, %{scopes: ["write"]} when action in [:dismiss])
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
@@ -26,7 +31,90 @@ defmodule Pleroma.Web.MastodonAPI.SuggestionController do
}
end
+ def index2_operation do
+ %OpenApiSpex.Operation{
+ tags: ["Suggestions"],
+ summary: "Follow suggestions",
+ operationId: "SuggestionController.index2",
+ responses: %{
+ 200 => Pleroma.Web.ApiSpec.Helpers.empty_array_response()
+ }
+ }
+ end
+
+ def dismiss_operation do
+ %OpenApiSpex.Operation{
+ tags: ["Suggestions"],
+ summary: "Remove a suggestion",
+ operationId: "SuggestionController.dismiss",
+ parameters: [
+ OpenApiSpex.Operation.parameter(
+ :account_id,
+ :path,
+ %OpenApiSpex.Schema{type: :string},
+ "Account to dismiss",
+ required: true
+ )
+ ],
+ responses: %{
+ 200 => Pleroma.Web.ApiSpec.Helpers.empty_object_response()
+ }
+ }
+ end
+
@doc "GET /api/v1/suggestions"
def index(conn, params),
do: Pleroma.Web.MastodonAPI.MastodonAPIController.empty_array(conn, params)
+
+ @doc "GET /api/v2/suggestions"
+ def index2(%{assigns: %{user: user}} = conn, params) do
+ limit = Map.get(params, :limit, 40) |> min(80)
+
+ users =
+ %{is_suggested: true, invisible: false, limit: limit}
+ |> User.Query.build()
+ |> exclude_user(user)
+ |> exclude_relationships(user, [:block, :mute, :suggestion_dismiss])
+ |> exclude_following(user)
+ |> Pleroma.Repo.all()
+
+ render(conn, "index.json", %{
+ users: users,
+ source: :staff,
+ for: user,
+ skip_visibility_check: true
+ })
+ end
+
+ defp exclude_user(query, %User{id: user_id}) do
+ where(query, [u], u.id != ^user_id)
+ end
+
+ defp exclude_relationships(query, %User{id: user_id}, relationship_types) do
+ query
+ |> join(:left, [u], r in UserRelationship,
+ as: :user_relationships,
+ on:
+ r.target_id == u.id and r.source_id == ^user_id and
+ r.relationship_type in ^relationship_types
+ )
+ |> where([user_relationships: r], is_nil(r.target_id))
+ end
+
+ defp exclude_following(query, %User{id: user_id}) do
+ query
+ |> join(:left, [u], r in FollowingRelationship,
+ as: :following_relationships,
+ on: r.following_id == u.id and r.follower_id == ^user_id and r.state == :follow_accept
+ )
+ |> where([following_relationships: r], is_nil(r.following_id))
+ end
+
+ @doc "DELETE /api/v1/suggestions/:account_id"
+ def dismiss(%{assigns: %{user: source}} = conn, %{account_id: user_id}) do
+ with %User{} = target <- User.get_cached_by_id(user_id),
+ {:ok, _} <- UserRelationship.create(:suggestion_dismiss, source, target) do
+ json(conn, %{})
+ end
+ end
end
diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex
index 9e9de33f6..6114e12b1 100644
--- a/lib/pleroma/web/mastodon_api/views/account_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/account_view.ex
@@ -269,6 +269,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
ap_id: user.ap_id,
also_known_as: user.also_known_as,
is_confirmed: user.is_confirmed,
+ is_suggested: user.is_suggested,
tags: user.tags,
hide_followers_count: user.hide_followers_count,
hide_follows_count: user.hide_follows_count,
diff --git a/lib/pleroma/web/mastodon_api/views/instance_view.ex b/lib/pleroma/web/mastodon_api/views/instance_view.ex
index ef208062b..5810f605a 100644
--- a/lib/pleroma/web/mastodon_api/views/instance_view.ex
+++ b/lib/pleroma/web/mastodon_api/views/instance_view.ex
@@ -59,6 +59,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
"mastodon_api",
"mastodon_api_streaming",
"polls",
+ "v2_suggestions",
"pleroma_explicit_addressing",
"shareable_emoji_packs",
"multifetch",
diff --git a/lib/pleroma/web/mastodon_api/views/suggestion_view.ex b/lib/pleroma/web/mastodon_api/views/suggestion_view.ex
new file mode 100644
index 000000000..865229a88
--- /dev/null
+++ b/lib/pleroma/web/mastodon_api/views/suggestion_view.ex
@@ -0,0 +1,28 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
+# SPDX-License-Identifier: AGPL-3.0-only
+
+defmodule Pleroma.Web.MastodonAPI.SuggestionView do
+ use Pleroma.Web, :view
+ alias Pleroma.Web.MastodonAPI.AccountView
+
+ @source_types [:staff, :global, :past_interactions]
+
+ def render("index.json", %{users: users} = opts) do
+ Enum.map(users, fn user ->
+ opts =
+ opts
+ |> Map.put(:user, user)
+ |> Map.delete(:users)
+
+ render("show.json", opts)
+ end)
+ end
+
+ def render("show.json", %{source: source, user: _user} = opts) when source in @source_types do
+ %{
+ source: source,
+ account: AccountView.render("show.json", opts)
+ }
+ end
+end
diff --git a/lib/pleroma/web/nodeinfo/nodeinfo.ex b/lib/pleroma/web/nodeinfo/nodeinfo.ex
index 6a0112d2a..3781781c8 100644
--- a/lib/pleroma/web/nodeinfo/nodeinfo.ex
+++ b/lib/pleroma/web/nodeinfo/nodeinfo.ex
@@ -35,7 +35,9 @@ defmodule Pleroma.Web.Nodeinfo.Nodeinfo do
openRegistrations: Config.get([:instance, :registrations_open]),
usage: %{
users: %{
- total: Map.get(stats, :user_count, 0)
+ total: Map.get(stats, :user_count, 0),
+ activeMonth: Pleroma.User.active_user_count(30),
+ activeHalfyear: Pleroma.User.active_user_count(180)
},
localPosts: Map.get(stats, :status_count, 0)
},
diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex
index afdc4f492..c1713c6cf 100644
--- a/lib/pleroma/web/router.ex
+++ b/lib/pleroma/web/router.ex
@@ -192,6 +192,9 @@ defmodule Pleroma.Web.Router do
patch("/users/deactivate", UserController, :deactivate)
patch("/users/approve", UserController, :approve)
+ patch("/users/suggest", UserController, :suggest)
+ patch("/users/unsuggest", UserController, :unsuggest)
+
get("/relay", RelayController, :index)
post("/relay", RelayController, :follow)
delete("/relay", RelayController, :unfollow)
@@ -535,6 +538,7 @@ defmodule Pleroma.Web.Router do
delete("/push/subscription", SubscriptionController, :delete)
get("/suggestions", SuggestionController, :index)
+ delete("/suggestions/:account_id", SuggestionController, :dismiss)
get("/timelines/home", TimelineController, :home)
get("/timelines/direct", TimelineController, :direct)
@@ -586,6 +590,8 @@ defmodule Pleroma.Web.Router do
get("/search", SearchController, :search2)
post("/media", MediaController, :create2)
+
+ get("/suggestions", SuggestionController, :index2)
end
scope "/api", Pleroma.Web do
@@ -742,6 +748,12 @@ defmodule Pleroma.Web.Router do
get("/manifest.json", ManifestController, :show)
end
+ scope "/", Pleroma.Web do
+ pipe_through(:pleroma_html)
+
+ post("/auth/password", TwitterAPI.PasswordController, :request)
+ end
+
scope "/proxy/", Pleroma.Web do
get("/preview/:sig/:url", MediaProxy.MediaProxyController, :preview)
get("/preview/:sig/:url/:filename", MediaProxy.MediaProxyController, :preview)
diff --git a/lib/pleroma/web/twitter_api/controllers/password_controller.ex b/lib/pleroma/web/twitter_api/controllers/password_controller.ex
index bc04a4d49..133a588b0 100644
--- a/lib/pleroma/web/twitter_api/controllers/password_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/password_controller.ex
@@ -11,9 +11,23 @@ defmodule Pleroma.Web.TwitterAPI.PasswordController do
require Logger
+ import Pleroma.Web.ControllerHelper, only: [json_response: 3]
+
alias Pleroma.PasswordResetToken
alias Pleroma.Repo
alias Pleroma.User
+ alias Pleroma.Web.TwitterAPI.TwitterAPI
+
+ plug(Pleroma.Web.Plugs.RateLimiter, [name: :request] when action == :request)
+
+ @doc "POST /auth/password"
+ def request(conn, params) do
+ nickname_or_email = params["email"] || params["nickname"]
+
+ TwitterAPI.password_reset(nickname_or_email)
+
+ json_response(conn, :no_content, "")
+ end
def reset(conn, %{"token" => token}) do
with %{used: false} = token <- Repo.get_by(PasswordResetToken, %{token: token}),
diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
index ef43f7682..a4e44efdd 100644
--- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex
+++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex
@@ -123,8 +123,10 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do
end
end
- def delete_account(%{assigns: %{user: user}} = conn, params) do
- password = params[:password] || ""
+ def delete_account(%{assigns: %{user: user}, body_params: body_params} = conn, params) do
+ # This endpoint can accept a query param or JSON body for backwards-compatibility.
+ # Submitting a JSON body is recommended, so passwords don't end up in server logs.
+ password = body_params[:password] || params[:password] || ""
case CommonAPI.Utils.confirm_current_password(user, password) do
{:ok, user} ->