Merge branch 'develop' into docs/apache-config
This commit is contained in:
commit
0b19534475
|
@ -8,9 +8,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- **Breaking:** Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
- **Breaking**: Changed `mix pleroma.user toggle_confirmed` to `mix pleroma.user confirm`
|
||||||
|
- **Breaking**: Changed `mix pleroma.user toggle_activated` to `mix pleroma.user activate/deactivate`
|
||||||
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
- **Breaking**: AdminAPI changed User field `confirmation_pending` to `is_confirmed`
|
||||||
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
|
- **Breaking**: AdminAPI changed User field `approval_pending` to `is_approved`
|
||||||
|
- **Breaking**: AdminAPI changed User field `deactivated` to `is_active`
|
||||||
- Polls now always return a `voters_count`, even if they are single-choice.
|
- Polls now always return a `voters_count`, even if they are single-choice.
|
||||||
- Admin Emails: The ap id is used as the user link in emails now.
|
- Admin Emails: The ap id is used as the user link in emails now.
|
||||||
- Improved registration workflow for email confirmation and account approval modes.
|
- Improved registration workflow for email confirmation and account approval modes.
|
||||||
|
@ -55,6 +57,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Streaming API: Posts and notifications are not dropped, when CLI task is executing.
|
- Streaming API: Posts and notifications are not dropped, when CLI task is executing.
|
||||||
- Creating incorrect IPv4 address-style HTTP links when encountering certain numbers.
|
- Creating incorrect IPv4 address-style HTTP links when encountering certain numbers.
|
||||||
- Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private.
|
- Reblog API Endpoint: Do not set visibility parameter to public by default and let CommonAPI to infer it from status, so a user can reblog their private status without explicitly setting reblog visibility to private.
|
||||||
|
- Tag URLs in statuses are now absolute
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
<summary>API Changes</summary>
|
<summary>API Changes</summary>
|
||||||
|
|
|
@ -133,22 +133,20 @@
|
||||||
mix pleroma.user sign_out <nickname>
|
mix pleroma.user sign_out <nickname>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Activate a user
|
||||||
## Deactivate or activate a user
|
|
||||||
|
|
||||||
=== "OTP"
|
=== "OTP"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
./bin/pleroma_ctl user toggle_activated <nickname>
|
./bin/pleroma_ctl user activate NICKNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
=== "From Source"
|
=== "From Source"
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
mix pleroma.user toggle_activated <nickname>
|
mix pleroma.user activate NICKNAME
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
## Deactivate a user and unsubscribes local users from the user
|
## Deactivate a user and unsubscribes local users from the user
|
||||||
|
|
||||||
=== "OTP"
|
=== "OTP"
|
||||||
|
|
|
@ -125,7 +125,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
||||||
|
|
|
@ -100,7 +100,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
* The previous command creates also the file `config/setup_db.psql`, with which you can create the database:
|
||||||
|
|
|
@ -98,7 +98,7 @@ sudo -Hu pleroma mix deps.get
|
||||||
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
* Check the configuration and if all looks right, rename it, so Pleroma will load it (`prod.secret.exs` for productive instance, `dev.secret.exs` for development instances):
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ sudo -Hu pleroma mix pleroma.instance gen
|
||||||
|
|
||||||
* コンフィギュレーションを確認して、もし問題なければ、ファイル名を変更してください。
|
* コンフィギュレーションを確認して、もし問題なければ、ファイル名を変更してください。
|
||||||
```
|
```
|
||||||
mv config/{generated_config.exs,prod.secret.exs}
|
sudo -Hu pleroma mv config/{generated_config.exs,prod.secret.exs}
|
||||||
```
|
```
|
||||||
|
|
||||||
* 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。
|
* 先程のコマンドで、すでに `config/setup_db.psql` というファイルが作られています。このファイルをもとに、データベースを作成します。
|
||||||
|
|
|
@ -33,7 +33,7 @@ def run(["resend_confirmation_emails"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
is_confirmed: false,
|
is_confirmed: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
})
|
})
|
||||||
|
|
|
@ -107,21 +107,6 @@ def run(["rm", nickname]) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def run(["toggle_activated", nickname]) do
|
|
||||||
start_pleroma()
|
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
|
||||||
{:ok, user} = User.deactivate(user, !user.deactivated)
|
|
||||||
|
|
||||||
shell_info(
|
|
||||||
"Activation status of #{nickname}: #{if(user.deactivated, do: "de", else: "")}activated"
|
|
||||||
)
|
|
||||||
else
|
|
||||||
_ ->
|
|
||||||
shell_error("No user #{nickname}")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def run(["reset_password", nickname]) do
|
def run(["reset_password", nickname]) do
|
||||||
start_pleroma()
|
start_pleroma()
|
||||||
|
|
||||||
|
@ -156,20 +141,41 @@ def run(["reset_mfa", nickname]) do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def run(["activate", nickname]) do
|
||||||
|
start_pleroma()
|
||||||
|
|
||||||
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
|
false <- user.is_active do
|
||||||
|
User.set_activation(user, true)
|
||||||
|
:timer.sleep(500)
|
||||||
|
|
||||||
|
shell_info("Successfully activated #{nickname}")
|
||||||
|
else
|
||||||
|
true ->
|
||||||
|
shell_info("User #{nickname} already activated")
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
shell_error("No user #{nickname}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def run(["deactivate", nickname]) do
|
def run(["deactivate", nickname]) do
|
||||||
start_pleroma()
|
start_pleroma()
|
||||||
|
|
||||||
with %User{} = user <- User.get_cached_by_nickname(nickname) do
|
with %User{} = user <- User.get_cached_by_nickname(nickname),
|
||||||
shell_info("Deactivating #{user.nickname}")
|
true <- user.is_active do
|
||||||
User.deactivate(user)
|
User.set_activation(user, false)
|
||||||
:timer.sleep(500)
|
:timer.sleep(500)
|
||||||
|
|
||||||
user = User.get_cached_by_id(user.id)
|
user = User.get_cached_by_id(user.id)
|
||||||
|
|
||||||
if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do
|
if Enum.empty?(Enum.filter(User.get_friends(user), & &1.local)) do
|
||||||
shell_info("Successfully unsubscribed all local followers from #{user.nickname}")
|
shell_info("Successfully deactivated #{nickname} and unsubscribed all local followers")
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
false ->
|
||||||
|
shell_info("User #{nickname} already deactivated")
|
||||||
|
|
||||||
_ ->
|
_ ->
|
||||||
shell_error("No user #{nickname}")
|
shell_error("No user #{nickname}")
|
||||||
end
|
end
|
||||||
|
@ -365,7 +371,7 @@ def run(["confirm_all"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
|
@ -383,7 +389,7 @@ def run(["unconfirm_all"]) do
|
||||||
|
|
||||||
Pleroma.User.Query.build(%{
|
Pleroma.User.Query.build(%{
|
||||||
local: true,
|
local: true,
|
||||||
deactivated: false,
|
is_active: true,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
invisible: false
|
invisible: false
|
||||||
|
@ -420,7 +426,7 @@ def run(["list"]) do
|
||||||
shell_info(
|
shell_info(
|
||||||
"#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{
|
"#{user.nickname} moderator: #{user.is_moderator}, admin: #{user.is_admin}, locked: #{
|
||||||
user.is_locked
|
user.is_locked
|
||||||
}, deactivated: #{user.deactivated}"
|
}, is_active: #{user.is_active}"
|
||||||
)
|
)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -152,7 +152,7 @@ def get_follow_requests(%User{id: id}) do
|
||||||
|> join(:inner, [r], f in assoc(r, :follower))
|
|> join(:inner, [r], f in assoc(r, :follower))
|
||||||
|> where([r], r.state == ^:follow_pending)
|
|> where([r], r.state == ^:follow_pending)
|
||||||
|> where([r], r.following_id == ^id)
|
|> where([r], r.following_id == ^id)
|
||||||
|> where([r, f], f.deactivated != true)
|
|> where([r, f], f.is_active == true)
|
||||||
|> select([r, f], f)
|
|> select([r, f], f)
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
|
@ -115,7 +115,7 @@ def for_user_query(user, opts \\ %{}) do
|
||||||
|> where(
|
|> where(
|
||||||
[n, a],
|
[n, a],
|
||||||
fragment(
|
fragment(
|
||||||
"? not in (SELECT ap_id FROM users WHERE deactivated = 'true')",
|
"? not in (SELECT ap_id FROM users WHERE is_active = 'false')",
|
||||||
a.actor
|
a.actor
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -75,7 +75,7 @@ def calculate_stat_data do
|
||||||
|
|
||||||
users_query =
|
users_query =
|
||||||
from(u in User,
|
from(u in User,
|
||||||
where: u.deactivated != true,
|
where: u.is_active == true,
|
||||||
where: u.local == true,
|
where: u.local == true,
|
||||||
where: not is_nil(u.nickname),
|
where: not is_nil(u.nickname),
|
||||||
where: not u.invisible
|
where: not u.invisible
|
||||||
|
|
|
@ -117,7 +117,7 @@ defmodule Pleroma.User do
|
||||||
field(:confirmation_token, :string, default: nil)
|
field(:confirmation_token, :string, default: nil)
|
||||||
field(:default_scope, :string, default: "public")
|
field(:default_scope, :string, default: "public")
|
||||||
field(:domain_blocks, {:array, :string}, default: [])
|
field(:domain_blocks, {:array, :string}, default: [])
|
||||||
field(:deactivated, :boolean, default: false)
|
field(:is_active, :boolean, default: true)
|
||||||
field(:no_rich_text, :boolean, default: false)
|
field(:no_rich_text, :boolean, default: false)
|
||||||
field(:ap_enabled, :boolean, default: false)
|
field(:ap_enabled, :boolean, default: false)
|
||||||
field(:is_moderator, :boolean, default: false)
|
field(:is_moderator, :boolean, default: false)
|
||||||
|
@ -217,7 +217,8 @@ def unquote(:"#{outgoing_relation_target}_relation")(user, restrict_deactivated?
|
||||||
target_users_query = assoc(user, unquote(outgoing_relation_target))
|
target_users_query = assoc(user, unquote(outgoing_relation_target))
|
||||||
|
|
||||||
if restrict_deactivated? do
|
if restrict_deactivated? do
|
||||||
restrict_deactivated(target_users_query)
|
target_users_query
|
||||||
|
|> User.Query.build(%{deactivated: false})
|
||||||
else
|
else
|
||||||
target_users_query
|
target_users_query
|
||||||
end
|
end
|
||||||
|
@ -286,7 +287,7 @@ def binary_id(%User{} = user), do: binary_id(user.id)
|
||||||
|
|
||||||
@doc "Returns status account"
|
@doc "Returns status account"
|
||||||
@spec account_status(User.t()) :: account_status()
|
@spec account_status(User.t()) :: account_status()
|
||||||
def account_status(%User{deactivated: true}), do: :deactivated
|
def account_status(%User{is_active: false}), do: :deactivated
|
||||||
def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
|
def account_status(%User{password_reset_pending: true}), do: :password_reset_pending
|
||||||
def account_status(%User{local: true, is_approved: false}), do: :approval_pending
|
def account_status(%User{local: true, is_approved: false}), do: :approval_pending
|
||||||
def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending
|
def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending
|
||||||
|
@ -378,11 +379,6 @@ def ap_followers(%User{} = user), do: "#{ap_id(user)}/followers"
|
||||||
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
|
||||||
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
def ap_following(%User{} = user), do: "#{ap_id(user)}/following"
|
||||||
|
|
||||||
@spec restrict_deactivated(Ecto.Query.t()) :: Ecto.Query.t()
|
|
||||||
def restrict_deactivated(query) do
|
|
||||||
from(u in query, where: u.deactivated != ^true)
|
|
||||||
end
|
|
||||||
|
|
||||||
defp truncate_fields_param(params) do
|
defp truncate_fields_param(params) do
|
||||||
if Map.has_key?(params, :fields) do
|
if Map.has_key?(params, :fields) do
|
||||||
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
|
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
|
||||||
|
@ -777,7 +773,7 @@ defp autofollow_users(user) do
|
||||||
candidates = Config.get([:instance, :autofollowed_nicknames])
|
candidates = Config.get([:instance, :autofollowed_nicknames])
|
||||||
|
|
||||||
autofollowed_users =
|
autofollowed_users =
|
||||||
User.Query.build(%{nickname: candidates, local: true, deactivated: false})
|
User.Query.build(%{nickname: candidates, local: true, is_active: true})
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
|
||||||
follow_all(user, autofollowed_users)
|
follow_all(user, autofollowed_users)
|
||||||
|
@ -938,7 +934,7 @@ def follow(%User{} = follower, %User{} = followed, state \\ :follow_accept) do
|
||||||
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
|
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
|
||||||
|
|
||||||
cond do
|
cond do
|
||||||
followed.deactivated ->
|
not followed.is_active ->
|
||||||
{:error, "Could not follow user: #{followed.nickname} is deactivated."}
|
{:error, "Could not follow user: #{followed.nickname} is deactivated."}
|
||||||
|
|
||||||
deny_follow_blocked and blocks?(followed, follower) ->
|
deny_follow_blocked and blocks?(followed, follower) ->
|
||||||
|
@ -1173,7 +1169,7 @@ def get_or_fetch_by_nickname(nickname) do
|
||||||
|
|
||||||
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
|
||||||
def get_followers_query(%User{} = user, nil) do
|
def get_followers_query(%User{} = user, nil) do
|
||||||
User.Query.build(%{followers: user, deactivated: false})
|
User.Query.build(%{followers: user, is_active: true})
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_followers_query(%User{} = user, page) do
|
def get_followers_query(%User{} = user, page) do
|
||||||
|
@ -1349,7 +1345,7 @@ def update_following_count(%User{local: true} = user) do
|
||||||
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
|
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
|
||||||
def get_users_from_set(ap_ids, opts \\ []) do
|
def get_users_from_set(ap_ids, opts \\ []) do
|
||||||
local_only = Keyword.get(opts, :local_only, true)
|
local_only = Keyword.get(opts, :local_only, true)
|
||||||
criteria = %{ap_id: ap_ids, deactivated: false}
|
criteria = %{ap_id: ap_ids, is_active: true}
|
||||||
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
|
criteria = if local_only, do: Map.put(criteria, :local, true), else: criteria
|
||||||
|
|
||||||
User.Query.build(criteria)
|
User.Query.build(criteria)
|
||||||
|
@ -1360,7 +1356,7 @@ def get_users_from_set(ap_ids, opts \\ []) do
|
||||||
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
|
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
|
||||||
to = [actor | to]
|
to = [actor | to]
|
||||||
|
|
||||||
query = User.Query.build(%{recipients_from_activity: to, local: true, deactivated: false})
|
query = User.Query.build(%{recipients_from_activity: to, local: true, is_active: true})
|
||||||
|
|
||||||
query
|
query
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
|
@ -1579,19 +1575,19 @@ defp maybe_filter_on_ap_id(query, ap_ids) when is_list(ap_ids) do
|
||||||
|
|
||||||
defp maybe_filter_on_ap_id(query, _ap_ids), do: query
|
defp maybe_filter_on_ap_id(query, _ap_ids), do: query
|
||||||
|
|
||||||
def deactivate_async(user, status \\ true) do
|
def set_activation_async(user, status \\ true) do
|
||||||
BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
|
BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status})
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate(user, status \\ true)
|
@spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
|
||||||
|
def set_activation(users, status) when is_list(users) do
|
||||||
def deactivate(users, status) when is_list(users) do
|
|
||||||
Repo.transaction(fn ->
|
Repo.transaction(fn ->
|
||||||
for user <- users, do: deactivate(user, status)
|
for user <- users, do: set_activation(user, status)
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate(%User{} = user, status) do
|
@spec set_activation(User.t(), boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
|
||||||
|
def set_activation(%User{} = user, status) do
|
||||||
with {:ok, user} <- set_activation_status(user, status) do
|
with {:ok, user} <- set_activation_status(user, status) do
|
||||||
user
|
user
|
||||||
|> get_followers()
|
|> get_followers()
|
||||||
|
@ -1680,7 +1676,7 @@ def purge_user_changeset(user) do
|
||||||
registration_reason: nil,
|
registration_reason: nil,
|
||||||
confirmation_token: nil,
|
confirmation_token: nil,
|
||||||
domain_blocks: [],
|
domain_blocks: [],
|
||||||
deactivated: true,
|
is_active: false,
|
||||||
ap_enabled: false,
|
ap_enabled: false,
|
||||||
is_moderator: false,
|
is_moderator: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
|
@ -1754,7 +1750,7 @@ def perform(:delete, %User{} = user) do
|
||||||
delete_or_deactivate(user)
|
delete_or_deactivate(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(:deactivate_async, user, status), do: deactivate(user, status)
|
def perform(:set_activation_async, user, status), do: set_activation(user, status)
|
||||||
|
|
||||||
@spec external_users_query() :: Ecto.Query.t()
|
@spec external_users_query() :: Ecto.Query.t()
|
||||||
def external_users_query do
|
def external_users_query do
|
||||||
|
@ -2048,7 +2044,7 @@ def error_user(ap_id) do
|
||||||
|
|
||||||
@spec all_superusers() :: [User.t()]
|
@spec all_superusers() :: [User.t()]
|
||||||
def all_superusers do
|
def all_superusers do
|
||||||
User.Query.build(%{super_users: true, local: true, deactivated: false})
|
User.Query.build(%{super_users: true, local: true, is_active: true})
|
||||||
|> Repo.all()
|
|> Repo.all()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -2089,7 +2085,7 @@ def list_inactive_users_query(inactivity_threshold \\ 7) do
|
||||||
left_join: a in Pleroma.Activity,
|
left_join: a in Pleroma.Activity,
|
||||||
on: u.ap_id == a.actor,
|
on: u.ap_id == a.actor,
|
||||||
where: not is_nil(u.nickname),
|
where: not is_nil(u.nickname),
|
||||||
where: u.deactivated != ^true,
|
where: u.is_active == ^true,
|
||||||
where: u.id not in ^has_read_notifications,
|
where: u.id not in ^has_read_notifications,
|
||||||
group_by: u.id,
|
group_by: u.id,
|
||||||
having:
|
having:
|
||||||
|
@ -2210,9 +2206,9 @@ def change_email(user, email) do
|
||||||
end
|
end
|
||||||
|
|
||||||
# Internal function; public one is `deactivate/2`
|
# Internal function; public one is `deactivate/2`
|
||||||
defp set_activation_status(user, deactivated) do
|
defp set_activation_status(user, status) do
|
||||||
user
|
user
|
||||||
|> cast(%{deactivated: deactivated}, [:deactivated])
|
|> cast(%{is_active: status}, [:is_active])
|
||||||
|> update_and_set_cache()
|
|> update_and_set_cache()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -137,7 +137,7 @@ defp compose_query({:local, _}, query), do: location_query(query, true)
|
||||||
defp compose_query({:external, _}, query), do: location_query(query, false)
|
defp compose_query({:external, _}, query), do: location_query(query, false)
|
||||||
|
|
||||||
defp compose_query({:active, _}, query) do
|
defp compose_query({:active, _}, query) do
|
||||||
User.restrict_deactivated(query)
|
where(query, [u], u.is_active == true)
|
||||||
|> where([u], u.is_approved == true)
|
|> where([u], u.is_approved == true)
|
||||||
|> where([u], u.is_confirmed == true)
|
|> where([u], u.is_confirmed == true)
|
||||||
end
|
end
|
||||||
|
@ -148,11 +148,11 @@ defp compose_query({:legacy_active, _}, query) do
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:deactivated, false}, query) do
|
defp compose_query({:deactivated, false}, query) do
|
||||||
User.restrict_deactivated(query)
|
where(query, [u], u.is_active == true)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:deactivated, true}, query) do
|
defp compose_query({:deactivated, true}, query) do
|
||||||
where(query, [u], u.deactivated == ^true)
|
where(query, [u], u.is_active == false)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp compose_query({:confirmation_pending, bool}, query) do
|
defp compose_query({:confirmation_pending, bool}, query) do
|
||||||
|
|
|
@ -56,7 +56,7 @@ defp check_actor_is_active(nil), do: true
|
||||||
|
|
||||||
defp check_actor_is_active(actor) when is_binary(actor) do
|
defp check_actor_is_active(actor) when is_binary(actor) do
|
||||||
case User.get_cached_by_ap_id(actor) do
|
case User.get_cached_by_ap_id(actor) do
|
||||||
%User{deactivated: deactivated} -> not deactivated
|
%User{is_active: true} -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,7 +35,7 @@ def validate_actor_presence(cng, options \\ []) do
|
||||||
cng
|
cng
|
||||||
|> validate_change(field_name, fn field_name, actor ->
|
|> validate_change(field_name, fn field_name, actor ->
|
||||||
case User.get_cached_by_ap_id(actor) do
|
case User.get_cached_by_ap_id(actor) do
|
||||||
%User{deactivated: true} ->
|
%User{is_active: false} ->
|
||||||
[{field_name, "user is deactivated"}]
|
[{field_name, "user is deactivated"}]
|
||||||
|
|
||||||
%User{} ->
|
%User{} ->
|
||||||
|
|
|
@ -172,9 +172,9 @@ def show(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
||||||
def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nickname}) do
|
||||||
user = User.get_cached_by_nickname(nickname)
|
user = User.get_cached_by_nickname(nickname)
|
||||||
|
|
||||||
{:ok, updated_user} = User.deactivate(user, !user.deactivated)
|
{:ok, updated_user} = User.set_activation(user, !user.is_active)
|
||||||
|
|
||||||
action = if user.deactivated, do: "activate", else: "deactivate"
|
action = if !user.is_active, do: "activate", else: "deactivate"
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
@ -189,7 +189,7 @@ def toggle_activation(%{assigns: %{user: admin}} = conn, %{"nickname" => nicknam
|
||||||
|
|
||||||
def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
||||||
{:ok, updated_users} = User.deactivate(users, false)
|
{:ok, updated_users} = User.set_activation(users, true)
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
@ -204,7 +204,7 @@ def activate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
|
|
||||||
def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
def deactivate(%{assigns: %{user: admin}} = conn, %{"nicknames" => nicknames}) do
|
||||||
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
users = Enum.map(nicknames, &User.get_cached_by_nickname/1)
|
||||||
{:ok, updated_users} = User.deactivate(users, true)
|
{:ok, updated_users} = User.set_activation(users, false)
|
||||||
|
|
||||||
ModerationLog.insert_log(%{
|
ModerationLog.insert_log(%{
|
||||||
actor: admin,
|
actor: admin,
|
||||||
|
|
|
@ -73,7 +73,7 @@ def render("show.json", %{user: user}) do
|
||||||
"avatar" => avatar,
|
"avatar" => avatar,
|
||||||
"nickname" => user.nickname,
|
"nickname" => user.nickname,
|
||||||
"display_name" => display_name,
|
"display_name" => display_name,
|
||||||
"deactivated" => user.deactivated,
|
"is_active" => user.is_active,
|
||||||
"local" => user.local,
|
"local" => user.local,
|
||||||
"roles" => User.roles(user),
|
"roles" => User.roles(user),
|
||||||
"tags" => user.tags || [],
|
"tags" => user.tags || [],
|
||||||
|
|
|
@ -182,7 +182,7 @@ defp account_admin do
|
||||||
properties:
|
properties:
|
||||||
Map.merge(Account.schema().properties, %{
|
Map.merge(Account.schema().properties, %{
|
||||||
nickname: %Schema{type: :string},
|
nickname: %Schema{type: :string},
|
||||||
deactivated: %Schema{type: :boolean},
|
is_active: %Schema{type: :boolean},
|
||||||
local: %Schema{type: :boolean},
|
local: %Schema{type: :boolean},
|
||||||
roles: %Schema{
|
roles: %Schema{
|
||||||
type: :object,
|
type: :object,
|
||||||
|
|
|
@ -132,7 +132,7 @@ def admin_account do
|
||||||
avatar: %Schema{type: :string},
|
avatar: %Schema{type: :string},
|
||||||
nickname: %Schema{type: :string},
|
nickname: %Schema{type: :string},
|
||||||
display_name: %Schema{type: :string},
|
display_name: %Schema{type: :string},
|
||||||
deactivated: %Schema{type: :boolean},
|
is_active: %Schema{type: :boolean},
|
||||||
local: %Schema{type: :boolean},
|
local: %Schema{type: :boolean},
|
||||||
roles: %Schema{
|
roles: %Schema{
|
||||||
type: :object,
|
type: :object,
|
||||||
|
|
|
@ -376,7 +376,7 @@ defp maybe_put_allow_following_move(data, %User{id: user_id} = user, %User{id: u
|
||||||
defp maybe_put_allow_following_move(data, _, _), do: data
|
defp maybe_put_allow_following_move(data, _, _), do: data
|
||||||
|
|
||||||
defp maybe_put_activation_status(data, user, %User{is_admin: true}) do
|
defp maybe_put_activation_status(data, user, %User{is_admin: true}) do
|
||||||
Kernel.put_in(data, [:pleroma, :deactivated], user.deactivated)
|
Kernel.put_in(data, [:pleroma, :deactivated], !user.is_active)
|
||||||
end
|
end
|
||||||
|
|
||||||
defp maybe_put_activation_status(data, _, _), do: data
|
defp maybe_put_activation_status(data, _, _), do: data
|
||||||
|
|
|
@ -491,7 +491,7 @@ def render_content(object), do: object.data["content"] || ""
|
||||||
def build_tags(object_tags) when is_list(object_tags) do
|
def build_tags(object_tags) when is_list(object_tags) do
|
||||||
object_tags
|
object_tags
|
||||||
|> Enum.filter(&is_binary/1)
|
|> Enum.filter(&is_binary/1)
|
||||||
|> Enum.map(&%{name: &1, url: "/tag/#{URI.encode(&1)}"})
|
|> Enum.map(&%{name: &1, url: "#{Pleroma.Web.base_url()}/tag/#{URI.encode(&1)}"})
|
||||||
end
|
end
|
||||||
|
|
||||||
def build_tags(_), do: []
|
def build_tags(_), do: []
|
||||||
|
|
|
@ -14,7 +14,7 @@ defmodule Pleroma.Web.MongooseIM.MongooseIMController do
|
||||||
plug(RateLimiter, [name: :authentication, params: ["user"]] when action == :check_password)
|
plug(RateLimiter, [name: :authentication, params: ["user"]] when action == :check_password)
|
||||||
|
|
||||||
def user_exists(conn, %{"user" => username}) do
|
def user_exists(conn, %{"user" => username}) do
|
||||||
with %User{} <- Repo.get_by(User, nickname: username, local: true, deactivated: false) do
|
with %User{} <- Repo.get_by(User, nickname: username, local: true, is_active: true) do
|
||||||
conn
|
conn
|
||||||
|> json(true)
|
|> json(true)
|
||||||
else
|
else
|
||||||
|
@ -26,7 +26,7 @@ def user_exists(conn, %{"user" => username}) do
|
||||||
end
|
end
|
||||||
|
|
||||||
def check_password(conn, %{"user" => username, "pass" => password}) do
|
def check_password(conn, %{"user" => username, "pass" => password}) do
|
||||||
with %User{password_hash: password_hash, deactivated: false} <-
|
with %User{password_hash: password_hash, is_active: true} <-
|
||||||
Repo.get_by(User, nickname: username, local: true),
|
Repo.get_by(User, nickname: username, local: true),
|
||||||
true <- AuthenticationPlug.checkpw(password, password_hash) do
|
true <- AuthenticationPlug.checkpw(password, password_hash) do
|
||||||
conn
|
conn
|
||||||
|
|
|
@ -26,7 +26,7 @@ defp fetch_users(user_ap_ids) do
|
||||||
user_ap_ids
|
user_ap_ids
|
||||||
|> Enum.map(&Pleroma.User.get_cached_by_ap_id/1)
|
|> Enum.map(&Pleroma.User.get_cached_by_ap_id/1)
|
||||||
|> Enum.filter(fn
|
|> Enum.filter(fn
|
||||||
%{deactivated: false} -> true
|
%{is_active: true} -> true
|
||||||
_ -> false
|
_ -> false
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
|
@ -150,7 +150,7 @@ def delete_account(%{assigns: %{user: user}} = conn, params) do
|
||||||
def disable_account(%{assigns: %{user: user}} = conn, params) do
|
def disable_account(%{assigns: %{user: user}} = conn, params) do
|
||||||
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
|
case CommonAPI.Utils.confirm_current_password(user, params["password"]) do
|
||||||
{:ok, user} ->
|
{:ok, user} ->
|
||||||
User.deactivate_async(user)
|
User.set_activation_async(user, false)
|
||||||
json(conn, %{status: "success"})
|
json(conn, %{status: "success"})
|
||||||
|
|
||||||
{:error, msg} ->
|
{:error, msg} ->
|
||||||
|
|
|
@ -59,7 +59,7 @@ defp create_user(params, opts) do
|
||||||
|
|
||||||
def password_reset(nickname_or_email) do
|
def password_reset(nickname_or_email) do
|
||||||
with true <- is_binary(nickname_or_email),
|
with true <- is_binary(nickname_or_email),
|
||||||
%User{local: true, email: email, deactivated: false} = user when is_binary(email) <-
|
%User{local: true, email: email, is_active: true} = user when is_binary(email) <-
|
||||||
User.get_by_nickname_or_email(nickname_or_email),
|
User.get_by_nickname_or_email(nickname_or_email),
|
||||||
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
{:ok, token_record} <- Pleroma.PasswordResetToken.create_token(user) do
|
||||||
user
|
user
|
||||||
|
|
|
@ -9,9 +9,9 @@ defmodule Pleroma.Workers.BackgroundWorker do
|
||||||
|
|
||||||
@impl Oban.Worker
|
@impl Oban.Worker
|
||||||
|
|
||||||
def perform(%Job{args: %{"op" => "deactivate_user", "user_id" => user_id, "status" => status}}) do
|
def perform(%Job{args: %{"op" => "user_activation", "user_id" => user_id, "status" => status}}) do
|
||||||
user = User.get_cached_by_id(user_id)
|
user = User.get_cached_by_id(user_id)
|
||||||
User.perform(:deactivate_async, user, status)
|
User.perform(:set_activation_async, user, status)
|
||||||
end
|
end
|
||||||
|
|
||||||
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
def perform(%Job{args: %{"op" => "delete_user", "user_id" => user_id}}) do
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
# Pleroma: A lightweight social networking server
|
||||||
|
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
|
||||||
|
# SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
|
||||||
|
defmodule Pleroma.Repo.Migrations.RefactorDeactivatedUserField do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def up do
|
||||||
|
# Flip the values before we change the meaning of the column
|
||||||
|
execute("UPDATE users SET deactivated = NOT deactivated;")
|
||||||
|
execute("ALTER TABLE users RENAME COLUMN deactivated TO is_active;")
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN is_active SET DEFAULT true;")
|
||||||
|
execute("ALTER INDEX users_deactivated_index RENAME TO users_is_active_index;")
|
||||||
|
end
|
||||||
|
|
||||||
|
def down do
|
||||||
|
execute("UPDATE users SET is_active = NOT is_active;")
|
||||||
|
execute("ALTER TABLE users RENAME COLUMN is_active TO deactivated;")
|
||||||
|
execute("ALTER TABLE users ALTER COLUMN deactivated SET DEFAULT false;")
|
||||||
|
execute("ALTER INDEX users_is_active_index RENAME TO users_deactivated_index;")
|
||||||
|
end
|
||||||
|
end
|
Binary file not shown.
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.f77689d7.css rel=stylesheet><link href=chunk-libs.5cf7f50a.css rel=stylesheet><link href=app.6fb984d1.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.5c1034c4.js></script><script type=text/javascript src=static/js/chunk-elementUI.21957ec8.js></script><script type=text/javascript src=static/js/chunk-libs.5ca2c8e8.js></script><script type=text/javascript src=static/js/app.01bfc983.js></script></body></html>
|
<!DOCTYPE html><html><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge,chrome=1"><meta name=renderer content=webkit><meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no"><title>Admin FE</title><link rel="shortcut icon" href=favicon.ico><link href=chunk-elementUI.f77689d7.css rel=stylesheet><link href=chunk-libs.5cf7f50a.css rel=stylesheet><link href=app.6fb984d1.css rel=stylesheet></head><body><div id=app></div><script type=text/javascript src=static/js/runtime.6b30c658.js></script><script type=text/javascript src=static/js/chunk-elementUI.21957ec8.js></script><script type=text/javascript src=static/js/chunk-libs.5ca2c8e8.js></script><script type=text/javascript src=static/js/app.1428845f.js></script></body></html>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
||||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.9a4c5ede37b2f0230836.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.952124344a84613dbac0.js></script><script type=text/javascript src=/static/js/app.45547c05212c403dd77c.js></script></body></html>
|
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.9a4c5ede37b2f0230836.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.54838a79dee084ec3dad.js></script><script type=text/javascript src=/static/js/app.eb8f7164fc75862a251d.js></script></body></html>
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue