[Backend] Allow to change your password

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel
2019-09-24 18:08:33 +02:00
parent 9820d4b904
commit f129d4137d
4 changed files with 245 additions and 2 deletions

View File

@@ -43,7 +43,9 @@ defmodule Mobilizon.Users.User do
@registration_required_attrs [:email, :password]
@password_reset_required_attrs [:password, :reset_password_token, :reset_password_sent_at]
@password_change_required_attrs [:password]
@password_reset_required_attrs @password_change_required_attrs ++
[:reset_password_token, :reset_password_sent_at]
@confirmation_token_length 30
@@ -107,8 +109,22 @@ defmodule Mobilizon.Users.User do
@doc false
@spec password_reset_changeset(t, map) :: Ecto.Changeset.t()
def password_reset_changeset(%__MODULE__{} = user, attrs) do
password_change_changeset(user, attrs, @password_reset_required_attrs)
end
@doc """
Changeset to change a password
It checks the minimum requirements for a password and hashes it.
"""
@spec password_change_changeset(t, map) :: Ecto.Changeset.t()
def password_change_changeset(
%__MODULE__{} = user,
attrs,
required_attrs \\ @password_change_required_attrs
) do
user
|> cast(attrs, @password_reset_required_attrs)
|> cast(attrs, required_attrs)
|> validate_length(:password,
min: 6,
max: 100,

View File

@@ -7,6 +7,7 @@ defmodule MobilizonWeb.Resolvers.User do
alias Mobilizon.Actors.Actor
alias Mobilizon.Service.Users.{ResetPassword, Activation}
alias Mobilizon.Users.User
alias Mobilizon.Storage.Repo
import Mobilizon.Users.Guards
@@ -238,4 +239,34 @@ defmodule MobilizonWeb.Resolvers.User do
{:ok, participations}
end
end
def change_password(_parent, %{old_password: old_password, new_password: new_password}, %{
context: %{current_user: %User{password_hash: old_password_hash} = user}
}) do
with {:current_password, true} <-
{:current_password, Argon2.verify_pass(old_password, old_password_hash)},
{:same_password, false} <- {:same_password, old_password == new_password},
{:ok, %User{} = user} <-
user
|> User.password_change_changeset(%{
"password" => new_password
})
|> Repo.update() do
{:ok, user}
else
{:current_password, false} ->
{:error, "The current password is invalid"}
{:same_password, true} ->
{:error, "The new password must be different"}
{:error, %Ecto.Changeset{errors: [password: {"registration.error.password_too_short", _}]}} ->
{:error,
"The password you have chosen is too short. Please make sure your password contains at least 6 characters."}
end
end
def change_password(_parent, _args, _resolution) do
{:error, "You need to be logged-in to change your password"}
end
end

View File

@@ -159,5 +159,12 @@ defmodule MobilizonWeb.Schema.UserType do
arg(:preferred_username, non_null(:string))
resolve(&User.change_default_actor/3)
end
@desc "Change an user password"
field :change_password, :user do
arg(:old_password, non_null(:string))
arg(:new_password, non_null(:string))
resolve(&User.change_password/3)
end
end
end