My app has a pre-subscription system to allow users to subscribe without password.
But malicious users who haven't finished their subscription (= don't have a password yet) could follow the password recovery process to set theirselves a password and brake the usual subscription process.
So I would like Devise to provide password recovery to only the users who are validated (namely users who finished their subscription).
If a non-validated user is entering his email to try to get a new password, I would like to show him the "email not found" error, as if he wasn't found at all.
I didn't find where to override Devise to add such a scope.
This method from the Recoverable
seems to fit but I haven't been able to customize it:
# Attempt to find a user by its email. If a record is found, send new
# password instructions to it. If user is not found, returns a new user
# with an email not found error.
# Attributes must contain the user's email
def send_reset_password_instructions(attributes={})
recoverable = find_or_initialize_with_errors(reset_password_keys, attributes, :not_found)
recoverable.send_reset_password_instructions if recoverable.persisted?
recoverable
end
So for the moment I overrode the PasswordsController
but this is not a clean solution.
class Users::PasswordsController < Devise::PasswordsController
def create
if resource_params[:email].present? && resource_class.registration_complete.where(email: resource_params[:email]).none?
self.resource = resource_class.new
self.resource.errors.add(:email, :not_found)
render :new
else
super
end
end
end