Fix confusing screen when visiting a confirmation link for an already-confirmed email (#27368)

This commit is contained in:
Claire 2023-10-25 23:33:44 +02:00 committed by GitHub
parent 9a3d047f3e
commit 49b8433c56
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 9 deletions

View file

@ -39,6 +39,12 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
show
end
def redirect_to_app?
truthy_param?(:redirect_to_app)
end
helper_method :redirect_to_app?
private
def require_captcha_if_needed!
@ -82,7 +88,7 @@ class Auth::ConfirmationsController < Devise::ConfirmationsController
end
def after_confirmation_path_for(_resource_name, user)
if user.created_by_application && truthy_param?(:redirect_to_app)
if user.created_by_application && redirect_to_app?
user.created_by_application.confirmation_redirect_uri
elsif user_signed_in?
web_url('start')

View file

@ -1,13 +1,29 @@
- content_for :page_title do
= t('auth.resend_confirmation')
= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= render 'shared/error_messages', object: resource
- if resource.errors.of_kind?(:email, :already_confirmed)
.simple_form
= render 'auth/shared/progress', stage: resource.approved? ? 'completed' : 'confirmed'
.fields-group
= f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint')
- if resource.approved?
%h1.title= t('auth.confirmations.welcome_title', name: resource.account.username)
%p.lead= t('auth.confirmations.registration_complete', domain: site_hostname)
- if resource.created_by_application && redirect_to_app?
- app = resource.created_by_application
%p.lead= t('auth.confirmations.redirect_to_app_html', app_name: app.name, clicking_this_link: link_to(t('auth.confirmations.clicking_this_link'), app.confirmation_redirect_uri))
- else
%p.lead= t('auth.confirmations.proceed_to_login_html', login_link: link_to_login(t('auth.confirmations.login_link')))
- else
%h1.title= t('auth.confirmations.awaiting_review_title')
%p.lead= t('auth.confirmations.awaiting_review', domain: site_hostname)
- else
= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f|
= render 'shared/error_messages', object: resource
.actions
= f.button :button, t('auth.resend_confirmation'), type: :submit
.fields-group
= f.input :email, autofocus: true, wrapper: :with_label, label: t('simple_form.labels.defaults.email'), input_html: { 'aria-label': t('simple_form.labels.defaults.email') }, readonly: current_user.present?, hint: current_user.present? && t('auth.confirmations.wrong_email_hint')
.actions
= f.button :button, t('auth.resend_confirmation'), type: :submit
.form-footer= render 'auth/shared/links'

View file

@ -1,4 +1,4 @@
- progress_index = { rules: 0, details: 1, confirm: 2 }[stage.to_sym]
- progress_index = { rules: 0, details: 1, confirm: 2, confirmed: 3, completed: 4 }[stage.to_sym]
%ol.progress-tracker
%li{ class: progress_index.positive? ? 'completed' : 'active' }
@ -20,6 +20,8 @@
.label= t('auth.progress.confirm')
- if approved_registrations?
%li.separator{ class: progress_index > 2 ? 'completed' : nil }
%li
%li{ class: [progress_index > 3 && 'completed', progress_index == 3 && 'active'] }
.circle
- if progress_index > 3
= check_icon
.label= t('auth.progress.review')

View file

@ -1041,6 +1041,14 @@ en:
hint_html: Just one more thing! We need to confirm you're a human (this is so we can keep the spam out!). Solve the CAPTCHA below and click "Continue".
title: Security check
confirmations:
awaiting_review: Your e-mail address is confirmed! The %{domain} staff is now reviewing your registration. You will receive an e-mail if they approve your account!
awaiting_review_title: Your registration is being reviewed
clicking_this_link: clicking this link
login_link: log in
proceed_to_login_html: You can now proceed to %{login_link}.
redirect_to_app_html: You should have been redirected to the <strong>%{app_name}</strong> app. If that did not happen, try %{clicking_this_link} or manually return to the app.
registration_complete: Your registration on %{domain} is now complete!
welcome_title: Welcome, %{name}!
wrong_email_hint: If that e-mail address is not correct, you can change it in account settings.
delete_account: Delete account
delete_account_html: If you wish to delete your account, you can <a href="%{path}">proceed here</a>. You will be asked for confirmation.

View file

@ -30,6 +30,14 @@ describe 'email confirmation flow when captcha is enabled' do
click_button I18n.t('challenge.confirm')
expect(user.reload.confirmed?).to be true
expect(page).to have_current_path(/\A#{client_app.confirmation_redirect_uri}/, url: true)
# Browsers will generally reload the original page upon redirection
# to external handlers, so test this as well
visit "/auth/confirmation?confirmation_token=#{user.confirmation_token}&redirect_to_app=true"
# It presents a page with a link to the app callback
expect(page).to have_content(I18n.t('auth.confirmations.registration_complete', domain: 'cb6e6126.ngrok.io'))
expect(page).to have_link(I18n.t('auth.confirmations.clicking_this_link'), href: client_app.confirmation_redirect_uri)
end
end
end