You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Only overwrite existing email after the new email has been verified
The version of the authentication-zero gem we used in our project, would directly overwrite the user's email, potentially locking the user out of their account in case of a typo, or when they lack access to that email address.
Find below my refactoring that will wait for the verification (the user receiving the verification email to their new address and clicking on the link) before replacing user.email. Hopefully it can serve as inspiration :)
Note: the example code has a JSONB field user.settings where it stores the new_email before it is verified. The new_email is then deleted from the settings field after it has been verified. It should be easy to adapt this to your own use case, e.g. a separate field new_email in the users table.
The code is also using current_user frequently instead of @user as it is rendering views (mostly) with Phlex.
app/controllers/identity/emails_controller.rb
defupdatecurrent_user.settings["new_email"]=user_params.delete(:email)ifcurrent_user.update(password_challenge: user_params[:password_challenge])send_email_and_redirect_to_rootelsenotice=current_user.errors.full_messagesrenderIdentity::Emails::EditView.new(user: current_user,notice:),status: :unprocessable_entityendendprivatedefsend_email_and_redirect_to_rootifcurrent_user.settings["new_email"].present?resend_email_verification(new_email: current_user.settings["new_email"])redirect_toroot_path,notice: "Your email has been changed"elseredirect_toroot_pathendenddefresend_email_verification(new_email:)UserMailer.with(user: current_user,new_email:).email_verification.deliver_laterend
app/mailers/user_mailer.rb
defemail_verification@user=params[:user]@new_email=params[:new_email]@signed_id=@user.generate_token_for(:email_verification)@email=@new_email || @user.emailmailto: @email,subject: "Verify your email"end
app/views/user_mailer/email_verification.html.erb
<p>Thisistoconfirmthat <%= @email %> istheemailyouwanttouseonyouraccount.Ifyoueverloseyourpassword,that's where we'llemailaresetlink.</p>
defshow@user.email=@user.settings.delete("new_email")if@user.settings["new_email"].present?@user.update!(verified: true)redirect_toroot_path,notice: "Thank you for verifying your email address"end
The text was updated successfully, but these errors were encountered:
i like the idea described in this issue, however, i am not a fan of storing the new_email in the settings JSONB column for various reasons:
if the user object already has a settings field, this may cause issues
i think, the new_email has nothing to do with settings (in a semantic way). settings should cover, for example, theme information for the application, default language, and so on.
maybe you could
create a PR to address this issue
refactor the code to use a new_email field (char) directly and change the business logic accordingly
provide tests
what do you think? I think this would be a valuable contribution to this project.
All the best
Only overwrite existing email after the new email has been verified
The version of the authentication-zero gem we used in our project, would directly overwrite the user's
email
, potentially locking the user out of their account in case of a typo, or when they lack access to that email address.Find below my refactoring that will wait for the verification (the user receiving the verification email to their new address and clicking on the link) before replacing
user.email
. Hopefully it can serve as inspiration :)app/controllers/identity/emails_controller.rb
app/mailers/user_mailer.rb
app/views/user_mailer/email_verification.html.erb
app/controllers/identity/email_verifications_controller.rb
The text was updated successfully, but these errors were encountered: