Merge pull request #5688 from betagouv/support-comptes

Ajout d'un écran de synthèse des emails dans /manager
This commit is contained in:
Keirua 2020-10-14 09:20:23 +02:00 committed by GitHub
commit be39d0dd29
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 219 additions and 2 deletions

View file

@ -69,6 +69,7 @@ gem 'rgeo-geojson'
gem 'sanitize-url' gem 'sanitize-url'
gem 'sassc-rails' # Use SCSS for stylesheets gem 'sassc-rails' # Use SCSS for stylesheets
gem 'sentry-raven' gem 'sentry-raven'
gem 'sib-api-v3-sdk'
gem 'skylight' gem 'skylight'
gem 'smart_listing' gem 'smart_listing'
gem 'spreadsheet_architect' gem 'spreadsheet_architect'

View file

@ -102,7 +102,7 @@ GEM
rake (>= 10.4, < 14.0) rake (>= 10.4, < 14.0)
ast (2.4.1) ast (2.4.1)
attr_required (1.0.1) attr_required (1.0.1)
autoprefixer-rails (10.0.0.2) autoprefixer-rails (10.0.1.0)
execjs execjs
axe-matchers (2.6.1) axe-matchers (2.6.1)
dumb_delegator (~> 0.8) dumb_delegator (~> 0.8)
@ -348,6 +348,7 @@ GEM
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
json (2.3.1)
json-jwt (1.13.0) json-jwt (1.13.0)
activesupport (>= 4.2) activesupport (>= 4.2)
aes_key_wrap aes_key_wrap
@ -658,6 +659,9 @@ GEM
shellany (0.0.1) shellany (0.0.1)
shoulda-matchers (4.4.1) shoulda-matchers (4.4.1)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
sib-api-v3-sdk (7.0.0)
json (~> 2.1, >= 2.1.0)
typhoeus (~> 1.0, >= 1.0.1)
simple_xlsx_reader (1.0.4) simple_xlsx_reader (1.0.4)
nokogiri nokogiri
rubyzip rubyzip
@ -860,6 +864,7 @@ DEPENDENCIES
scss_lint scss_lint
sentry-raven sentry-raven
shoulda-matchers shoulda-matchers
sib-api-v3-sdk
simple_xlsx_reader simple_xlsx_reader
skylight skylight
smart_listing smart_listing

View file

@ -46,5 +46,27 @@ module Manager
redirect_to manager_users_path redirect_to manager_users_path
end end
def emails
@user = User.find(params[:id])
transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new
@transactionnal_emails = transactionnal_api.get_transac_emails_list(email: @user.email)
@events = transactionnal_api.get_email_event_report(email: @user.email, days: 30)
rescue ::SibApiV3Sdk::ApiError => e
flash.alert = "Impossible de récupérer les emails de cet utilisateur chez Sendinblue : #{e.message}"
end
def unblock_user
@user = User.find(params[:id])
transactionnal_api = ::SibApiV3Sdk::TransactionalEmailsApi.new
transactionnal_api.smtp_blocked_contacts_email_delete(@user.email)
rescue ::SibApiV3Sdk::ApiError => e
flash.alert = "Impossible de débloquer cet email auprès de Sendinblue : #{e.message}"
end
end end
end end

View file

@ -26,6 +26,8 @@ class WebhookController < ActionController::Base
html << link_to_manager(administrateur, url) html << link_to_manager(administrateur, url)
end end
html << email_link_to_manager(user)
render json: { html: html.join('<br>') } render json: { html: html.join('<br>') }
end end
end end
@ -36,6 +38,11 @@ class WebhookController < ActionController::Base
"<a target='_blank' href='#{url}' rel='noopener'>#{model.model_name.human}##{model.id}</a>" "<a target='_blank' href='#{url}' rel='noopener'>#{model.model_name.human}##{model.id}</a>"
end end
def email_link_to_manager(user)
url = emails_manager_user_url(user)
"<a target='_blank' href='#{url}' rel='noopener'>Emails##{user.id}</a>"
end
def verify_signature! def verify_signature!
if generate_body_signature(request.body.read) != request.headers['X-Helpscout-Signature'] if generate_body_signature(request.body.read) != request.headers['X-Helpscout-Signature']
request_http_token_authentication request_http_token_authentication

View file

@ -0,0 +1,12 @@
module EmailHelper
def event_color_code(email_events)
unique_events = email_events.map(&:event)
if unique_events.include?('delivered')
return 'email-sent'
elsif unique_events.include?('blocked') || unique_events.include?('hardBounces')
return 'email-blocked'
else
return ''
end
end
end

