mailers: add procedure context to the confirmation link
This allows to redirect the user to the procedure they signed up for even when the browser session is not available (like if they changed of browser). Fix #4738
This commit is contained in:
parent
10c940c188
commit
6664965961
8 changed files with 50 additions and 5 deletions
|
@ -42,9 +42,19 @@ class Users::ConfirmationsController < Devise::ConfirmationsController
|
|||
if sign_in_after_confirmation?(resource)
|
||||
resource.remember_me = true
|
||||
sign_in(resource)
|
||||
end
|
||||
|
||||
if procedure_from_params
|
||||
commencer_path(path: procedure_from_params.path)
|
||||
elsif signed_in?
|
||||
# Will try to use `stored_location_for` to find a path
|
||||
after_sign_in_path_for(resource_name)
|
||||
else
|
||||
super(resource_name, resource)
|
||||
end
|
||||
end
|
||||
|
||||
def procedure_from_params
|
||||
params[:procedure_id] && Procedure.find_by(id: params[:procedure_id])
|
||||
end
|
||||
end
|
||||
|
|
|
@ -21,6 +21,12 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
|
||||
# POST /resource
|
||||
def create
|
||||
# We may need the confirmation mailer to access the current procedure.
|
||||
# But there's no easy way to pass an argument to the mailer through
|
||||
# all Devise code.
|
||||
# So instead we use a per-request global variable.
|
||||
CurrentConfirmation.procedure_after_confirmation = @procedure
|
||||
|
||||
# Handle existing user trying to sign up again
|
||||
existing_user = User.find_by(email: params[:user][:email])
|
||||
if existing_user.present?
|
||||
|
|
|
@ -15,6 +15,7 @@ class DeviseUserMailer < Devise::Mailer
|
|||
|
||||
def confirmation_instructions(record, token, opts = {})
|
||||
opts[:from] = NO_REPLY_EMAIL
|
||||
@procedure = CurrentConfirmation.procedure_after_confirmation || nil
|
||||
super
|
||||
end
|
||||
end
|
||||
|
|
3
app/models/current_confirmation.rb
Normal file
3
app/models/current_confirmation.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
class CurrentConfirmation < ActiveSupport::CurrentAttributes
|
||||
attribute :procedure_after_confirmation
|
||||
end
|
|
@ -7,7 +7,8 @@
|
|||
|
||||
%p
|
||||
Pour activer votre compte sur demarches-simplifiees.fr, veuillez cliquer sur le lien suivant :
|
||||
= link_to(confirmation_url(@user, confirmation_token: @token), confirmation_url(@user, confirmation_token: @token))
|
||||
- link = confirmation_url(@user, confirmation_token: @token, procedure_id: @procedure&.id)
|
||||
= link_to(link, link)
|
||||
|
||||
- else
|
||||
- content_for(:title, "Changement d'adresse email")
|
||||
|
|
|
@ -77,8 +77,10 @@ feature 'Signing up:' do
|
|||
sign_up_with user_email, user_password
|
||||
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
|
||||
|
||||
click_confirmation_link_for user_email
|
||||
click_confirmation_link_for(user_email, in_another_browser: true)
|
||||
|
||||
# After confirmation, the user is redirected to the procedure they were initially starting
|
||||
# (even when confirming the account in another browser).
|
||||
expect(page).to have_current_path(commencer_path(path: procedure.path))
|
||||
expect(page).to have_content 'Votre compte a été activé'
|
||||
click_on 'Commencer la démarche'
|
||||
|
@ -106,6 +108,14 @@ feature 'Signing up:' do
|
|||
# The confirmation email is sent again
|
||||
confirmation_email = open_email(user_email)
|
||||
expect(confirmation_email.body).to have_text('Pour activer votre compte')
|
||||
|
||||
click_confirmation_link_for(user_email, in_another_browser: true)
|
||||
|
||||
# After confirmation, the user is redirected to the procedure they were initially starting
|
||||
# (even when confirming the account in another browser).
|
||||
expect(page).to have_current_path(commencer_path(path: procedure.path))
|
||||
expect(page).to have_content 'Votre compte a été activé'
|
||||
expect(page).to have_content 'Commencer la démarche'
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -3,6 +3,11 @@ class DeviseUserMailerPreview < ActionMailer::Preview
|
|||
DeviseUserMailer.confirmation_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
||||
def confirmation_instructions___with_procedure
|
||||
CurrentConfirmation.procedure_after_confirmation = procedure
|
||||
DeviseUserMailer.confirmation_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
||||
def reset_password_instructions
|
||||
DeviseUserMailer.reset_password_instructions(user, "faketoken", {})
|
||||
end
|
||||
|
@ -12,4 +17,8 @@ class DeviseUserMailerPreview < ActionMailer::Preview
|
|||
def user
|
||||
User.new(id: 10, email: "usager@example.com")
|
||||
end
|
||||
|
||||
def procedure
|
||||
Procedure.new(id: 20, libelle: 'Dotation d’Équipement des Territoires Ruraux - Exercice 2019', path: 'dotation-etr')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -48,11 +48,16 @@ module FeatureHelpers
|
|||
end
|
||||
end
|
||||
|
||||
def click_confirmation_link_for(email)
|
||||
def click_confirmation_link_for(email, in_another_browser: false)
|
||||
confirmation_email = open_email(email)
|
||||
token_params = confirmation_email.body.match(/confirmation_token=[^"]+/)
|
||||
confirmation_link = confirmation_email.body.match(/href="[^"]*(\/users\/confirmation[^"]*)"/)[1]
|
||||
|
||||
visit "/users/confirmation?#{token_params}"
|
||||
if in_another_browser
|
||||
# Simulate the user opening the link in another browser, thus loosing the session cookie
|
||||
Capybara.reset_session!
|
||||
end
|
||||
|
||||
visit confirmation_link
|
||||
end
|
||||
|
||||
def click_procedure_sign_in_link_for(email)
|
||||
|
|
Loading…
Reference in a new issue