This implements what is known as "paranoid" password reset flash messages (using the terminology from Devise). It avoids revealing whether the supplied email address is already registered. Added an explicit test for this situation, so that the test for email non-existance is separate from the duplicate-case tests.
81 lines
2.1 KiB
Ruby
81 lines
2.1 KiB
Ruby
class PasswordsController < ApplicationController
|
|
include SessionMethods
|
|
|
|
layout "site"
|
|
|
|
before_action :authorize_web
|
|
before_action :set_locale
|
|
before_action :check_database_readable
|
|
|
|
authorize_resource :class => false
|
|
|
|
before_action :check_database_writable
|
|
|
|
def new
|
|
@title = t ".title"
|
|
end
|
|
|
|
def edit
|
|
@title = t ".title"
|
|
|
|
if params[:token]
|
|
self.current_user = User.find_by_token_for(:password_reset, params[:token]) ||
|
|
UserToken.unexpired.find_by(:token => params[:token])&.user
|
|
|
|
if current_user.nil?
|
|
flash[:error] = t ".flash token bad"
|
|
redirect_to :action => "new"
|
|
end
|
|
else
|
|
head :bad_request
|
|
end
|
|
end
|
|
|
|
def create
|
|
user = User.visible.find_by(:email => params[:email])
|
|
|
|
if user.nil?
|
|
users = User.visible.where("LOWER(email) = LOWER(?)", params[:email])
|
|
|
|
user = users.first if users.count == 1
|
|
end
|
|
|
|
if user
|
|
token = user.generate_token_for(:password_reset)
|
|
UserMailer.lost_password(user, token).deliver_later
|
|
end
|
|
|
|
flash[:notice] = t ".send_paranoid_instructions"
|
|
redirect_to login_path
|
|
end
|
|
|
|
def update
|
|
if params[:token]
|
|
self.current_user = User.find_by_token_for(:password_reset, params[:token]) ||
|
|
UserToken.unexpired.find_by(:token => params[:token])&.user
|
|
|
|
if current_user
|
|
if params[:user]
|
|
current_user.pass_crypt = params[:user][:pass_crypt]
|
|
current_user.pass_crypt_confirmation = params[:user][:pass_crypt_confirmation]
|
|
current_user.activate if current_user.may_activate?
|
|
current_user.email_valid = true
|
|
|
|
if current_user.save
|
|
UserToken.delete_by(:token => params[:token])
|
|
session[:fingerprint] = current_user.fingerprint
|
|
flash[:notice] = t ".flash changed"
|
|
successful_login(current_user)
|
|
else
|
|
render :edit
|
|
end
|
|
end
|
|
else
|
|
flash[:error] = t ".flash token bad"
|
|
redirect_to :action => "new"
|
|
end
|
|
else
|
|
head :bad_request
|
|
end
|
|
end
|
|
end
|