Merge pull request #4778 from betagouv/redirect-to-procedure-after-confirmation

Usager : redirige vers la démarche après l'email de confirmation, même lorsque le navigateur web est différent
This commit is contained in:
Pierre de La Morinerie 2020-02-25 12:51:51 +01:00 committed by GitHub
commit 9ad56d8e9b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 58 additions and 16 deletions

View file

@ -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

View file

@ -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?

View file

@ -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

View file

@ -0,0 +1,3 @@
class CurrentConfirmation < ActiveSupport::CurrentAttributes
attribute :procedure_after_confirmation
end

View file

@ -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")

View file

@ -5,16 +5,15 @@ feature 'Signing up:' do
let(:user_password) { 'démarches-simplifiées-pwd' }
let(:procedure) { create :simple_procedure, :with_service }
scenario 'a new user can sign-up' do
visit commencer_path(path: procedure.path)
click_on 'Créer un compte demarches-simplifiees.fr'
scenario 'a new user can sign-up from scratch' do
visit new_user_registration_path
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
expect(page).to have_content 'Votre compte a été activé'
expect(page).to have_current_path commencer_path(path: procedure.path)
expect(page).to have_current_path dossiers_path
end
context 'when the user makes a typo in their email address' do
@ -68,11 +67,9 @@ feature 'Signing up:' do
context 'when visiting a procedure' do
let(:procedure) { create :simple_procedure, :with_service }
before do
visit commencer_path(path: procedure.path)
end
scenario 'a new user can sign-up and fill the procedure' do
visit commencer_path(path: procedure.path)
click_on 'Créer un compte'
expect(page).to have_current_path new_user_registration_path
expect(page).to have_procedure_description(procedure)
@ -80,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'
@ -103,12 +102,20 @@ feature 'Signing up:' do
sign_up_with user_email, user_password
# The same page than for initial sign-ups is displayed, to avoid leaking informations
# about the accound existence.
# about the account existence.
expect(page).to have_content "nous avons besoin de vérifier votre adresse #{user_email}"
# 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
@ -131,8 +138,8 @@ feature 'Signing up:' do
warning_email = open_email(user_email)
expect(warning_email.body).to have_text('Votre compte existe déjà')
# When clicking the main button, the user has a link to directly sign-in
# for the procedure they were initially starting
# When clicking the main button, the user is redirected directly to
# the sign-in page for the procedure they were initially starting.
click_procedure_sign_in_link_for user_email
expect(page).to have_current_path new_user_session_path

View file

@ -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

View file

@ -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)