Merge pull request #6122 from betagouv/add-reset-link-page

Improve password reset : confirmation page and button in email
This commit is contained in:
LeSim 2021-04-22 14:33:00 +02:00 committed by GitHub
commit a640ec1d43
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 122 additions and 34 deletions

View file

@ -4,3 +4,9 @@
font-family: "Muli", system-ui, -apple-system, sans-serif; font-family: "Muli", system-ui, -apple-system, sans-serif;
color: $black; color: $black;
} }
ol {
line-height: 28px;
list-style-type: decimal;
list-style-position: inside;
}

View file

@ -5,26 +5,38 @@
padding-top: 2 * $default-padding; padding-top: 2 * $default-padding;
padding-bottom: 2 * $default-padding; padding-bottom: 2 * $default-padding;
text-align: center; text-align: center;
max-width: 600px; max-width: 700px;
b { section {
text-align: left;
margin: 3 * $default-padding auto;
}
p,
ol {
margin-top: $default-padding;
margin-bottom: $default-padding;
}
.link-sent-info {
color: #000000;
background-color: $yellow;
padding: 0 $default-padding;
border: 1px solid transparent; // prevent margin collapse of first paragraph
}
.link-sent-help {
border-top: 1px solid $grey;
padding-top: $default-padding;
margin-bottom: $default-padding;
}
.link-sent-help-title {
font-weight: bold; font-weight: bold;
} }
p { .link-sent-help-list {
text-align: left; list-style-position: outside;
margin: 6 * $default-spacer auto; padding-left: $default-padding;
}
p.mail {
color: #000000;
background-color: $yellow;
padding: $default-padding;
}
p.help {
border-top: 1px solid $grey;
padding-top: 6 * $default-spacer;
margin-bottom: 2 * $default-spacer;
} }
} }

View file

@ -33,6 +33,10 @@ class Users::PasswordsController < Devise::PasswordsController
# super # super
# end # end
def reset_link_sent
@email = params[:email]
end
# protected # protected
# def after_resetting_password_path_for(resource) # def after_resetting_password_path_for(resource)
@ -74,4 +78,9 @@ class Users::PasswordsController < Devise::PasswordsController
def password_params def password_params
params.require(:user).permit(:reset_password_token, :password) params.require(:user).permit(:reset_password_token, :password)
end end
def after_sending_reset_password_instructions_path_for(resource_name)
flash.discard(:notice)
users_password_reset_link_sent_path(email: resource.email)
end
end end

View file

