field(:confirmation_token, :string, default: nil)
field(:default_scope, :string, default: "public")
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(:ap_enabled, :boolean, default: false)
field(:is_moderator, :boolean, default: false)
field(:inbox, :string)
field(:shared_inbox, :string)
field(:accepts_chat_messages, :boolean, default: nil)
+ field(:last_active_at, :naive_datetime)
embeds_one(
:notification_settings,
target_users_query = assoc(user, unquote(outgoing_relation_target))
if restrict_deactivated? do
- restrict_deactivated(target_users_query)
+ target_users_query
+ |> User.Query.build(%{deactivated: false})
else
target_users_query
end
@doc "Returns status account"
@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{local: true, is_approved: false}), do: :approval_pending
-
- def account_status(%User{local: true, is_confirmed: false}) do
- if Config.get([:instance, :account_activation_required]) do
- :confirmation_pending
- else
- :active
- end
- end
-
+ def account_status(%User{local: true, is_confirmed: false}), do: :confirmation_pending
def account_status(%User{}), do: :active
@spec visible_for(User.t(), User.t() | nil) ::
def ap_following(%User{following_address: fa}) when is_binary(fa), do: fa
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
if Map.has_key?(params, :fields) do
Map.put(params, :fields, Enum.map(params[:fields], &truncate_field/1))
candidates = Config.get([:instance, :autofollowed_nicknames])
autofollowed_users =
- User.Query.build(%{nickname: candidates, local: true, deactivated: false})
+ User.Query.build(%{nickname: candidates, local: true, is_active: true})
|> Repo.all()
follow_all(user, autofollowed_users)
end
def post_register_action(%User{is_confirmed: false} = user) do
- with {:ok, _} <- try_send_confirmation_email(user) do
+ with {:ok, _} <- maybe_send_confirmation_email(user) do
{:ok, user}
end
end
with {:ok, user} <- autofollow_users(user),
{:ok, _} <- autofollowing_users(user),
{:ok, user} <- set_cache(user),
- {:ok, _} <- send_welcome_email(user),
- {:ok, _} <- send_welcome_message(user),
- {:ok, _} <- send_welcome_chat_message(user) do
+ {:ok, _} <- maybe_send_registration_email(user),
+ {:ok, _} <- maybe_send_welcome_email(user),
+ {:ok, _} <- maybe_send_welcome_message(user),
+ {:ok, _} <- maybe_send_welcome_chat_message(user) do
{:ok, user}
end
end
{:ok, :enqueued}
end
- def send_welcome_message(user) do
+ defp maybe_send_welcome_message(user) do
if User.WelcomeMessage.enabled?() do
User.WelcomeMessage.post_message(user)
{:ok, :enqueued}
end
end
- def send_welcome_chat_message(user) do
+ defp maybe_send_welcome_chat_message(user) do
if User.WelcomeChatMessage.enabled?() do
User.WelcomeChatMessage.post_message(user)
{:ok, :enqueued}
end
end
- def send_welcome_email(%User{email: email} = user) when is_binary(email) do
+ defp maybe_send_welcome_email(%User{email: email} = user) when is_binary(email) do
if User.WelcomeEmail.enabled?() do
User.WelcomeEmail.send_email(user)
{:ok, :enqueued}
end
end
- def send_welcome_email(_), do: {:ok, :noop}
+ defp maybe_send_welcome_email(_), do: {:ok, :noop}
- @spec try_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
- def try_send_confirmation_email(%User{is_confirmed: false, email: email} = user)
+ @spec maybe_send_confirmation_email(User.t()) :: {:ok, :enqueued | :noop}
+ def maybe_send_confirmation_email(%User{is_confirmed: false, email: email} = user)
when is_binary(email) do
if Config.get([:instance, :account_activation_required]) do
send_confirmation_email(user)
end
end
- def try_send_confirmation_email(_), do: {:ok, :noop}
+ def maybe_send_confirmation_email(_), do: {:ok, :noop}
@spec send_confirmation_email(Uset.t()) :: User.t()
def send_confirmation_email(%User{} = user) do
user
end
+ @spec maybe_send_registration_email(User.t()) :: {:ok, :enqueued | :noop}
+ defp maybe_send_registration_email(%User{email: email} = user) when is_binary(email) do
+ with false <- User.WelcomeEmail.enabled?(),
+ false <- Config.get([:instance, :account_activation_required], false),
+ false <- Config.get([:instance, :account_approval_required], false) do
+ user
+ |> Pleroma.Emails.UserEmail.successful_registration_email()
+ |> Pleroma.Emails.Mailer.deliver_async()
+
+ {:ok, :enqueued}
+ else
+ _ ->
+ {:ok, :noop}
+ end
+ end
+
+ defp maybe_send_registration_email(_), do: {:ok, :noop}
+
def needs_update?(%User{local: true}), do: false
def needs_update?(%User{local: false, last_refreshed_at: nil}), do: true
deny_follow_blocked = Config.get([:user, :deny_follow_blocked])
cond do
- followed.deactivated ->
+ not followed.is_active ->
{:error, "Could not follow user: #{followed.nickname} is deactivated."}
deny_follow_blocked and blocks?(followed, follower) ->
@spec get_followers_query(User.t(), pos_integer() | nil) :: Ecto.Query.t()
def get_followers_query(%User{} = user, nil) do
- User.Query.build(%{followers: user, deactivated: false})
+ User.Query.build(%{followers: user, is_active: true})
end
def get_followers_query(%User{} = user, page) do
@spec get_users_from_set([String.t()], keyword()) :: [User.t()]
def get_users_from_set(ap_ids, opts \\ []) do
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
User.Query.build(criteria)
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
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
|> Repo.all()
defp maybe_filter_on_ap_id(query, _ap_ids), do: query
- def deactivate_async(user, status \\ true) do
- BackgroundWorker.enqueue("deactivate_user", %{"user_id" => user.id, "status" => status})
+ def set_activation_async(user, status \\ true) do
+ BackgroundWorker.enqueue("user_activation", %{"user_id" => user.id, "status" => status})
end
- def deactivate(user, status \\ true)
-
- def deactivate(users, status) when is_list(users) do
+ @spec set_activation([User.t()], boolean()) :: {:ok, User.t()} | {:error, Changeset.t()}
+ def set_activation(users, status) when is_list(users) do
Repo.transaction(fn ->
- for user <- users, do: deactivate(user, status)
+ for user <- users, do: set_activation(user, status)
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
user
|> get_followers()
registration_reason: nil,
confirmation_token: nil,
domain_blocks: [],
- deactivated: true,
+ is_active: false,
ap_enabled: false,
is_moderator: false,
is_admin: false,
delete_or_deactivate(user)
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()
def external_users_query do
|> hd()
end
+ def full_nickname(%User{} = user) do
+ if String.contains?(user.nickname, "@") do
+ user.nickname
+ else
+ %{host: host} = URI.parse(user.ap_id)
+ user.nickname <> "@" <> host
+ end
+ end
+
def full_nickname(nickname_or_mention),
do: String.trim_leading(nickname_or_mention, "@")
@spec all_superusers() :: [User.t()]
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()
end
left_join: a in Pleroma.Activity,
on: u.ap_id == a.actor,
where: not is_nil(u.nickname),
- where: u.deactivated != ^true,
+ where: u.is_active == ^true,
where: u.id not in ^has_read_notifications,
group_by: u.id,
having:
end
# Internal function; public one is `deactivate/2`
- defp set_activation_status(user, deactivated) do
+ defp set_activation_status(user, status) do
user
- |> cast(%{deactivated: deactivated}, [:deactivated])
+ |> cast(%{is_active: status}, [:is_active])
|> update_and_set_cache()
end
def get_host(%User{ap_id: ap_id} = _user) do
URI.parse(ap_id).host
end
+
+ def update_last_active_at(%__MODULE__{local: true} = user) do
+ user
+ |> cast(%{last_active_at: NaiveDateTime.utc_now()}, [:last_active_at])
+ |> update_and_set_cache()
+ end
+
+ def active_user_count(weeks \\ 4) do
+ active_after = Timex.shift(NaiveDateTime.utc_now(), weeks: -weeks)
+
+ __MODULE__
+ |> where([u], u.last_active_at >= ^active_after)
+ |> where([u], u.local == true)
+ |> Repo.aggregate(:count)
+ end
end