Add confirmation page and email when a user changes the email on their account

Description

Currently, if a user changes the email address on their account, there is no method to confirm that they actually own the email address they're changing to. This can lead to situations where a user changes to an email address they do not own, and that person starts getting their emails from the site.

We would like to add a separate confirmation page and email as part of the email change process. After submitting their new email, there should be a new page created (like the muting confirmation page) where they are presented with the email they entered and asked whether this is the correct email. Upon agreeing, an email is sent to the new address and they need to confirm it by clicking on a link in the email before their account's email is actually updated. If they do not confirm within a certain length of time, the email address should not be changed.

We'll most likely want to use Devise's Confirmable module for this, which has the following option:

+reconfirmable+: requires any email changes to be confirmed (exactly the same way as initial account confirmation) to be applied. Requires additional unconfirmed_email db field to be set up (t.reconfirmable in migrations). Until confirmed, new email is stored in unconfirmed email column, and copied to email column on successful confirmation. Also, when used in conjunction with send_email_changed_notification, the notification is sent to the original email when the change is requested, not when the unconfirmed email is confirmed.

To Do: 

Update buttons at the top of the Preferences page:

  • Remove the "Orphan My Works" button

  • Update "Change My Username" button to "Change Username" (remove the "my")

  • Add "Change Password" and "Change Email" buttons at the end of the list 

Update the change email page: /users/USERNAME/change_email

  • Edit page header to remove the "my" and match the browser page title: Change My Email → Change Email 

  • Add blue banner message to the top of the form (like on the Muted Users page): 

<div class="notice">   <p>Changing your email will send a request for confirmation to your new email address and a notification to your current email address.</p>   <p>You must use the link in the confirmation email in order to finish confirming your email change. If you don't confirm your request within 7 days, the link will expire and your email address will not be changed.</p>   <p>Resubmitting this form with a new email address will <strong>invalidate any pending email change requests</strong>.</p> </div>
  • "7 days" corresponds to DAYS_TO_PURGE_UNACTIVATED

  • Form labels should all be sentence case (Current email, New email, etc)

  • Edit "Confirm New Email" form label to "Enter new email again"

  • Edit "Change Email" button to "Confirm New Email"

  • Edit incorrect password error message to: Your password was incorrect. Please try again or log out and reset your password via the link on the login form. If you are still having trouble, <a href="https://archiveofourown.org/support">contact Support</a> for help.

New email change confirmation page, like the muting confirmation page: /users/USERNAME/confirm_change_email 

  • Page header and browser page title should both be: Confirm New Email

  • Add yellow banner message to the top of the form: 

<div class="caution notice">   <p>Are you sure you want to change your email address to <strong>UNCONFIRMED_EMAIL@EXAMPLE.COM</strong>? A confirmation email will be sent to this address.</p>    <p>You must use the link in the confirmation email in order to finish confirming your email change. <strong>If you don't confirm your request within 7 days, the link will expire and your email address will not be changed.</strong></p> </div>
  • Buttons at the bottom of the form: [Cancel] [Yes, Change Email] 

Email confirmation token should not be created and emails should not be sent unless "Yes, Change Email" is clicked. Following "Cancel" should redirect the user back to the change_email page.

Upon confirming the email change, user should be redirected back to the change_email page, with a new yellow banner at the top (like on the Change Username page): 

<div class="caution notice">   <p>You have requested to change your email address to <strong>UNCONFIRMED_EMAIL@EXAMPLE.COM</strong>. A confirmation email has been sent to this address.</p>   <p><strong>You must use the link in the confirmation email in order to finish confirming your email change.</strong> Please check your spam folder or <a href="https://archiveofourown.org/support">contact Support</a> if you do not receive the confirmation email.</p>   <p><strong>If you don't confirm your request by DATE, your email address will not be changed.</strong></p> </div>
  • This banner should always be shown if an email change request is pending. After DATE passes, or if the request is confirmed via the email link, the banner should vanish.

  • DATE should be in a localized, human-readable format, like the change_username banner.

  • If the email change form is submitted again during the 7-day period, the banner should show the most recent date/unconfirmed email.

 

Emails:

  • Currently, all email footers have a “contact Support” link; the new “Email change request” email will use a new “contact Policy & Abuse” footer instead (see below for details).

  • For the HTML emails, USERNAME should be formatted with style_bold and UNCONFIRMED_EMAIL@EXAMPLE.COM should be formatted with style_email.

  • DATE should correspond with when the CONFIRMATION_URL expires.

HTML email to current address: 

[AO3] Email change request Hi USERNAME,  Someone has made a request to change the email address associated with your AO3 account.  If you made this request, check your email at UNCONFIRMED_EMAIL@EXAMPLE.COM within 7 days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please <a href="https://archiveofourown.org/support">contact Support</a>. If you entered the wrong email address, you will need to <a href="https://archiveofourown.org/users/USERNAME/change_email">submit the email change form</a> again. If you did not make this request, someone else may have access to your AO3 account. Please <a href="https://archiveofourown.org/users/password/new">reset your password now</a>. If you are unable to reset your password, <a href="https://archiveofourown.org/abuse_reports/new">contact Policy & Abuse</a>. 

TXT email to current address: 

[AO3] Email change request Hi USERNAME, Someone has made a request to change the email address associated with your AO3 account.  If you made this request, check your email at UNCONFIRMED_EMAIL@EXAMPLE.COM within 7 days to confirm your email change. If you do not receive a confirmation email, or if you have other issues, please contact Support: https://archiveofourown.org/support. If you entered the wrong email address, you will need to submit the email change form again: https://archiveofourown.org/users/USERNAME/change_email. If you did not make this request, someone else may have access to your AO3 account. Please reset your password now: https://archiveofourown.org/users/password/new. If you are unable to reset your password, contact Policy & Abuse: https://archiveofourown.org/abuse_reports/new. 

HTML email to new address: 

[AO3] Confirm your email change Hi,  Someone has made a request to change the email address associated with the AO3 account USERNAME to this email address.  If you made this request, please <a href="CONFIRMATION_URL">confirm your email change</a> within 7 days.  If you don't confirm your request by DATE, the link in this email will expire and you will need to <a href="https://archiveofourown.org/users/USERNAME/change_email">submit the email change form</a> again. If you did not make this request, you can safely ignore and delete this email. Someone else may have entered your email address by mistake.

TXT email to new address: 

[AO3] Confirm your email change Hi,  Someone has made a request to change the email address associated with the AO3 account USERNAME to this email address.  If you made this request, please confirm your email change within 7 days: CONFIRMATION_URL. If you don't confirm your request by DATE, the link in this email will expire and you will need to submit the email change form again: https://archiveofourown.org/users/USERNAME/change_email. If you did not make this request, you can safely ignore and delete this email. Someone else may have entered your email address by mistake.

Email greetings: We don't currently have a formal unaddressed greeting, and Dear doesn't lend itself well to being unaddressed. So let's do Hi comma instead: 

      greeting:         formal:           addressed_html: Hi %{name},           unaddressed: Hi,         informal:           addressed_html: Hi, %{name}!           unaddressed: Hi!

Email footers: update mailer.general.footer to allow for Support and PAC versions. 

  • The PAC footer should be otherwise identical to Support's, but replace the "contact Support" link with "contact Policy & Abuse": https://archiveofourown.org/abuse_reports/new 

  • The PAC footer should only be used on the "Email change request" mailer for now – all other mailers (including "Confirm your email change") should continue to use the Support version of the footer (and can be swapped to PAC later as needed). 

  • For clarity and consistency, the code/text of the footer has been revised: 

      footer:         about:           html: The Archive of Our Own is a fan-run and fan-supported archive that relies on %{your_donations_link}.           text: "The Archive of Our Own is a fan-run and fan-supported archive that relies on your donations: %{your_donations_url}."           your_donations: your donations         sent_at: Sent at %{sent_at}.         why_policy_abuse:           contact_policy_abuse: contact Policy & Abuse           html: If you don't understand why you received this email, please %{contact_policy_abuse_link}.           text: "If you don't understand why you received this email, please contact Policy & Abuse: %{contact_policy_abuse_url}."         why_support:           contact_support: contact Support           html: If you don't understand why you received this email, please %{contact_support_link}.           text: "If you don't understand why you received this email, please contact Support: %{contact_support_url}."

 

When following the email confirmation link: 

  • Error flash message for invalid confirmation link: 

This email confirmation link is invalid or expired. Please check your email for the correct link or submit the email change form again.
  • Valid confirmation link should lead to /users/USERNAME/change_email

    • If the user is not logged in, they will need to log in. The email should not change until they log in successfully. 

    • If they don't log in, the confirmation link should continue to work until it's expired/invalidated.

    • If they are logged in to a different account, they should be redirected to the homepage with a custom error message (not the usual "Sorry, you don't have permission to access the page you were trying to reach."): 

      • You are not logged in to the account whose email you are trying to change. Please log out and try again.

    • If they are logged in to the correct account, they should be redirected to the change_email page and the email should be updated.

  • Successful email change: 

    • There should be a period at the end of the existing flash message: Your email has been successfully updated.

    • There should not be any yellow "You have requested…" banner at the top of the page.

    • "Current Email" now displays the new email. 

Testing

  • Preferences page should: 

    • have "Change X" buttons for username/password/email 

    • not have an "Orphan My Works" button

  • Change Email page:

    • The text/buttons/links/form fields should all be correct

    • The form should work as expected for both correct and incorrect inputs

    • The incorrect password error message should have a Try again sentence and end in a period. The Support link should work.

  • Confirm Email page should have all the correct text/buttons/links.

  • The yellow pending request banner should:

    • be accurate (text, links, formatting)

    • update with a new date/email if you submit a second email while the first is pending

    • vanish upon successful confirmation

  • HTML and TXT versions of both emails should be correct, including the greetings, links, and footers.

  • The error message for trying to change the email for account A while logged in to account B should tell you to log out and try again.

  • The successful email change message should end in a period.

Deploy notes

Migration:

bundle exec rake db:migrate:up VERSION=20250407174814

Activity

Show:

therealmorticia 
April 23, 2025 at 8:28 PM

Saw the correct error messages with the correct wording when testing the three scenarios (same as current email, email used by another account, and emails don’t match).
Links are red in HTML previews.
Last sentence of change_email has the correct wording

lydia-theda 
April 23, 2025 at 7:18 PM

Got all the errors I was supposed to. This time, did not see the duplicate/incorrect flash message (I did do them in a slightly different order though). Still autofilling but whatever.

Email preview for both versions says ”log in and confirm” now.

Bilka 
April 23, 2025 at 3:00 PM
(edited)

I can’t reproduce the flash error duplication. The autofill is unrelated to this issue - the form did not change regarding this.

Edit: As is my luck, I just reproduced the flash thing. I can see how to fix it, I’ll make a PR, but testing it won’t be reliable. For autofill, that’s mostly device side as far as I know, but we can make a best effort by setting autocomplete off on the field.

lydia-theda 
April 23, 2025 at 10:41 AM
(edited)

Mail links are styled red

Html and txt versions of the PAC sentence are updated correctly

All three error messages have the updated language

I do note that I did them all in a row and when submitting the taken email after the unchanged email I still saw the “must be different” flash error above the header when the “already associated” validation message appeared, but I’m pretty sure that’s a known bug? Redoing that one for a second time, only the validation error showed.

Also on mobile safari the password autofill thinks the Enter new email again field is where my username goes and would overwrite that field, which was kind of annoying when I’d already entered an email twice. (Compared to desktop chrome where the autofill ran upon page load and treated the New email field as a username field, so I manually cleared it when entering the emails.) I don’t know if it’s possible to suppress autofill for these two email fields while leaving the password field, but that might also be device specific and thus not within scope for this issue…

Bilka 
April 22, 2025 at 9:59 PM
(edited)

Based on Lydia's testing and feedback, further changes need to be made. On the change email page (/users/USERNAME/change_email), the following errors should be added/reworded:

  • When entering the same email address as currently used for the account, it should error with Your new email address must be different from your current email.

  • When entering an email already in use by an existing account, it should error with This email is already associated with another account. Please try again with a different email address.

  • When entering two different emails in the "New email" and "Enter new email again" fields, it should error with The email addresses you entered do not match. Please try again.


In the two mails, there are a few changes that can be tested with the mailer previews, https://test.archiveofourown.org/rails/mailers/user_mailer/change_email and https://test.archiveofourown.org/rails/mailers/archive_devise_mailer/confirmation_instructions:

  • All links in both HTML mails should be red (instead of blue).

  • The last sentence in the notification to the original email address (change_email) should be changed:

    • HTML mail: From Please <reset your password now>. If you are unable to reset your password, <contact Policy & Abuse>. to Please <reset your password now> or <contact Policy & Abuse>.

    • Plain-text mail: From Please reset your password now: RESET_PASSWORD_URL. If you are unable to reset your password, contact Policy & Abuse: CONTACT_POLICY_ABUSE_URL. to Please reset your password now (RESET_PASSWORD_URL) or contact Policy & Abuse: CONTACT_POLICY_ABUSE_URL.

DeployedToBeta

Details

Assignee

Reporter

Roadmap

Users

Priority

Affects versions

Fix versions

Components

BackEnd

Difficulty

Milestone

Sentry

Created September 2, 2022 at 11:16 PM
Updated April 24, 2025 at 9:44 PM
Resolved April 24, 2025 at 9:44 PM