@ -1,6 +1,7 @@
# Preview all emails at http://localhost:3000/rails/mailers/devise_user_mailer # Preview all emails at http://localhost:3000/rails/mailers/devise_user_mailer
class DeviseUserMailer < Devise::Mailer class DeviseUserMailer < Devise::Mailer
helper :application # gives access to all helpers defined within `application_helper`. helper :application # gives access to all helpers defined within `application_helper`.
helper MailerHelper
include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url` include Devise::Controllers::UrlHelpers # Optional. eg. `confirmation_url`
layout 'mailers/layout' layout 'mailers/layout'

View file

@ -2,9 +2,9 @@
Bonjour, Bonjour,
%p %p
Vous avez demandé à regénérer votre mot de passe sur #{APPLICATION_BASE_URL}. Pour ceci, merci de suivre le lien suivant : Vous avez demandé à changer votre mot de passe sur #{APPLICATION_NAME}. Pour ceci, merci de cliquer sur le lien suivant :
%br
= link_to edit_password_url(@resource, reset_password_token: @token), edit_password_url(@resource, reset_password_token: @token) = round_button 'Changer mon mot de passe', edit_password_url(@resource, reset_password_token: @token), :primary
%p %p
Si vous n'avez pas effectué une telle demande, merci d'ignorer cet email. Votre mot de passe ne sera pas changé. Si vous n'avez pas effectué une telle demande, merci d'ignorer cet email. Votre mot de passe ne sera pas changé.

View file

@ -0,0 +1,32 @@
- content_for(:title, t('views.users.passwords.reset_link_sent.title'))
- content_for :footer do
= render partial: 'root/footer'
#link-sent.container
= image_tag('user/confirmation-email.svg')
%h1
= t('views.users.passwords.reset_link_sent.got_it')
%br
= t('views.users.passwords.reset_link_sent.open_your_mailbox')
%section.link-sent-info
%p
= t('views.users.passwords.reset_link_sent.email_sent_html', email: @email)
%p
= t('views.users.passwords.reset_link_sent.click_link_to_reset_password')
%p
= t('views.users.shared.email_can_take_a_while_html')
%section.link-sent-help
%h2.link-sent-help-title= t('views.users.passwords.reset_link_sent.no_mail')
%ol.link-sent-help-list
%li
= t('views.users.passwords.reset_link_sent.check_spams')
%li
= t('views.users.passwords.reset_link_sent.check_account', email: @email, application_name: APPLICATION_NAME)
- if FranceConnectService.enabled?
%li
= t('views.users.passwords.reset_link_sent.check_france_connect_html', href: france_connect_particulier_path)
%p
= t('views.users.shared.contact_us_if_any_trouble_html', href: contact_url)

View file

@ -7,16 +7,14 @@
= image_tag('user/confirmation-email.svg') = image_tag('user/confirmation-email.svg')
%h1 Encore une petite étape :) %h1 Encore une petite étape :)
%p.mail %section.link-sent-info
Ouvrez votre boite email <b>#{@email}</b> puis cliquez sur le lien d'activation du message <b>Connexion sécurisée à #{APPLICATION_NAME}</b>. %p
%br Ouvrez votre boite email <strong>#{@email}</strong> puis cliquez sur le lien dactivation du message <strong>Connexion sécurisée à #{APPLICATION_NAME}</strong>.
%br %p
<b>Attention</b>, ce message peut mettre jusqu'à <b>15 minutes</b> pour arriver. = t('views.users.shared.email_can_take_a_while')
%p.help %section.link-sent-help
Si vous voyez cette page trop souvent, consultez notre aide : #{link_to FAQ_CONFIRMER_COMPTE_CHAQUE_CONNEXION_URL, FAQ_CONFIRMER_COMPTE_CHAQUE_CONNEXION_URL, target: '_blank', rel: 'noopener' } %p
%br Si vous voyez cette page trop souvent, consultez notre aide : #{link_to FAQ_CONFIRMER_COMPTE_CHAQUE_CONNEXION_URL, FAQ_CONFIRMER_COMPTE_CHAQUE_CONNEXION_URL, target: '_blank', rel: 'noopener' }
%br %p
En cas de difficultés, nous restons joignables = t('views.users.shared.contact_us_if_any_trouble_html', href: contact_admin_url)
= succeed '.' do
= link_to("via ce formulaire", contact_admin_url)

View file

@ -53,6 +53,21 @@ fr:
passwords: passwords:
new: new:
send_me_reset_password_instructions: "Indiquez lemail de votre compte, et nous vous enverrons un lien pour créer un nouveau mot de passe." send_me_reset_password_instructions: "Indiquez lemail de votre compte, et nous vous enverrons un lien pour créer un nouveau mot de passe."
users:
passwords:
reset_link_sent:
email_sent_html: "Nous vous avons envoyé un email à ladresse <strong>%{email}</strong>."
click_link_to_reset_password: "Cliquez sur le lien contenu dans lemail pour changer votre mot de passe."
no_mail: "Vous navez pas reçu lemail ?"
check_spams: "Vérifiez la boite Indésirables ou Spam de votre boite email."
check_account: "Avez-vous bien créé un compte %{application_name} avec ladresse %{email} ? Si aucun compte nexiste avec cette adresse, vous ne recevrez pas de message."
check_france_connect_html: "Vous êtes-vous connecté avec France Connect par le passé ? Dans ce cas <a href=\"%{href}\">essayez à nouveau avec France Connect</a>."
got_it: "Bien reçu !"
open_your_mailbox: "Maintenant ouvrez votre boite email."
title: "Lien de réinitialisation du mot de passe envoyé"
shared:
email_can_take_a_while_html: "<strong>Attention</strong>, ce message peut mettre jusquà <strong>15 minutes</strong> pour arriver."
contact_us_if_any_trouble_html: "En cas de difficultés, nous restons joignables <a href=\"%{href}\">via ce formulaire</a>."
modal: modal:
publish: publish:
title: title:

View file

@ -106,6 +106,7 @@ Rails.application.routes.draw do
get '/users/no_procedure' => 'users/sessions#no_procedure' get '/users/no_procedure' => 'users/sessions#no_procedure'
get 'connexion-par-jeton/:id' => 'users/sessions#sign_in_by_link', as: 'sign_in_by_link' get 'connexion-par-jeton/:id' => 'users/sessions#sign_in_by_link', as: 'sign_in_by_link'
get 'lien-envoye/:email' => 'users/sessions#link_sent', constraints: { email: /.*/ }, as: 'link_sent' get 'lien-envoye/:email' => 'users/sessions#link_sent', constraints: { email: /.*/ }, as: 'link_sent'
get '/users/password/reset-link-sent' => 'users/passwords#reset_link_sent'
end end
devise_scope :administrateur do devise_scope :administrateur do

View file

@ -38,4 +38,16 @@ describe Users::PasswordsController, type: :controller do
end end
end end
end end
describe '#reset_link_sent' do
let(:email) { 'test@example.com' }
it 'displays the page' do
get 'reset_link_sent', params: { email: email }
expect(response).to have_http_status(:ok)
expect(response).to render_template('reset_link_sent')
expect(assigns(:email)).to eq email
end
end
end end

View file

@ -13,7 +13,8 @@ feature 'Managing password:' do
perform_enqueued_jobs do perform_enqueued_jobs do
click_on 'Demander un nouveau mot de passe' click_on 'Demander un nouveau mot de passe'
end end
expect(page).to have_content('Si votre courriel existe dans notre base de données, vous recevrez un lien vous permettant de récupérer votre mot de passe.') expect(page).to have_text 'Nous vous avons envoyé un email'
expect(page).to have_text user.email
click_reset_password_link_for user.email click_reset_password_link_for user.email
expect(page).to have_content 'Changement de mot de passe' expect(page).to have_content 'Changement de mot de passe'
@ -40,7 +41,8 @@ feature 'Managing password:' do
perform_enqueued_jobs do perform_enqueued_jobs do
click_on 'Demander un nouveau mot de passe' click_on 'Demander un nouveau mot de passe'
end end
expect(page).to have_content('Si votre courriel existe dans notre base de données, vous recevrez un lien vous permettant de récupérer votre mot de passe.') expect(page).to have_text 'Nous vous avons envoyé un email'
expect(page).to have_text user.email
click_reset_password_link_for user.email click_reset_password_link_for user.email