profile: send an email when the account is already taken

This commit is contained in:
Pierre de La Morinerie 2019-07-09 17:08:27 +02:00
parent 80074d6d82
commit 03fc555edf
6 changed files with 67 additions and 3 deletions

View file

@ -12,8 +12,9 @@ module Users
def update_email def update_email
if @current_user.update(update_email_params) if @current_user.update(update_email_params)
flash.notice = t('devise.registrations.update_needs_confirmation') 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 } elsif @current_user.errors&.details&.dig(:email)&.any? { |e| e[:error] == :taken }
UserMailer.account_already_taken(@current_user, requested_email).deliver_later
# avoid leaking information about whether an account with this email exists or not
flash.notice = t('devise.registrations.update_needs_confirmation') flash.notice = t('devise.registrations.update_needs_confirmation')
else else
flash.alert = @current_user.errors.full_messages flash.alert = @current_user.errors.full_messages
@ -27,5 +28,9 @@ module Users
def update_email_params def update_email_params
params.require(:user).permit(:email) params.require(:user).permit(:email)
end end
def requested_email
update_email_params[:email]
end
end end
end end

View file

@ -8,4 +8,12 @@ class UserMailer < ApplicationMailer
mail(to: user.email, subject: @subject) mail(to: user.email, subject: @subject)
end end
def account_already_taken(user, requested_email)
@user = user
@requested_email = requested_email
@subject = "Changement dadresse email"
mail(to: requested_email, subject: @subject)
end
end end

View file

@ -0,0 +1,20 @@
- content_for(:title, @subject)
%p
Bonjour,
%p
Lutilisateur « #{@user.email} » a demandé le changement de son adresse vers « #{@requested_email} ».
%p
Malheureusement, votre compte « #{@requested_email} » existe déjà. Nous ne pouvons pas fusionner automatiquement vos comptes.
%p
%strong Nous ne pouvons donc pas effectuer le changement dadresse email.
%p
Si vous n'êtes pas à lorigine de cette demande, vous pouvez ignorer ce message. Et si vous avez besoin dassistance, nhésitez pas à nous contacter à
= succeed '.' do
= mail_to CONTACT_EMAIL
= render partial: "layouts/mailers/signature"

View file

@ -1,6 +1,8 @@
require 'spec_helper' require 'spec_helper'
describe Users::ProfilController, type: :controller do describe Users::ProfilController, type: :controller do
include ActiveJob::TestHelper
let(:user) { create(:user) } let(:user) { create(:user) }
before { sign_in(user) } before { sign_in(user) }
@ -34,13 +36,17 @@ describe Users::ProfilController, type: :controller do
end end
context 'when the mail is already taken' do context 'when the mail is already taken' do
let!(:user2) { create(:user) } let(:existing_user) { create(:user) }
before do before do
patch :update_email, params: { user: { email: user2.email } } perform_enqueued_jobs do
patch :update_email, params: { user: { email: existing_user.email } }
end
user.reload user.reload
end end
it { expect(user.unconfirmed_email).to be_nil }
it { expect(ActionMailer::Base.deliveries.last.to).to eq([existing_user.email]) }
it { expect(response).to redirect_to(profil_path) } it { expect(response).to redirect_to(profil_path) }
it { expect(flash.notice).to eq(I18n.t('devise.registrations.update_needs_confirmation')) } it { expect(flash.notice).to eq(I18n.t('devise.registrations.update_needs_confirmation')) }
end end

View file

@ -3,6 +3,10 @@ class UserMailerPreview < ActionMailer::Preview
UserMailer.new_account_warning(user) UserMailer.new_account_warning(user)
end end
def account_already_taken
UserMailer.account_already_taken(user, 'dircab@territoires.gouv.fr')
end
private private
def user def user

View file

@ -0,0 +1,21 @@
require "rails_helper"
RSpec.describe UserMailer, type: :mailer do
let(:user) { build(:user) }
describe '.new_account_warning' do
subject { described_class.new_account_warning(user) }
it { expect(subject.to).to eq([user.email]) }
it { expect(subject.body).to include(user.email) }
end
describe '.account_already_taken' do
let(:requested_email) { 'new@exemple.fr' }
subject { described_class.account_already_taken(user, requested_email) }
it { expect(subject.to).to eq([requested_email]) }
it { expect(subject.body).to include(requested_email) }
end
end