44 lines
1.3 KiB
Ruby
44 lines
1.3 KiB
Ruby
module Users
|
|
class ChangePassword
|
|
Result = Struct.new(:ok?, :error, keyword_init: true)
|
|
|
|
def self.call(user:, current_password:, password:, password_confirmation:)
|
|
new(
|
|
user: user,
|
|
current_password: current_password,
|
|
password: password,
|
|
password_confirmation: password_confirmation
|
|
).call
|
|
end
|
|
|
|
def initialize(user:, current_password:, password:, password_confirmation:)
|
|
@user = user
|
|
@current_password = current_password.to_s
|
|
@password = password.to_s
|
|
@password_confirmation = password_confirmation.to_s
|
|
end
|
|
|
|
def call
|
|
unless @user.authenticate(@current_password)
|
|
return Result.new(ok?: false, error: :current_incorrect)
|
|
end
|
|
|
|
if @password != @password_confirmation
|
|
return Result.new(ok?: false, error: :mismatch)
|
|
end
|
|
|
|
if (code = PasswordComplexity.violation(@password))
|
|
return Result.new(ok?: false, error: code == :blank ? :too_short : code)
|
|
end
|
|
|
|
unless @user.update(password: @password)
|
|
complexity_error = @user.errors.details[:password]&.any? { |d| d[:error] == :complexity }
|
|
return Result.new(ok?: false, error: complexity_error ? :too_weak : :too_short)
|
|
end
|
|
|
|
@user.clear_password_reset!
|
|
Result.new(ok?: true)
|
|
end
|
|
end
|
|
end
|