diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d0924e76e35..592a80cdfc5 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -687,6 +687,25 @@ class ApplicationController < ActionController::Base
     request.original_url unless request.original_url =~ /uploads/
   end
 
+  def redirect_to_login
+    dont_cache_page
+
+    if SiteSetting.enable_sso?
+      # save original URL in a session so we can redirect after login
+      session[:destination_url] = destination_url
+      redirect_to path('/session/sso')
+    elsif !SiteSetting.enable_local_logins && Discourse.enabled_authenticators.length == 1 && !cookies[:authentication_data]
+      # Only one authentication provider, direct straight to it.
+      # If authentication_data is present, then we are halfway though registration. Don't redirect offsite
+      cookies[:destination_url] = destination_url
+      redirect_to path("/auth/#{Discourse.enabled_authenticators.first.name}")
+    else
+      # save original URL in a cookie (javascript redirects after login in this case)
+      cookies[:destination_url] = destination_url
+      redirect_to path("/login")
+    end
+  end
+
   def redirect_to_login_if_required
     return if request.format.json? && is_api?
 
@@ -715,24 +734,8 @@ class ApplicationController < ActionController::Base
 
     if !current_user && SiteSetting.login_required?
       flash.keep
-      dont_cache_page
-
-      if SiteSetting.enable_sso?
-        # save original URL in a session so we can redirect after login
-        session[:destination_url] = destination_url
-        redirect_to path('/session/sso')
-        return
-      elsif !SiteSetting.enable_local_logins && Discourse.enabled_authenticators.length == 1 && !cookies[:authentication_data]
-        # Only one authentication provider, direct straight to it.
-        # If authentication_data is present, then we are halfway though registration. Don't redirect offsite
-        cookies[:destination_url] = destination_url
-        redirect_to path("/auth/#{Discourse.enabled_authenticators.first.name}")
-      else
-        # save original URL in a cookie (javascript redirects after login in this case)
-        cookies[:destination_url] = destination_url
-        redirect_to path("/login")
-        return
-      end
+      redirect_to_login
+      return
     end
 
     check_totp = current_user &&
diff --git a/app/controllers/users_email_controller.rb b/app/controllers/users_email_controller.rb
index f74f60a94a2..aaead3bf624 100644
--- a/app/controllers/users_email_controller.rb
+++ b/app/controllers/users_email_controller.rb
@@ -4,8 +4,26 @@ class UsersEmailController < ApplicationController
 
   requires_login only: [:index, :update]
 
-  skip_before_action :check_xhr, only: [:confirm]
-  skip_before_action :redirect_to_login_if_required, only: [:confirm]
+  skip_before_action :check_xhr, only: [
+    :confirm_old_email,
+    :show_confirm_old_email,
+    :confirm_new_email,
+    :show_confirm_new_email
+  ]
+
+  skip_before_action :redirect_to_login_if_required, only: [
+    :confirm_old_email,
+    :show_confirm_old_email,
+    :confirm_new_email,
+    :show_confirm_new_email
+  ]
+
+  before_action :require_login, only: [
+    :confirm_old_email,
+    :show_confirm_old_email,
+    :confirm_new_email,
+    :show_confirm_new_email
+  ]
 
   def index
   end
@@ -29,38 +47,141 @@ class UsersEmailController < ApplicationController
     render_json_error(I18n.t("rate_limiter.slow_down"))
   end
 
-  def confirm
-    expires_now
+  def confirm_new_email
+    load_change_request(:new)
 
-    token = EmailToken.confirmable(params[:token])
-    user = token&.user
+    if @change_request&.change_state != EmailChangeRequest.states[:authorizing_new]
+      @error = I18n.t("change_email.already_done")
+    end
 
-    change_request =
-      if user
-        user.email_change_requests.where(new_email_token_id: token.id).first
-      end
+    redirect_url = path("/u/confirm-new-email/#{params[:token]}")
 
-    if change_request&.change_state == EmailChangeRequest.states[:authorizing_new] &&
-       user.totp_enabled? && !user.authenticate_second_factor(params[:second_factor_token], params[:second_factor_method].to_i)
+    if !@error && @user.totp_enabled? && !@user.authenticate_second_factor(params[:second_factor_token], params[:second_factor_method].to_i)
+      RateLimiter.new(nil, "second-factor-min-#{request.remote_ip}", 3, 1.minute).performed!
+      flash[:invalid_second_factor] = true
+      redirect_to redirect_url
+      return
+    end
 
-      @update_result = :invalid_second_factor
-      @backup_codes_enabled = true if user.backup_codes_enabled?
-
-      if params[:second_factor_token].present?
-        RateLimiter.new(nil, "second-factor-min-#{request.remote_ip}", 3, 1.minute).performed!
-        @show_invalid_second_factor_error = true
-      end
-    else
+    if !@error
       updater = EmailUpdater.new
-      @update_result = updater.confirm(params[:token])
-
-      if @update_result == :complete
+      if updater.confirm(params[:token]) == :complete
         updater.user.user_stat.reset_bounce_score!
-        log_on_user(updater.user)
+      else
+        @error = I18n.t("change_email.already_done")
       end
     end
 
+    if @error
+      flash[:error] = @error
+      redirect_to redirect_url
+    else
+      redirect_to "#{redirect_url}?done=true"
+    end
+  end
+
+  def show_confirm_new_email
+    load_change_request(:new)
+
+    if params[:done].to_s == "true"
+      @done = true
+    end
+
+    if @change_request&.change_state != EmailChangeRequest.states[:authorizing_new]
+      @error = I18n.t("change_email.already_done")
+    end
+
+    @show_invalid_second_factor_error = flash[:invalid_second_factor]
+
+    if !@error
+      if @user.totp_enabled?
+        @backup_codes_enabled = @user.backup_codes_enabled?
+        if params[:show_backup].to_s == "true" && @backup_codes_enabled
+          @show_backup_codes = true
+        else
+          @show_second_factor = true
+        end
+      end
+
+      @to_email = @change_request.new_email
+    end
+
     render layout: 'no_ember'
   end
 
+  def confirm_old_email
+    load_change_request(:old)
+
+    if @change_request&.change_state != EmailChangeRequest.states[:authorizing_old]
+      @error = I18n.t("change_email.already_done")
+    end
+
+    redirect_url = path("/u/confirm-old-email/#{params[:token]}")
+
+    if !@error
+      updater = EmailUpdater.new
+      if updater.confirm(params[:token]) != :authorizing_new
+        @error = I18n.t("change_email.already_done")
+      end
+    end
+
+    if @error
+      flash[:error] = @error
+      redirect_to redirect_url
+    else
+      redirect_to "#{redirect_url}?done=true"
+    end
+  end
+
+  def show_confirm_old_email
+    load_change_request(:old)
+
+    if @change_request&.change_state != EmailChangeRequest.states[:authorizing_old]
+      @error = I18n.t("change_email.already_done")
+    end
+
+    if params[:done].to_s == "true"
+      @almost_done = true
+    end
+
+    if !@error
+      @from_email = @user.email
+      @to_email = @change_request.new_email
+    end
+
+    render layout: 'no_ember'
+  end
+
+  private
+
+  def load_change_request(type)
+    expires_now
+
+    @token = EmailToken.confirmable(params[:token])
+
+    if @token
+      if type == :old
+        @change_request = @token.user&.email_change_requests.where(old_email_token_id: @token.id).first
+      elsif type == :new
+        @change_request = @token.user&.email_change_requests.where(new_email_token_id: @token.id).first
+      end
+    end
+
+    @user = @token&.user
+
+    if (!@user || !@change_request)
+      @error = I18n.t("change_email.already_done")
+    end
+
+    if current_user.id != @user&.id
+      @error = I18n.t 'change_email.wrong_account_error'
+    end
+  end
+
+  def require_login
+    if !current_user
+      redirect_to_login
+    end
+  end
+
 end
diff --git a/app/views/users_email/confirm.html.erb b/app/views/users_email/confirm.html.erb
deleted file mode 100644
index 69d63eecce7..00000000000
--- a/app/views/users_email/confirm.html.erb
+++ /dev/null
@@ -1,47 +0,0 @@
-<div id="simple-container">
-  <% if @update_result == :authorizing_new %>
-    <h2><%= t 'change_email.authorizing_old.title' %></h2>
-    <br>
-    <p><%= t 'change_email.authorizing_old.description' %></p>
-  <% elsif @update_result == :complete %>
-    <h2><%= t 'change_email.confirmed' %></h2>
-    <br>
-    <a class="btn" href="/"><%= t('change_email.please_continue', site_name: SiteSetting.title) %></a>
-  <% elsif @update_result == :invalid_second_factor%>
-    <% if !params[:show_backup] || params[:show_backup] == "false" %>
-      <div id="primary-second-factor-form">
-        <h2><%= t('login.second_factor_title') %></h2>
-        <br>
-        <%=form_tag({}, method: :put) do %>
-          <%= label_tag(:second_factor_token, t('login.second_factor_description')) %>
-          <div><%= render 'common/second_factor_text_field' %></div>
-          <% if @show_invalid_second_factor_error %>
-            <div class='alert alert-error'><%= t('login.invalid_second_factor_code') %></div>
-          <% end %>
-          <%= submit_tag t('submit'), class: "btn btn-primary" %>
-        <% end %>
-      </div>
-      <% if @backup_codes_enabled %>
-        <%= link_to t("login.second_factor_toggle.backup_code"), show_backup: "true" %>
-      <% end %>
-    <% end %>
-
-    <% if @backup_codes_enabled && params[:show_backup] == "true" %>
-      <div id="backup-second-factor-form" style="">
-        <h2><%= t('login.second_factor_backup_title') %></h2>
-        <br>
-        <%= form_tag({}, method: :put) do%>
-          <%= label_tag(:second_factor_token, t("login.second_factor_backup_description")) %>
-          <div><%= render 'common/second_factor_backup_input' %></div>
-          <%= submit_tag(t("submit"), class: "btn btn-primary") %>
-        <%end%>
-
-      </div>
-      <%= link_to t("login.second_factor_toggle.totp"), show_backup: "false" %>
-    <%end%>
-  <% else %>
-    <div class='alert alert-error'>
-      <%=t 'change_email.already_done' %>
-    </div>
-  <% end %>
-</div>
diff --git a/app/views/users_email/show_confirm_new_email.html.erb b/app/views/users_email/show_confirm_new_email.html.erb
new file mode 100644
index 00000000000..fe14cf53df2
--- /dev/null
+++ b/app/views/users_email/show_confirm_new_email.html.erb
@@ -0,0 +1,51 @@
+<div id="simple-container">
+  <% if @done %>
+    <h2>
+      <%= t 'change_email.confirmed' %>
+    </h2>
+    <p>
+    <a class="btn" href="<%= path "/" %>"><%= t('change_email.please_continue', site_name: SiteSetting.title) %></a>
+    </p>
+  <% elsif @error %>
+    <div class='alert alert-error'>
+      <%= @error %>
+    </div>
+  <% else %>
+    <h2><%= t 'change_email.authorizing_new.title' %></h2>
+    <p>
+      <%= t 'change_email.authorizing_new.description' %>
+    </p>
+    <p>
+      <%= @to_email %>
+    </p>
+
+    <%=form_tag(u_confirm_new_email_path, method: :put) do %>
+      <%= hidden_field_tag 'token', @token.token %>
+
+      <% if @show_backup_codes %>
+        <div id="backup-second-factor-form" style="">
+          <h3><%= t('login.second_factor_backup_title') %></h3>
+            <%= label_tag(:second_factor_token, t("login.second_factor_backup_description")) %>
+            <div><%= render 'common/second_factor_backup_input' %></div>
+            <%= submit_tag(t("submit"), class: "btn btn-primary") %>
+        </div>
+        <%= link_to t("login.second_factor_toggle.totp"), show_backup: "false" %>
+      <% elsif @show_second_factor %>
+        <div id="primary-second-factor-form">
+          <h3><%= t('login.second_factor_title') %></h3>
+          <%= label_tag(:second_factor_token, t('login.second_factor_description')) %>
+          <div><%= render 'common/second_factor_text_field' %></div>
+          <% if @show_invalid_second_factor_error %>
+            <div class='alert alert-error'><%= t('login.invalid_second_factor_code') %></div>
+          <% end %>
+          <%= submit_tag t('submit'), class: "btn btn-primary" %>
+        </div>
+        <% if @backup_codes_enabled %>
+          <%= link_to t("login.second_factor_toggle.backup_code"), show_backup: "true" %>
+        <% end %>
+      <% else %>
+        <%= submit_tag t('change_email.confirm'), class: "btn btn-primary" %>
+      <% end %>
+    <%end%>
+  <% end%>
+</div>
diff --git a/app/views/users_email/show_confirm_old_email.html.erb b/app/views/users_email/show_confirm_old_email.html.erb
new file mode 100644
index 00000000000..6d810931860
--- /dev/null
+++ b/app/views/users_email/show_confirm_old_email.html.erb
@@ -0,0 +1,27 @@
+<div id="simple-container">
+  <% if @almost_done %>
+    <h2><%= t 'change_email.authorizing_old.almost_done_title' %></h2>
+    <p>
+      <%= t 'change_email.authorizing_old.almost_done_description' %>
+    </p>
+  <% elsif @error %>
+    <div class='alert alert-error'>
+      <%= @error %>
+    </div>
+  <% else %>
+    <h2><%= t 'change_email.authorizing_old.title' %></h2>
+    <p>
+      <%= t 'change_email.authorizing_old.description' %>
+      <br>
+      <br>
+      <%= t 'change_email.authorizing_old.old_email', email: @from_email %>
+      <br>
+      <%= t 'change_email.authorizing_old.new_email', email: @to_email %>
+    </p>
+
+    <%=form_tag(u_confirm_old_email_path, method: :put) do %>
+      <%= hidden_field_tag 'token', @token.token %>
+      <%= submit_tag t('change_email.confirm'), class: "btn btn-primary" %>
+    <% end %>
+  <% end %>
+</div>
diff --git a/config/locales/server.ar.yml b/config/locales/server.ar.yml
index f2adf79e850..ac62eb1e1d0 100644
--- a/config/locales/server.ar.yml
+++ b/config/locales/server.ar.yml
@@ -1456,7 +1456,7 @@ ar:
       text_body_template: |
         أكد عنوان بريدك الإلكتروني لـ %{site_name} بالضغط على الرابط التالي :
 
-        %{email_token}/u/authorize-email/%{base_url}
+        %{email_token}/u/confirm-new-email/%{base_url}
     confirm_old_email:
       subject_template: "أكّد عنوان بريد الإلكتروني الحالي %{email_prefix}"
       text_body_template: |
@@ -1466,7 +1466,7 @@ ar:
 
         أكّد عنوان بريدك الإلكتروني الحالي لـ %{site_name} بالضغط على الرابط التالي :
 
-        %{email_token}/u/authorize-email/%{base_url}
+        %{email_token}/u/confirm-old-email/%{base_url}
     notify_old_email:
       subject_template: "عنوان بريد الإلكتروني تم تغييرة %{email_prefix}"
     signup_after_approval:
diff --git a/config/locales/server.ca.yml b/config/locales/server.ca.yml
index 449d71503c1..b33c23a523a 100644
--- a/config/locales/server.ca.yml
+++ b/config/locales/server.ca.yml
@@ -2745,7 +2745,7 @@ ca:
       text_body_template: |
         Confirmeu la vostra nova adreça de correu per a %{site_name} fent clic en l'enllaç següent:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Confirmeu l'adreça de correu antiga"
       subject_template: "[%{email_prefix}] Confirmeu la vostra adreça de correu actual"
@@ -2756,7 +2756,7 @@ ca:
 
          Confirmeu la vostra adreça actual per a %{site_name} fent clic en l'enllaç següent:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Notifica l'adreça de correu antiga"
       subject_template: "[%{email_prefix}] La vostra adreça de correu ha canviat"
diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml
index b08f8f19742..13f4b63a4a5 100644
--- a/config/locales/server.de.yml
+++ b/config/locales/server.de.yml
@@ -3019,7 +3019,7 @@ de:
       text_body_template: |
         Bestätige deine neue E-Mail-Adresse für %{site_name}, indem du dem diesem Link folgst:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "E-Mail-Adresse bestätigen (an alte)"
       subject_template: "[%{email_prefix}] Bestätige deine aktuelle E-Mail-Adresse"
@@ -3028,7 +3028,7 @@ de:
 
         Bestätige deine aktuelle E-Mail-Adresse für %{site_name}, indem du diesem Link folgst:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Benachrichtigung an alte E-Mail-Adresse"
       subject_template: "[%{email_prefix}] Deine E-Mail-Adresse wurde geändert"
diff --git a/config/locales/server.el.yml b/config/locales/server.el.yml
index 0e57b3621e2..7c18fa00693 100644
--- a/config/locales/server.el.yml
+++ b/config/locales/server.el.yml
@@ -2084,7 +2084,7 @@ el:
 
         Επικυρώστε την νέα σας διεύθυνση email στην %{site_name} κάνοντας κλικ στον παρακάτω σύνδεσμο:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Επιβεβαίωση παλιάς διεύθυνσης email"
       subject_template: "[%{email_prefix}] Επικυρώστε την νέα σας διεύθυνση email"
@@ -2098,7 +2098,7 @@ el:
 
         Επιβεβαιώστε την τρέχουσα διεύθυνση email στην%{site_name} κάνοντας κλικ στον παρακάτω σύνδεσμο:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Ειδοποίηση παλιάς διεύθυνσης email"
       subject_template: "[%{email_prefix}] Η διεύθυνση email σας έχει αλλαχθεί"
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index acfd572e8d0..c93fb0cb285 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -805,14 +805,25 @@ en:
       unknown: "unknown operating system"
 
   change_email:
+    wrong_account_error: "You are logged in the wrong account, please log out and try again."
     confirmed: "Your email has been updated."
     please_continue: "Continue to %{site_name}"
     error: "There was an error changing your email address. Perhaps the address is already in use?"
     error_staged: "There was an error changing your email address. The address is already in use by a staged user."
     already_done: "Sorry, this confirmation link is no longer valid. Perhaps your email was already changed?"
+    confirm: "Confirm"
+
+    authorizing_new:
+      title: "Confirm your new email"
+      description: "Please confirm you would like your new email address changed to:"
+
     authorizing_old:
-      title: "Thanks for confirming your current email address"
-      description: "We're now emailing your new address for confirmation."
+      title: "Change your email address"
+      description: "Please confirm your email address change"
+      old_email: "Old email: %{email}"
+      new_email: "New email: %{email}"
+      almost_done_title: "Confirming new email address"
+      almost_done_description: "We have sent an email to your new email address to confirm the change!"
 
   associated_accounts:
     revoke_failed: "Failed to revoke your account with %{provider_name}."
@@ -3545,7 +3556,7 @@ en:
       text_body_template: |
         Confirm your new email address for %{site_name} by clicking on the following link:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
 
     confirm_old_email:
       title: "Confirm Old Email"
@@ -3557,7 +3568,7 @@ en:
 
         Confirm your current email address for %{site_name} by clicking on the following link:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
 
     notify_old_email:
       title: "Notify Old Email"
diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml
index 2d8687676e0..7c2ed250332 100644
--- a/config/locales/server.es.yml
+++ b/config/locales/server.es.yml
@@ -3144,7 +3144,7 @@ es:
       text_body_template: |
         Confirma tu nueva dirección de correo electrónico para %{site_name} haciendo clic en el siguiente enlace:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Confirmar correo electrónico antiguo"
       subject_template: "[%{email_prefix}] Confirma tu dirección actual de correo electrónico"
@@ -3155,7 +3155,7 @@ es:
 
         Confirma tu correo electrónico actual para %{site_name} haciendo clic en el siguiente enlace:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     notify_old_email:
       title: "Antiguo correo electrónico de notificaciones"
       subject_template: "[%{email_prefix}] Tu dirección de correo electrónico ha sido cambiada"
diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml
index 4179077907c..354e22fed28 100644
--- a/config/locales/server.fa_IR.yml
+++ b/config/locales/server.fa_IR.yml
@@ -1896,7 +1896,7 @@ fa_IR:
       text_body_template: |
         ایمیل جدید خود را برای %{site_name} با کلیک روی لینک زیر تایید کنید:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "تایید ایمیل قبلی"
       subject_template: "[%{email_prefix}] ایمیل فعلی خود را تایید کنید"
@@ -1907,7 +1907,7 @@ fa_IR:
 
         ایمیل فعلی خود در سایت %{site_name} را با کلیکل روی لینک زیر تعیید کنید:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "اعلام ایمیل قبلی"
       subject_template: "[%{email_prefix}] ایمیل شما تغییر کرده است"
diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml
index 4b617760114..5d202e566d3 100644
--- a/config/locales/server.fi.yml
+++ b/config/locales/server.fi.yml
@@ -2879,7 +2879,7 @@ fi:
       text_body_template: |
         Vahvista uusi sähköpostiosoitteesi sivustolla %{site_name} klikkaamalla linkkiä:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Vahvista vanha sähköpostiosoite"
       subject_template: "[%{email_prefix}] Vahvista nykyinen sähköpostiosoitteesi"
@@ -2888,7 +2888,7 @@ fi:
 
         Vahvista nykyinen sähköpostiosoitteesi sivustolla %{site_name} klikkaamalla linkkiä:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Ilmoita vanhaan sähköpostiosoitteeseen"
       subject_template: "[%{email_prefix}] Sähköpostiosoitteesi on vaihdettu"
diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml
index aa6de0aa519..5d2e352f736 100644
--- a/config/locales/server.fr.yml
+++ b/config/locales/server.fr.yml
@@ -3009,7 +3009,7 @@ fr:
       text_body_template: |
         Confirmez votre nouvelle adresse email pour %{site_name} en cliquant sur le lien suivant :
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Confirmez votre ancienne adresse email"
       subject_template: "[%{email_prefix}] Confirmez votre adresse email actuelle"
@@ -3018,7 +3018,7 @@ fr:
 
         Confirmez votre adresse email actuelle pour %{site_name} en cliquant sur le lien suivant :
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Notifier l'ancienne adresse courriel"
       subject_template: "[%{email_prefix}] Votre adresse email a été modifié"
diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml
index 097f22db589..ac476139b73 100644
--- a/config/locales/server.he.yml
+++ b/config/locales/server.he.yml
@@ -3259,7 +3259,7 @@ he:
       text_body_template: |
         אשרו את כתובת המייל החדשה שלכם עבור %{site_name} על ידי לחיצה על הקישור הבא:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "אישור מייל ישן"
       subject_template: "[%{email_prefix}] אשרו את כתובת המייל הנוכחית שלכם"
@@ -3269,7 +3269,7 @@ he:
 
         אשרו את כתובת המייל הנוכחית עבור %{site_name} על ידי לחיצה על הקישור הבא:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "התראת דוא״ל ישן"
       subject_template: "[%{email_prefix}] כתובת הדוא״ל שלך הוחלפה"
diff --git a/config/locales/server.hy.yml b/config/locales/server.hy.yml
index 91f214c20fa..30db6aa4d01 100644
--- a/config/locales/server.hy.yml
+++ b/config/locales/server.hy.yml
@@ -2701,7 +2701,7 @@ hy:
       text_body_template: |
         Հաստատեք Ձեր նոր էլ. հասցեն %{site_name} -ի համար՝ սեղմելով հետևյալ հղումը.
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Հաստատել Հին Էլ. Հասցեն"
       subject_template: "[%{email_prefix}] Հաստատել Ձեր ընթացիկ էլ. հասցեն"
diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml
index 2c52e5446e3..faf3d8a1b36 100644
--- a/config/locales/server.it.yml
+++ b/config/locales/server.it.yml
@@ -2862,7 +2862,7 @@ it:
       text_body_template: |
         Conferma il tuo nuovo indirizzo email su %{site_name} cliccando il seguente collegamento:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Conferma Vecchia Email"
       subject_template: "[%{email_prefix}] Conferma il tuo attuale indirizzo email"
@@ -2873,7 +2873,7 @@ it:
 
         Conferma il tuo attuale indirizzo email su %{site_name} cliccando il seguente collegamento:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Notifica Vecchia Email"
       subject_template: "[%{email_prefix}] Il tuo indirizzo email è stato cambiato"
diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml
index 529d544a953..dc9ca9e287c 100644
--- a/config/locales/server.ja.yml
+++ b/config/locales/server.ja.yml
@@ -1300,7 +1300,7 @@ ja:
       text_body_template: |
         %{site_name}への新しいメールアドレスを下のリンクから確認してください。
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "古いメールの確認"
       subject_template: "[%{email_prefix}]現在のメールアドレスの確認"
diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml
index 75f2d442316..39c273adf25 100644
--- a/config/locales/server.pl_PL.yml
+++ b/config/locales/server.pl_PL.yml
@@ -2313,7 +2313,7 @@ pl_PL:
       text_body_template: |
         Potwierdź swój nowy adres email dla %{site_name} poprzez kliknięcia na następujący link:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Potwierdź stary email"
       subject_template: "[%{site_name}] Potwierdź aktualny adres email"
@@ -2322,7 +2322,7 @@ pl_PL:
 
         Potwierdź obecny adres email dla %{site_name}poprzez naciśnięcie na następujący link:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Powiadom Stary Email"
       subject_template: "[%{site_name}] Twój adres email został zmieniony"
diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml
index b2fe3bbc579..d2bfcc8549e 100644
--- a/config/locales/server.pt_BR.yml
+++ b/config/locales/server.pt_BR.yml
@@ -2925,11 +2925,11 @@ pt_BR:
       text_body_template: |
         Confirme seu novo endereço de e-mail para %{site_name} clicando no seguinte link:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Confirmar Antigo e-mail"
       subject_template: "[%{email_prefix}] Confirme seu endereço de e-mail atual"
-      text_body_template: "Antes que possamos alterar seu endereço de e-mail, precisamos que você confirme que você controla a conta de e-mail atual. \nDepois de concluir esta etapa, você terá que confirmar\no novo endereço de e-mail.\n\nConfirme seu endereço de e-mail atual para %{site_name} clicando no seguinte link:\n\n%{base_url}/u/authorize-email/%{email_token}\n"
+      text_body_template: "Antes que possamos alterar seu endereço de e-mail, precisamos que você confirme que você controla a conta de e-mail atual. \nDepois de concluir esta etapa, você terá que confirmar\no novo endereço de e-mail.\n\nConfirme seu endereço de e-mail atual para %{site_name} clicando no seguinte link:\n\n%{base_url}/u/confirm-old-email/%{email_token}\n"
     notify_old_email:
       title: "Notificar e-mail antigo"
       subject_template: "[%{email_prefix}] Seu endereço de e-mail foi alterado"
diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml
index d4ee59168d3..ac71a206914 100644
--- a/config/locales/server.ru.yml
+++ b/config/locales/server.ru.yml
@@ -2217,7 +2217,7 @@ ru:
       text_body_template: |
         Подтвердите ваш новый адрес e-mail почты для %{site_name} нажав на следующую ссылку:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       text_body_template: |
         Прежде чем мы сможем изменить ваш адрес электронной почты, нам нужно, чтобы вы подтвердили, что вы контролируете
@@ -2226,7 +2226,7 @@ ru:
 
         Подтвердите свой текущий адрес e-mail почты для %{site_name} нажав на следующую ссылку:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     signup_after_approval:
       title: "Регистрация После Утверждения"
       subject_template: "Ваша учетная запись на сайте %{site_name} одобрена!"
diff --git a/config/locales/server.sl.yml b/config/locales/server.sl.yml
index 6a5711a1419..fe4a8618d21 100644
--- a/config/locales/server.sl.yml
+++ b/config/locales/server.sl.yml
@@ -1659,7 +1659,7 @@ sl:
       text_body_template: |
         Potrdite vaš nov e-naslov pri %{site_name} tako da sledite povezavi:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Potrdite star e-naslov"
       subject_template: "[%{email_prefix}] Potrdite vaš trenutni e-naslov"
@@ -1668,7 +1668,7 @@ sl:
 
         Potrdite vaš trenutni e-naslov pri %{site_name} tako da sledite povezavi:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "Obvesti stari e-naslov"
       subject_template: "[%{email_prefix}] Vaš e-naslov je bil spremenjen"
diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml
index 6130e9b8ad5..f93a1297a0d 100644
--- a/config/locales/server.sq.yml
+++ b/config/locales/server.sq.yml
@@ -1163,7 +1163,7 @@ sq:
       text_body_template: |
         Konfirmoni adresën tuaj të re të emailit për "%{site_name}" duke klikuar linkun më poshtë:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       subject_template: "[%{email_prefix}] Konfirmoni adresën e tanishme të emailit "
     notify_old_email:
diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml
index 756ae8b7293..12c4680b488 100644
--- a/config/locales/server.uk.yml
+++ b/config/locales/server.uk.yml
@@ -2434,7 +2434,7 @@ uk:
       text_body_template: |
         Підтвердіть свою нову електронну адресу для %{site_name} натиснувши наступне посилання:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "Підтвердіть стару електронну пошту"
       subject_template: "[%{email_prefix}] Підтвердіть свою поточну адресу електроної пошти"
diff --git a/config/locales/server.ur.yml b/config/locales/server.ur.yml
index 42da5aa0238..9036cb9ed66 100644
--- a/config/locales/server.ur.yml
+++ b/config/locales/server.ur.yml
@@ -3033,7 +3033,7 @@ ur:
       text_body_template: |
         %{site_name} پر اپنے نئے ای میل ایڈریس کی تصدیق کرنے کیلئے مندرجہ ذیل لِنک پر کلِک کریں:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "پرانی ای میل تصدیق"
       subject_template: "[%{email_prefix}] اپنا موجودہ ای میل ایڈریس تصدیق کریں"
@@ -3044,7 +3044,7 @@ ur:
 
         %{site_name} پر اپنے موجودہ ای میل ایڈریس کی تصدیق کرنے کیلئے مندرجہ ذیل لِنک پر کلک کریں:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "پرانا ای میل مطلع"
       subject_template: "[%{email_prefix}] آپ کا ای میل ایڈریس تبدیل ہوگیا ہے"
diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml
index e7d2150d2a9..52c35fff8f7 100644
--- a/config/locales/server.zh_CN.yml
+++ b/config/locales/server.zh_CN.yml
@@ -3013,7 +3013,7 @@ zh_CN:
       text_body_template: |
         点击下面的链接来确认你在%{site_name}上的新电子邮箱地址:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "确认旧邮箱"
       subject_template: "[%{email_prefix}] 确认你现在的电子邮箱地址"
@@ -3022,7 +3022,7 @@ zh_CN:
 
         点击下面的链接来确认你在%{site_name}正使用的邮件:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "通知旧邮箱"
       subject_template: "[%{email_prefix}] 你的邮箱已经修改成功"
diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml
index e530144e023..27cada2b1c0 100644
--- a/config/locales/server.zh_TW.yml
+++ b/config/locales/server.zh_TW.yml
@@ -2810,7 +2810,7 @@ zh_TW:
       text_body_template: |
         點擊以下連結,確認你 %{site_name} 的新郵件地址:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-new-email/%{email_token}
     confirm_old_email:
       title: "確認原郵件地址"
       subject_template: "[%{email_prefix}] 確認你的現行郵件地址"
@@ -2820,7 +2820,7 @@ zh_TW:
 
         點擊下面的連結,以確認你當前在 %{site_name} 的郵件地址:
 
-        %{base_url}/u/authorize-email/%{email_token}
+        %{base_url}/u/confirm-old-email/%{email_token}
     notify_old_email:
       title: "通知原郵件地址"
       subject_template: "[%{email_prefix}] 已變更你的郵件地址"
diff --git a/config/routes.rb b/config/routes.rb
index eb1bab02127..7fd6e9cef81 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -408,8 +408,13 @@ Discourse::Application.routes.draw do
     put "#{root_path}/password-reset/:token" => "users#password_reset"
     get "#{root_path}/activate-account/:token" => "users#activate_account"
     put({ "#{root_path}/activate-account/:token" => "users#perform_account_activation" }.merge(index == 1 ? { as: 'perform_activate_account' } : {}))
-    get "#{root_path}/authorize-email/:token" => "users_email#confirm"
-    put "#{root_path}/authorize-email/:token" => "users_email#confirm"
+
+    get "#{root_path}/confirm-old-email/:token" => "users_email#show_confirm_old_email"
+    put "#{root_path}/confirm-old-email" => "users_email#confirm_old_email"
+
+    get "#{root_path}/confirm-new-email/:token" => "users_email#show_confirm_new_email"
+    put "#{root_path}/confirm-new-email" => "users_email#confirm_new_email"
+
     get({
       "#{root_path}/confirm-admin/:token" => "users#confirm_admin",
       constraints: { token: /[0-9a-f]+/ }
diff --git a/spec/requests/users_email_controller_spec.rb b/spec/requests/users_email_controller_spec.rb
index d2512e08d5c..55bd65c62f5 100644
--- a/spec/requests/users_email_controller_spec.rb
+++ b/spec/requests/users_email_controller_spec.rb
@@ -4,72 +4,65 @@ require 'rails_helper'
 
 describe UsersEmailController do
 
-  describe '#confirm' do
+  fab!(:user) { Fabricate(:user) }
+  fab!(:moderator) { Fabricate(:moderator) }
+
+  describe "#confirm-new-email" do
+    it 'redirects to login for signed out accounts' do
+      get "/u/confirm-new-email/asdfasdf"
+
+      expect(response.status).to eq(302)
+      expect(response.redirect_url).to eq("http://test.localhost/login")
+    end
+
     it 'errors out for invalid tokens' do
-      get "/u/authorize-email/asdfasdf"
+      sign_in(user)
+
+      get "/u/confirm-new-email/asdfasdf"
 
       expect(response.status).to eq(200)
       expect(response.body).to include(I18n.t('change_email.already_done'))
     end
 
-    context 'valid old address token' do
-      fab!(:user) { Fabricate(:moderator) }
-      let(:updater) { EmailUpdater.new(user.guardian, user) }
+    it 'does not change email if accounts mismatch' do
+      updater = EmailUpdater.new(user.guardian, user)
+      updater.change_to('new.n.cool@example.com')
 
-      before do
-        updater.change_to('new.n.cool@example.com')
-      end
+      old_email = user.email
 
-      it 'confirms with a correct token' do
-        get "/u/authorize-email/#{user.email_tokens.last.token}"
+      sign_in(moderator)
 
-        expect(response.status).to eq(200)
+      put "/u/confirm-new-email", params: {
+        token: "#{user.email_tokens.last.token}"
+      }
 
-        body = CGI.unescapeHTML(response.body)
-
-        expect(body)
-          .to include(I18n.t('change_email.authorizing_old.title'))
-
-        expect(body)
-          .to include(I18n.t('change_email.authorizing_old.description'))
-      end
+      user.reload
+      expect(user.email).to eq(old_email)
     end
 
-    context 'valid new address token' do
-      fab!(:user) { Fabricate(:user) }
+    context "with a valid user" do
       let(:updater) { EmailUpdater.new(user.guardian, user) }
 
       before do
+        sign_in(user)
         updater.change_to('new.n.cool@example.com')
       end
 
       it 'confirms with a correct token' do
         user.user_stat.update_columns(bounce_score: 42, reset_bounce_score_after: 1.week.from_now)
 
-        events = DiscourseEvent.track_events do
-          get "/u/authorize-email/#{user.email_tokens.last.token}"
-        end
+        put "/u/confirm-new-email", params: {
+          token: "#{user.email_tokens.last.token}"
+        }
 
-        expect(events.map { |event| event[:event_name] }).to include(
-          :user_logged_in, :user_first_logged_in
-        )
-
-        expect(response.status).to eq(200)
-        expect(response.body).to include(I18n.t('change_email.confirmed'))
+        expect(response.status).to eq(302)
+        expect(response.redirect_url).to include("done")
 
         user.reload
 
         expect(user.user_stat.bounce_score).to eq(0)
         expect(user.user_stat.reset_bounce_score_after).to eq(nil)
-      end
-
-      it 'automatically adds the user to a group when the email matches' do
-        group = Fabricate(:group, automatic_membership_email_domains: "example.com")
-
-        get "/u/authorize-email/#{user.email_tokens.last.token}"
-
-        expect(response.status).to eq(200)
-        expect(group.reload.users.include?(user)).to eq(true)
+        expect(user.email).to eq("new.n.cool@example.com")
       end
 
       context 'second factor required' do
@@ -77,7 +70,7 @@ describe UsersEmailController do
         fab!(:backup_code) { Fabricate(:user_second_factor_backup, user: user) }
 
         it 'requires a second factor token' do
-          get "/u/authorize-email/#{user.email_tokens.last.token}"
+          get "/u/confirm-new-email/#{user.email_tokens.last.token}"
 
           expect(response.status).to eq(200)
 
@@ -88,7 +81,7 @@ describe UsersEmailController do
         end
 
         it 'requires a backup token' do
-          get "/u/authorize-email/#{user.email_tokens.last.token}?show_backup=true"
+          get "/u/confirm-new-email/#{user.email_tokens.last.token}?show_backup=true"
 
           expect(response.status).to eq(200)
 
@@ -98,34 +91,94 @@ describe UsersEmailController do
         end
 
         it 'adds an error on a second factor attempt' do
-          get "/u/authorize-email/#{user.email_tokens.last.token}", params: {
+          put "/u/confirm-new-email", params: {
+            token: user.email_tokens.last.token,
             second_factor_token: "000000",
             second_factor_method: UserSecondFactor.methods[:totp]
           }
 
-          expect(response.status).to eq(200)
-          expect(response.body).to include(I18n.t("login.invalid_second_factor_code"))
+          expect(response.status).to eq(302)
+          expect(flash[:invalid_second_factor]).to eq(true)
         end
 
         it 'confirms with a correct second token' do
-          get "/u/authorize-email/#{user.email_tokens.last.token}", params: {
+          put "/u/confirm-new-email", params: {
             second_factor_token: ROTP::TOTP.new(second_factor.data).now,
-            second_factor_method: UserSecondFactor.methods[:totp]
+            second_factor_method: UserSecondFactor.methods[:totp],
+            token: user.email_tokens.last.token
           }
 
-          expect(response.status).to eq(200)
+          expect(response.status).to eq(302)
 
-          response_body = response.body
-
-          expect(response_body).not_to include(I18n.t("login.second_factor_title"))
-          expect(response_body).not_to include(I18n.t("login.invalid_second_factor_code"))
+          user.reload
+          expect(user.email).to eq("new.n.cool@example.com")
         end
       end
     end
   end
 
+  describe '#confirm-old-email' do
+
+    it 'redirects to login for signed out accounts' do
+      get "/u/confirm-old-email/asdfasdf"
+
+      expect(response.status).to eq(302)
+      expect(response.redirect_url).to eq("http://test.localhost/login")
+    end
+
+    it 'errors out for invalid tokens' do
+      sign_in(user)
+
+      get "/u/confirm-old-email/asdfasdf"
+
+      expect(response.status).to eq(200)
+      expect(response.body).to include(I18n.t('change_email.already_done'))
+    end
+
+    it 'bans change when accounts do not match' do
+
+      sign_in(user)
+      updater = EmailUpdater.new(moderator.guardian, moderator)
+      updater.change_to('new.n.cool@example.com')
+
+      get "/u/confirm-old-email/#{moderator.email_tokens.last.token}"
+
+      expect(response.status).to eq(200)
+      expect(body).to include("alert-error")
+    end
+
+    context 'valid old address token' do
+
+      it 'confirms with a correct token' do
+        # NOTE: only moderators need to confirm both old and new
+        sign_in(moderator)
+        updater = EmailUpdater.new(moderator.guardian, moderator)
+        updater.change_to('new.n.cool@example.com')
+
+        get "/u/confirm-old-email/#{moderator.email_tokens.last.token}"
+
+        expect(response.status).to eq(200)
+
+        body = CGI.unescapeHTML(response.body)
+
+        expect(body)
+          .to include(I18n.t('change_email.authorizing_old.title'))
+
+        expect(body)
+          .to include(I18n.t('change_email.authorizing_old.description'))
+
+        put "/u/confirm-old-email", params: {
+          token: moderator.email_tokens.last.token
+        }
+
+        expect(response.status).to eq(302)
+        expect(response.redirect_url).to include("done=true")
+
+      end
+    end
+  end
+
   describe '#update' do
-    fab!(:user) { Fabricate(:user) }
     let(:new_email) { 'bubblegum@adventuretime.ooo' }
 
     it "requires you to be logged in" do