Fix 1709 change my email (#4047)
Possibilité de changer l'adresse email de son compte
This commit is contained in:
commit
7634fb6d8a
17 changed files with 212 additions and 69 deletions
|
@ -1,12 +0,0 @@
|
||||||
module NewAdministrateur
|
|
||||||
class ProfilController < AdministrateurController
|
|
||||||
def show
|
|
||||||
end
|
|
||||||
|
|
||||||
def renew_api_token
|
|
||||||
@token = current_administrateur.renew_api_token
|
|
||||||
flash.now.notice = 'Votre jeton a été regénéré.'
|
|
||||||
render :show
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
31
app/controllers/users/profil_controller.rb
Normal file
31
app/controllers/users/profil_controller.rb
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
module Users
|
||||||
|
class ProfilController < UserController
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def renew_api_token
|
||||||
|
@token = current_administrateur.renew_api_token
|
||||||
|
flash.now.notice = 'Votre jeton a été regénéré.'
|
||||||
|
render :show
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_email
|
||||||
|
if @current_user.update(update_email_params)
|
||||||
|
flash.notice = t('devise.registrations.update_needs_confirmation')
|
||||||
|
# to avoid leaking who has signed in
|
||||||
|
elsif @current_user.errors&.details&.dig(:email)&.any? { |e| e[:error] == :taken }
|
||||||
|
flash.notice = t('devise.registrations.update_needs_confirmation')
|
||||||
|
else
|
||||||
|
flash.alert = @current_user.errors.full_messages
|
||||||
|
end
|
||||||
|
|
||||||
|
redirect_to profil_path
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def update_email_params
|
||||||
|
params.require(:user).permit(:email)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
11
app/helpers/tableau_de_bord_helper.rb
Normal file
11
app/helpers/tableau_de_bord_helper.rb
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module TableauDeBordHelper
|
||||||
|
def tableau_de_bord_helper_path
|
||||||
|
if current_administrateur.present?
|
||||||
|
admin_procedures_path
|
||||||
|
elsif current_gestionnaire.present?
|
||||||
|
gestionnaire_procedures_path
|
||||||
|
else
|
||||||
|
dossiers_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,10 +1,22 @@
|
||||||
- content_for(:title, 'Activez votre compte')
|
-# ugly hack to know if the mail is creation confirmation or a password change confirmation
|
||||||
|
- if @user.unconfirmed_email.nil?
|
||||||
|
- content_for(:title, 'Activez votre compte')
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Bonjour,
|
Bonjour,
|
||||||
|
|
||||||
%p
|
%p
|
||||||
Pour activer votre compte sur demarches-simplifiees.fr, veuillez cliquer sur le lien suivant :
|
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_to(confirmation_url(@user, confirmation_token: @token), confirmation_url(@user, confirmation_token: @token))
|
||||||
|
|
||||||
|
- else
|
||||||
|
- content_for(:title, "Changement d'adresse email")
|
||||||
|
|
||||||
|
%p
|
||||||
|
Bonjour,
|
||||||
|
|
||||||
|
%p
|
||||||
|
Pour confirmer votre changement d'adresse email, veuillez cliquer sur le lien suivant :
|
||||||
|
= link_to(confirmation_url(@user, confirmation_token: @token), confirmation_url(@user, confirmation_token: @token))
|
||||||
|
|
||||||
= render partial: "layouts/mailers/signature"
|
= render partial: "layouts/mailers/signature"
|
||||||
|
|
|
@ -26,6 +26,10 @@
|
||||||
= link_to admin_procedures_path, class: "menu-item menu-link" do
|
= link_to admin_procedures_path, class: "menu-item menu-link" do
|
||||||
= image_tag "icons/switch-profile.svg"
|
= image_tag "icons/switch-profile.svg"
|
||||||
Passer en administrateur
|
Passer en administrateur
|
||||||
|
%li
|
||||||
|
= link_to profil_path, class: "menu-item menu-link" do
|
||||||
|
= image_tag "icons/switch-profile.svg"
|
||||||
|
Voir mon profil
|
||||||
|
|
||||||
%li
|
%li
|
||||||
= link_to destroy_user_session_path, method: :delete, class: "menu-item menu-link" do
|
= link_to destroy_user_session_path, method: :delete, class: "menu-item menu-link" do
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
= render partial: 'new_administrateur/breadcrumbs',
|
|
||||||
locals: { steps: [link_to('Tableau de bord', admin_procedures_path),
|
|
||||||
'Profil'] }
|
|
||||||
|
|
||||||
#profil-page.container
|
|
||||||
%h1 Profil
|
|
||||||
|
|
||||||
.card
|
|
||||||
.card-title Jeton d'identification de l'API (token)
|
|
||||||
%p Ce jeton est nécessaire pour effectuer des appels vers l'API de demarches-simplifiees.fr.
|
|
||||||
|
|
||||||
- if defined?(@token)
|
|
||||||
%p Jeton : <b>#{@token}</b>
|
|
||||||
%p Pour des raisons de sécurité, ce jeton ne sera plus ré-affiché, notez-le bien.
|
|
||||||
|
|
||||||
- else
|
|
||||||
%p Pour des raisons de sécurité, nous ne pouvons vous l'afficher que lors de sa génération.
|
|
||||||
%p Attention, si vous avez déjà des applications qui utilisent votre jeton, le regénérer bloquera leurs accès à l'API.
|
|
||||||
|
|
||||||
= link_to "Regénérer et afficher mon jeton",
|
|
||||||
renew_api_token_path,
|
|
||||||
method: :post,
|
|
||||||
class: "button primary",
|
|
||||||
data: { confirm: "Confirmez-vous la regénération de votre jeton ? Les applications qui l'utilisent actuellement seront bloquées.",
|
|
||||||
disable: true }
|
|
39
app/views/users/profil/show.html.haml
Normal file
39
app/views/users/profil/show.html.haml
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
= render partial: 'new_administrateur/breadcrumbs',
|
||||||
|
locals: { steps: [link_to('Tableau de bord', tableau_de_bord_helper_path),
|
||||||
|
'Profil'] }
|
||||||
|
|
||||||
|
#profil-page.container
|
||||||
|
%h1 Profil
|
||||||
|
|
||||||
|
.card
|
||||||
|
.card-title Coordonnées
|
||||||
|
%p Votre email est actuellement #{current_user.email}
|
||||||
|
- if current_user.unconfirmed_email.present?
|
||||||
|
%p
|
||||||
|
Un email a été envoyé à #{current_user.unconfirmed_email}.
|
||||||
|
%br
|
||||||
|
Merci de vérifier vos emails et de cliquer sur le lien d’activation pour finaliser la validation de votre nouvelle adresse.
|
||||||
|
|
||||||
|
= form_for @current_user, url: update_email_path, method: :patch, html: { class: 'form' } do |f|
|
||||||
|
= f.email_field :email, value: nil, placeholder: 'Nouvelle adresse email', required: true
|
||||||
|
= f.submit "Changer mon adresse", class: 'button primary'
|
||||||
|
|
||||||
|
- if current_administrateur.present?
|
||||||
|
.card
|
||||||
|
.card-title Jeton d’identification de l’API (token)
|
||||||
|
%p Ce jeton est nécessaire pour effectuer des appels vers l’API de demarches-simplifiees.fr.
|
||||||
|
|
||||||
|
- if defined?(@token)
|
||||||
|
%p Jeton : <b>#{@token}</b>
|
||||||
|
%p Pour des raisons de sécurité, ce jeton ne sera plus ré-affiché, notez-le bien.
|
||||||
|
|
||||||
|
- else
|
||||||
|
%p Pour des raisons de sécurité, nous ne pouvons vous l’afficher que lors de sa génération.
|
||||||
|
%p Attention, si vous avez déjà des applications qui utilisent votre jeton, le regénérer bloquera leurs accès à l’API.
|
||||||
|
|
||||||
|
= link_to "Regénérer et afficher mon jeton",
|
||||||
|
renew_api_token_path,
|
||||||
|
method: :post,
|
||||||
|
class: "button primary",
|
||||||
|
data: { confirm: "Confirmez-vous la regénération de votre jeton ? Les applications qui l’utilisent actuellement seront bloquées.",
|
||||||
|
disable: true }
|
|
@ -121,7 +121,7 @@ Devise.setup do |config|
|
||||||
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
# initial account confirmation) to be applied. Requires additional unconfirmed_email
|
||||||
# db field (see migrations). Until confirmed, new email is stored in
|
# db field (see migrations). Until confirmed, new email is stored in
|
||||||
# unconfirmed_email column, and copied to email column on successful confirmation.
|
# unconfirmed_email column, and copied to email column on successful confirmation.
|
||||||
config.reconfirmable = false
|
config.reconfirmable = true
|
||||||
|
|
||||||
# Defines which key will be used when confirming an account
|
# Defines which key will be used when confirming an account
|
||||||
# config.confirmation_keys = [ :email ]
|
# config.confirmation_keys = [ :email ]
|
||||||
|
|
|
@ -42,7 +42,7 @@ fr:
|
||||||
signed_up_but_inactive: "Vous êtes bien enregistré. Vous ne pouvez cependant pas vous connecter car votre compte n'est pas encore activé."
|
signed_up_but_inactive: "Vous êtes bien enregistré. Vous ne pouvez cependant pas vous connecter car votre compte n'est pas encore activé."
|
||||||
signed_up_but_locked: "Vous êtes bien enregistré. Vous ne pouvez cependant pas vous connecter car votre compte est verrouillé."
|
signed_up_but_locked: "Vous êtes bien enregistré. Vous ne pouvez cependant pas vous connecter car votre compte est verrouillé."
|
||||||
signed_up_but_unconfirmed: "Nous vous avons envoyé un email contenant un lien d'activation. Ouvrez ce lien pour activer votre compte."
|
signed_up_but_unconfirmed: "Nous vous avons envoyé un email contenant un lien d'activation. Ouvrez ce lien pour activer votre compte."
|
||||||
update_needs_confirmation: "Votre compte a bien été mis à jour mais nous devons vérifier votre nouvelle adresse email. Merci de vérifier vos email et de cliquer sur le lien d'activation pour finaliser la validation de votre nouvelle adresse."
|
update_needs_confirmation: "Votre compte a bien été mis à jour mais nous devons vérifier votre nouvelle adresse email. Merci de vérifier vos emails et de cliquer sur le lien d’activation pour finaliser la validation de votre nouvelle adresse."
|
||||||
updated: "Votre compte a été modifié avec succès."
|
updated: "Votre compte a été modifié avec succès."
|
||||||
sessions:
|
sessions:
|
||||||
signed_in: "Connecté."
|
signed_in: "Connecté."
|
||||||
|
|
|
@ -291,6 +291,12 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
resource :feedback, only: [:create]
|
resource :feedback, only: [:create]
|
||||||
get 'demarches' => 'demarches#index'
|
get 'demarches' => 'demarches#index'
|
||||||
|
|
||||||
|
get 'profil' => 'profil#show'
|
||||||
|
post 'renew-api-token' => 'profil#renew_api_token'
|
||||||
|
# allow refresh 'renew api token' page
|
||||||
|
get 'renew-api-token' => redirect('/profil')
|
||||||
|
patch 'update_email' => 'profil#update_email'
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -377,11 +383,6 @@ Rails.application.routes.draw do
|
||||||
patch 'add_to_procedure'
|
patch 'add_to_procedure'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
get 'profil' => 'profil#show'
|
|
||||||
post 'renew-api-token' => 'profil#renew_api_token'
|
|
||||||
# allow refresh 'renew api token' page
|
|
||||||
get 'renew-api-token' => redirect('/profil')
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddUnconfirmedEmailColumnToUsers < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :users, :unconfirmed_email, :text
|
||||||
|
end
|
||||||
|
end
|
|
@ -605,6 +605,7 @@ ActiveRecord::Schema.define(version: 2019_07_04_144304) do
|
||||||
t.string "confirmation_token"
|
t.string "confirmation_token"
|
||||||
t.datetime "confirmed_at"
|
t.datetime "confirmed_at"
|
||||||
t.datetime "confirmation_sent_at"
|
t.datetime "confirmation_sent_at"
|
||||||
|
t.text "unconfirmed_email"
|
||||||
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
t.index ["confirmation_token"], name: "index_users_on_confirmation_token", unique: true
|
||||||
t.index ["email"], name: "index_users_on_email", unique: true
|
t.index ["email"], name: "index_users_on_email", unique: true
|
||||||
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe NewAdministrateur::ProfilController, type: :controller do
|
|
||||||
let(:administrateur) { create(:administrateur) }
|
|
||||||
|
|
||||||
before { sign_in(administrateur) }
|
|
||||||
|
|
||||||
describe 'POST #renew_api_token' do
|
|
||||||
before do
|
|
||||||
allow(administrateur).to receive(:renew_api_token)
|
|
||||||
allow(controller).to receive(:current_administrateur) { administrateur }
|
|
||||||
post :renew_api_token
|
|
||||||
end
|
|
||||||
|
|
||||||
it { expect(administrateur).to have_received(:renew_api_token) }
|
|
||||||
it { expect(response.status).to render_template(:show) }
|
|
||||||
it { expect(flash.notice).to eq('Votre jeton a été regénéré.') }
|
|
||||||
end
|
|
||||||
end
|
|
60
spec/controllers/users/profil_controller_spec.rb
Normal file
60
spec/controllers/users/profil_controller_spec.rb
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Users::ProfilController, type: :controller do
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
|
||||||
|
before { sign_in(user) }
|
||||||
|
|
||||||
|
describe 'POST #renew_api_token' do
|
||||||
|
let(:administrateur) { create(:administrateur) }
|
||||||
|
|
||||||
|
before { sign_in(administrateur) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(administrateur).to receive(:renew_api_token)
|
||||||
|
allow(controller).to receive(:current_administrateur) { administrateur }
|
||||||
|
post :renew_api_token
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(administrateur).to have_received(:renew_api_token) }
|
||||||
|
it { expect(response.status).to render_template(:show) }
|
||||||
|
it { expect(flash.notice).to eq('Votre jeton a été regénéré.') }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'PATCH #update_email' do
|
||||||
|
context 'when everything is fine' do
|
||||||
|
before do
|
||||||
|
patch :update_email, params: { user: { email: 'loulou@lou.com' } }
|
||||||
|
user.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(user.unconfirmed_email).to eq('loulou@lou.com') }
|
||||||
|
it { expect(response).to redirect_to(profil_path) }
|
||||||
|
it { expect(flash.notice).to eq(I18n.t('devise.registrations.update_needs_confirmation')) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the mail is already taken' do
|
||||||
|
let!(:user2) { create(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
patch :update_email, params: { user: { email: user2.email } }
|
||||||
|
user.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response).to redirect_to(profil_path) }
|
||||||
|
it { expect(flash.notice).to eq(I18n.t('devise.registrations.update_needs_confirmation')) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when the mail is incorrect' do
|
||||||
|
let!(:user2) { create(:user) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
patch :update_email, params: { user: { email: 'incorrect' } }
|
||||||
|
user.reload
|
||||||
|
end
|
||||||
|
|
||||||
|
it { expect(response).to redirect_to(profil_path) }
|
||||||
|
it { expect(flash.alert).to eq(['Email invalide']) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -6,6 +6,7 @@ feature 'Administrator connection' do
|
||||||
let(:email) { 'admin1@admin.com' }
|
let(:email) { 'admin1@admin.com' }
|
||||||
let(:password) { 'mon chien aime les bananes' }
|
let(:password) { 'mon chien aime les bananes' }
|
||||||
let!(:admin) { create(:administrateur, :with_procedure, email: email, password: password) }
|
let!(:admin) { create(:administrateur, :with_procedure, email: email, password: password) }
|
||||||
|
let!(:user) { create(:user, email: email, password: password) }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
Flipflop::FeatureSet.current.test!.switch!(:enable_email_login_token, true)
|
||||||
|
|
32
spec/features/users/change_email_spec.rb
Normal file
32
spec/features/users/change_email_spec.rb
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
feature 'Changing an email' do
|
||||||
|
let(:old_email) { 'old@email.com' }
|
||||||
|
let(:user) { create(:user, email: old_email) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
login_as user, scope: :user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'is easy' do
|
||||||
|
new_email = 'new@email.com'
|
||||||
|
|
||||||
|
visit '/profil'
|
||||||
|
|
||||||
|
fill_in :user_email, with: new_email
|
||||||
|
|
||||||
|
perform_enqueued_jobs do
|
||||||
|
click_button 'Changer mon adresse'
|
||||||
|
end
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.email).to eq(old_email)
|
||||||
|
expect(user.unconfirmed_email).to eq(new_email)
|
||||||
|
|
||||||
|
click_confirmation_link_for(new_email)
|
||||||
|
|
||||||
|
user.reload
|
||||||
|
expect(user.email).to eq(new_email)
|
||||||
|
expect(user.unconfirmed_email).to be_nil
|
||||||
|
end
|
||||||
|
end
|
|
@ -107,6 +107,7 @@ describe User, type: :model do
|
||||||
gestionnaire = create(:gestionnaire, email: user.email)
|
gestionnaire = create(:gestionnaire, email: user.email)
|
||||||
|
|
||||||
user.update(email: 'whoami@plop.com', password: 'super secret')
|
user.update(email: 'whoami@plop.com', password: 'super secret')
|
||||||
|
user.confirm
|
||||||
|
|
||||||
gestionnaire.reload
|
gestionnaire.reload
|
||||||
expect(gestionnaire.email).to eq('whoami@plop.com')
|
expect(gestionnaire.email).to eq('whoami@plop.com')
|
||||||
|
@ -118,6 +119,7 @@ describe User, type: :model do
|
||||||
admin = create(:administrateur, email: user.email)
|
admin = create(:administrateur, email: user.email)
|
||||||
|
|
||||||
user.update(email: 'whoami@plop.com', password: 'super secret')
|
user.update(email: 'whoami@plop.com', password: 'super secret')
|
||||||
|
user.confirm
|
||||||
|
|
||||||
admin.reload
|
admin.reload
|
||||||
expect(admin.email).to eq('whoami@plop.com')
|
expect(admin.email).to eq('whoami@plop.com')
|
||||||
|
|
Loading…
Add table
Reference in a new issue