summaryrefslogtreecommitdiff
path: root/app/models/concerns/recoverable_by_any_email.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/concerns/recoverable_by_any_email.rb')
-rw-r--r--app/models/concerns/recoverable_by_any_email.rb45
1 files changed, 45 insertions, 0 deletions
diff --git a/app/models/concerns/recoverable_by_any_email.rb b/app/models/concerns/recoverable_by_any_email.rb
new file mode 100644
index 00000000000..aaea7707d51
--- /dev/null
+++ b/app/models/concerns/recoverable_by_any_email.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+# Concern that overrides the Devise methods
+# to send reset password instructions to any verified user email
+module RecoverableByAnyEmail
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def send_reset_password_instructions(attributes = {})
+ return super unless Feature.enabled?(:password_reset_any_verified_email)
+
+ email = attributes.delete(:email)
+ super unless email
+
+ recoverable = by_email_with_errors(email)
+ recoverable.send_reset_password_instructions(to: email) if recoverable&.persisted?
+ recoverable
+ end
+
+ private
+
+ def by_email_with_errors(email)
+ record = find_by_any_email(email, confirmed: true) || new
+ record.errors.add(:email, :invalid) unless record.persisted?
+ record
+ end
+ end
+
+ def send_reset_password_instructions(opts = {})
+ return super() unless Feature.enabled?(:password_reset_any_verified_email)
+
+ token = set_reset_password_token
+ send_reset_password_instructions_notification(token, opts)
+
+ token
+ end
+
+ private
+
+ def send_reset_password_instructions_notification(token, opts = {})
+ return super(token) unless Feature.enabled?(:password_reset_any_verified_email)
+
+ send_devise_notification(:reset_password_instructions, token, opts)
+ end
+end