Allow to edit account email and delete account
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
@@ -20,7 +20,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
|
||||
%{context: %{current_user: %User{id: id} = user}}
|
||||
) do
|
||||
with {:is_owned, %Actor{}} <- User.owns_actor(user, actor_id),
|
||||
{:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id, "actor_id" => actor_id}) do
|
||||
{:ok, feed_token} <- Events.create_feed_token(%{user_id: id, actor_id: actor_id}) do
|
||||
{:ok, feed_token}
|
||||
else
|
||||
{:is_owned, nil} ->
|
||||
@@ -33,7 +33,7 @@ defmodule Mobilizon.GraphQL.Resolvers.FeedToken do
|
||||
"""
|
||||
@spec create_feed_token(any, map, map) :: {:ok, FeedToken.t()}
|
||||
def create_feed_token(_parent, %{}, %{context: %{current_user: %User{id: id}}}) do
|
||||
with {:ok, feed_token} <- Events.create_feed_token(%{"user_id" => id}) do
|
||||
with {:ok, feed_token} <- Events.create_feed_token(%{user_id: id}) do
|
||||
{:ok, feed_token}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,6 +7,7 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
|
||||
alias Mobilizon.{Actors, Config, Events, Users}
|
||||
alias Mobilizon.Actors.Actor
|
||||
alias Mobilizon.Crypto
|
||||
alias Mobilizon.Storage.Repo
|
||||
alias Mobilizon.Users.User
|
||||
|
||||
@@ -14,6 +15,8 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
|
||||
require Logger
|
||||
|
||||
@confirmation_token_length 30
|
||||
|
||||
@doc """
|
||||
Find an user by its ID
|
||||
"""
|
||||
@@ -298,4 +301,82 @@ defmodule Mobilizon.GraphQL.Resolvers.User do
|
||||
def change_password(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to change your password"}
|
||||
end
|
||||
|
||||
def change_email(_parent, %{email: new_email, password: password}, %{
|
||||
context: %{current_user: %User{email: old_email, password_hash: password_hash} = user}
|
||||
}) do
|
||||
with {:current_password, true} <-
|
||||
{:current_password, Argon2.verify_pass(password, password_hash)},
|
||||
{:same_email, false} <- {:same_email, new_email == old_email},
|
||||
{:email_valid, true} <- {:email_valid, Email.Checker.valid?(new_email)},
|
||||
{:ok, %User{} = user} <-
|
||||
user
|
||||
|> User.changeset(%{
|
||||
unconfirmed_email: new_email,
|
||||
confirmation_token: Crypto.random_string(@confirmation_token_length),
|
||||
confirmation_sent_at: DateTime.utc_now() |> DateTime.truncate(:second)
|
||||
})
|
||||
|> Repo.update() do
|
||||
user
|
||||
|> Email.User.send_email_reset_old_email()
|
||||
|> Email.Mailer.deliver_later()
|
||||
|
||||
user
|
||||
|> Email.User.send_email_reset_new_email()
|
||||
|> Email.Mailer.deliver_later()
|
||||
|
||||
{:ok, user}
|
||||
else
|
||||
{:current_password, false} ->
|
||||
{:error, "The password provided is invalid"}
|
||||
|
||||
{:same_email, true} ->
|
||||
{:error, "The new email must be different"}
|
||||
|
||||
{:email_valid, _} ->
|
||||
{:error, "The new email doesn't seem to be valid"}
|
||||
end
|
||||
end
|
||||
|
||||
def change_email(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to change your email"}
|
||||
end
|
||||
|
||||
def validate_email(_parent, %{token: token}, _resolution) do
|
||||
with %User{} = user <- Users.get_user_by_activation_token(token),
|
||||
{:ok, %User{} = user} <-
|
||||
user
|
||||
|> User.changeset(%{
|
||||
email: user.unconfirmed_email,
|
||||
unconfirmed_email: nil,
|
||||
confirmation_token: nil,
|
||||
confirmation_sent_at: nil
|
||||
})
|
||||
|> Repo.update() do
|
||||
{:ok, user}
|
||||
end
|
||||
end
|
||||
|
||||
def delete_account(_parent, %{password: password}, %{
|
||||
context: %{current_user: %User{password_hash: password_hash} = user}
|
||||
}) do
|
||||
with {:current_password, true} <-
|
||||
{:current_password, Argon2.verify_pass(password, password_hash)},
|
||||
actors <- Users.get_actors_for_user(user),
|
||||
# Detach actors from user
|
||||
:ok <- Enum.each(actors, fn actor -> Actors.update_actor(actor, %{user_id: nil}) end),
|
||||
# Launch a background job to delete actors
|
||||
:ok <- Enum.each(actors, &Actors.delete_actor/1),
|
||||
# Delete user
|
||||
{:ok, user} <- Users.delete_user(user) do
|
||||
{:ok, user}
|
||||
else
|
||||
{:current_password, false} ->
|
||||
{:error, "The password provided is invalid"}
|
||||
end
|
||||
end
|
||||
|
||||
def delete_account(_parent, _args, _resolution) do
|
||||
{:error, "You need to be logged-in to delete your account"}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -178,5 +178,21 @@ defmodule Mobilizon.GraphQL.Schema.UserType do
|
||||
arg(:new_password, non_null(:string))
|
||||
resolve(&User.change_password/3)
|
||||
end
|
||||
|
||||
field :change_email, :user do
|
||||
arg(:email, non_null(:string))
|
||||
arg(:password, non_null(:string))
|
||||
resolve(&User.change_email/3)
|
||||
end
|
||||
|
||||
field :validate_email, :user do
|
||||
arg(:token, non_null(:string))
|
||||
resolve(&User.validate_email/3)
|
||||
end
|
||||
|
||||
field :delete_account, :deleted_object do
|
||||
arg(:password, non_null(:string))
|
||||
resolve(&User.delete_account/3)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user