View file

@ -42,6 +42,7 @@ as well as a link to its edit page.
</header> </header>
<section class="main-content__body"> <section class="main-content__body">
<%= render partial: 'manager/application/user_meta', locals: {user: page.resource&.user} %>
<dl> <dl>
<% page.attributes.each do |attribute| %> <% page.attributes.each do |attribute| %>
<dt class="attribute-label" id="<%= attribute.name %>"> <dt class="attribute-label" id="<%= attribute.name %>">

View file

@ -0,0 +1,43 @@
<dl>
<dt class="attribute-label" id="meta-usager">
Emails
</dt>
<dd class="attribute-data attribute-data--meta-usager">
<%= link_to('Voir les derniers emails', emails_manager_user_path(user)) %>
</dd>
</dl>
<dl>
<dt class="attribute-label" id="meta-usager">
Usager
</dt>
<dd class="attribute-data attribute-data--meta-usager">
<%= link_to('Voir son compte utilisateur', manager_user_path(user)) %>
</dd>
</dl>
<dl>
<dt class="attribute-label" id="meta-usager">
Instructeur
</dt>
<dd class="attribute-data attribute-data--meta-usager">
<% if user.instructeur.present? %>
<%= link_to('Voir son compte instructeur', manager_instructeur_path(user.instructeur)) %>
<% else %>
Pas instructeur !
<% end %>
</dd>
</dl>
<dl>
<dt class="attribute-label" id="meta-usager">
Administrateur
</dt>
<dd class="attribute-data attribute-data--meta-usager">
<% if user.administrateur.present? %>
<%= link_to('Voir son compte administrateur', manager_administrateur_path(user.administrateur)) %>
<% else %>
Pas administrateur !
<% end %>
</dd>
</dl>
<hr />

View file

@ -41,6 +41,7 @@ as well as a link to its edit page.
</header> </header>
<section class="main-content__body"> <section class="main-content__body">
<%= render partial: 'manager/application/user_meta', locals: {user: page.resource&.user} %>
<dl> <dl>
<% page.attributes.each do |attribute| %> <% page.attributes.each do |attribute| %>
<dt class="attribute-label" id="<%= attribute.name %>"> <dt class="attribute-label" id="<%= attribute.name %>">

View file

@ -0,0 +1,117 @@
<% content_for(:title) { "Emails vers #{@user.email}" } %>
<style>
.hidden { display: none }
.email-sent { color: green !important}
.email-blocked { color: red }
</style>
<script type="text/javascript" charset="utf-8">
function reveal_email(id) {
document.querySelector(id).classList.toggle('hidden');
}
</script>
<header class="main-content__header" role="banner">
<h1 class="main-content__page-title">
<%= content_for(:title) %>
</h1>
</header>
<section class="main-content__body">
<h2>Historique des email</h2>
<% if @transactionnal_emails.present? %>
<p>
Cet historique contient les 30 derniers jours. Pour un recherche plus fine, il faut <a href="https://app-smtp.sendinblue.com/log">fouiller les logs</a>.
</p>
<table>
<thead>
<tr>
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
Émetteur
</th>
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
Sujet
</th>
<th class="cell-label cell-label--string cell-label--false" scope="col" role="columnheader" aria-sort="none">
Date
</th>
</tr>
</thead>
<tbody>
<% @transactionnal_emails&.transactional_emails&.reverse&.each do |email| %>
<% matching_events = @events&.events&.select { |e| e.message_id == email.message_id } %>
<tr class="<%= event_color_code(matching_events) %>">
<td class="cell-data cell-data--string" style="">
<%= email.from %>
</td>
<td class="cell-data cell-data--string" style="">
<%= email.subject %>
</td>
<td class="cell-data cell-data--string" style="text-align: center;">
<%= l(email.date, format: '%d/%m/%y à %H:%M') %>
</td>
<td class="cell-data cell-data--string" style="text-align: center;">
<ul>
<% matching_events.each do |event|%>
<li><%= event.event %></li>
<% end %>
</ul>
</td>
</tr>
<% end %>
</tbody>
</table>
<% else %>
<p>Historique indisponible. Cet email n'existe pas chez Sendinblue, ou nous n'avons pas réussi à échanger.
Vous pouvez éventuellement <a href="https://app-smtp.sendinblue.com/log">fouiller leurs logs</a>.</p>
<% end %>
<h2>Problèmes potentiel</h2>
<% if @user.confirmed? %>
<p><strong>Compte activé, n'arrive pas à se connecter</strong> ? <button class="btn btn-secondary btn-small" onclick="reveal_email('#activated-cant-connect')">Voir la suggestion demail</button></p>
<pre class="hidden" id="activated-cant-connect">
Bonjour,
votre compte est activé de notre côté.
Vous pouvez vous connecter à votre compte de deux manières :
- à cette adresse, afin de consulter vos dossiers : https://www.demarches-simplifiees.fr/users/sign_in
- depuis la page de démarrage dune démarche qu'on vous a communiqué, afin de déposer un dossier.
Si vous avez oublié votre mot de passe, vous pouvez aussi en demander un nouveau via:
https://www.demarches-simplifiees.fr/users/password/new
Bien cordialement</pre>
<% else %>
<p><strong>Ce compte n'est pas activé</strong>. Vous pouvez lui <%= link_to('renvoyer lemail de confirmation', [:resend_confirmation_instructions, namespace, 'user'], method: :post, class: 'button') %>, puis un email. <button class="btn btn-secondary btn-small" onclick="reveal_email('#not-activated')">Voir la suggestion demail</button> </p>
<pre class="hidden" id="not-activated">
Bonjour,
Votre compte n'a pas été confirmé. Je vous ai transmis à nouveau un code de confirmation
dans un email séparé ; après avoir cliqué sur le lien qui s'y trouve, vous pourrez vous connecter
à votre compte, voir les dossiers déposés et en déposer de nouveaux.
Si vous avez oublié votre mot de passe, vous pouvez aussi en demander un autre via:
https://www.demarches-simplifiees.fr/users/password/new
Cordialement</pre>
<% end %>
<p><strong>Compte <a href="https://app-smtp.sendinblue.com/block">bloqué</a> chez Sendinblue ?</strong> Vous pouvez le <%= link_to('débloquer', manager_user_unblock_email_path(@user), method: :put, class: 'button', remote: true) %> puis lui envoyer <button class="btn btn-secondary btn-small" onclick="reveal_email('#unblock_email')">le mail suivant</button></p>
<pre class="hidden" id="unblock_email">
Bonjour,
votre email était bloqué par notre prestataire.
Je l'ai débloqué, vous devriez recevoir les mails à venir.
Cela peut arriver si vous, ou ceux qui gèrent vos emails, marquent nos emails comme spam.
Nous vous invitons donc à autoriser les emails émis depuis demarches-simplifiees.fr
Bien cordialement</pre>
<p><strong>Problème chez Sendinblue ?</strong> Regardez leur <a href="https://status.sendinblue.com/">page de status</a>. <button class="btn btn-secondary btn-small" onclick="reveal_email('#pb-sendinblue')">Voir la suggestion demail</button></p>
<pre class="hidden" id="pb-sendinblue">
Bonjour,
Désolé, notre prestataire d'envoi d'email subit actuellement des soucis avec sa plateforme ;
vous allez recevoir cet email sous peu.
Bien cordialement,</pre>
</section>

View file

@ -34,10 +34,11 @@ as well as a link to its edit page.
<% if !user.confirmed? %> <% if !user.confirmed? %>
<%= link_to('Renvoyer lemail de confirmation', [:resend_confirmation_instructions, namespace, page.resource], method: :post, class: 'button') %> <%= link_to('Renvoyer lemail de confirmation', [:resend_confirmation_instructions, namespace, page.resource], method: :post, class: 'button') %>
<% end %> <% end %>
<div> </div>
</header> </header>
<section class="main-content__body"> <section class="main-content__body">
<%= render partial: 'manager/application/user_meta', locals: {user: user} %>
<dl> <dl>
<% page.attributes.each do |attribute| %> <% page.attributes.each do |attribute| %>
<dt class="attribute-label" id="<%= attribute.name %>"> <dt class="attribute-label" id="<%= attribute.name %>">

View file

@ -0,0 +1,5 @@
require 'sib-api-v3-sdk'
SibApiV3Sdk.configure do |config|
config.api_key['api-key'] = ENV.fetch('SENDINBLUE_API_V3_KEY', '')
end

View file

@ -31,6 +31,8 @@ Rails.application.routes.draw do
delete 'delete', on: :member delete 'delete', on: :member
post 'resend_confirmation_instructions', on: :member post 'resend_confirmation_instructions', on: :member
put 'enable_feature', on: :member put 'enable_feature', on: :member
get 'emails', on: :member
put 'unblock_email'
end end
resources :instructeurs, only: [:index, :show] do resources :instructeurs, only: [:index, :show] do