diff --git a/app/assets/images/faq/usager-confirm-update-email.png b/app/assets/images/faq/usager-confirm-update-email.png new file mode 100644 index 000000000..b93ff5680 Binary files /dev/null and b/app/assets/images/faq/usager-confirm-update-email.png differ diff --git a/app/assets/images/faq/usager-dropdown.png b/app/assets/images/faq/usager-dropdown.png new file mode 100644 index 000000000..6fd5f65a2 Binary files /dev/null and b/app/assets/images/faq/usager-dropdown.png differ diff --git a/app/assets/images/faq/usager-edit-email.png b/app/assets/images/faq/usager-edit-email.png new file mode 100644 index 000000000..6a8b0b48d Binary files /dev/null and b/app/assets/images/faq/usager-edit-email.png differ diff --git a/app/assets/stylesheets/markdown-content.scss b/app/assets/stylesheets/markdown-content.scss new file mode 100644 index 000000000..c166078e8 --- /dev/null +++ b/app/assets/stylesheets/markdown-content.scss @@ -0,0 +1,20 @@ +.markdown-content { + img { + max-width: 100%; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + + display: block; + + // In markdown img are always wrapped in p, + // which already contains vertical margin. + // We only add margin when there are siblings. + // NOTE: CSS consider the img is only-child even + // when there are only text node siblings, but it's still fine for us. + margin: 1.5rem auto; + + &:only-child { + margin-top: 0; + margin-bottom: 0; + } + } +} diff --git a/app/controllers/faq_controller.rb b/app/controllers/faq_controller.rb index a6b28d7ed..6c28f2725 100644 --- a/app/controllers/faq_controller.rb +++ b/app/controllers/faq_controller.rb @@ -8,9 +8,7 @@ class FAQController < ApplicationController end def show - @renderer = Redcarpet::Markdown.new( - Redcarpet::BareRenderer.new(class_names_map: { list: 'fr-ol-content--override' }) - ) + @renderer = Redcarpet::Markdown.new(Redcarpet::TrustedRenderer.new(view_context), autolink: true) @siblings = loader_service.faqs_for_category(@metadata[:category]) end diff --git a/app/lib/redcarpet/bare_renderer.rb b/app/lib/redcarpet/bare_renderer.rb index d8944374c..39bfc9342 100644 --- a/app/lib/redcarpet/bare_renderer.rb +++ b/app/lib/redcarpet/bare_renderer.rb @@ -33,7 +33,7 @@ module Redcarpet when :url link(link, nil, link) when :email - # NOTE: As of Redcarpet 3.6.0, autolinking email containing is broken https://github.com/vmg/redcarpet/issues/402 + # NOTE: As of Redcarpet 3.6.0, autolinking email containing underscore is broken https://github.com/vmg/redcarpet/issues/402 content_tag(:a, link, { href: "mailto:#{link}" }) else link diff --git a/app/lib/redcarpet/trusted_renderer.rb b/app/lib/redcarpet/trusted_renderer.rb new file mode 100644 index 000000000..f0ee50129 --- /dev/null +++ b/app/lib/redcarpet/trusted_renderer.rb @@ -0,0 +1,41 @@ +module Redcarpet + class TrustedRenderer < Redcarpet::Render::HTML + include ActionView::Helpers::TagHelper + include Sprockets::Rails::Helper + include ApplicationHelper + + attr_reader :view_context + + def initialize(view_context, extensions = {}) + @view_context = view_context + + super extensions + end + + def link(href, title, content) + html_options = { + href: href + } + + unless href.starts_with?('/') + html_options.merge!(title: new_tab_suffix(title), **external_link_attributes) + end + + content_tag(:a, content, html_options, false) + end + + def autolink(link, link_type) + case link_type + when :url + link(link, nil, link) + when :email + # NOTE: As of Redcarpet 3.6.0, autolinking email containing underscore is broken https://github.com/vmg/redcarpet/issues/402 + content_tag(:a, link, { href: "mailto:#{link}" }) + end + end + + def image(link, title, alt) + view_context.image_tag(link, title:, alt:, loading: :lazy) + end + end +end diff --git a/app/views/faq/show.html.haml b/app/views/faq/show.html.haml index b72b8c8f0..cca79a4f0 100644 --- a/app/views/faq/show.html.haml +++ b/app/views/faq/show.html.haml @@ -5,4 +5,5 @@ .fr-col-12.fr-col-md-4 = render partial: "sidebar", locals: { faqs: @siblings, current: @metadata } .fr-col-12.fr-col-md-8.fr-py-12v - = @renderer.render(@content).html_safe + .markdown-content + = @renderer.render(@content).html_safe diff --git a/doc/faqs/usager/je-veux-changer-mon-adresse-email.fr.md b/doc/faqs/usager/je-veux-changer-mon-adresse-email.fr.md new file mode 100644 index 000000000..eb0ab61b9 --- /dev/null +++ b/doc/faqs/usager/je-veux-changer-mon-adresse-email.fr.md @@ -0,0 +1,41 @@ + +--- +category: "usager" +subcategory: "account" +slug: "je-veux-changer-mon-adresse-email" +locale: "fr" +keywords: "adresse email, compte usager, sécurité, changement, profil" +title: "Je veux changer mon adresse email" +--- + +# Je veux changer mon adresse email + +Si vous disposez d’un compte usager sur demarches.gouv.fr, il est possible de changer l’adresse email associée à celui-ci. + +**Attention** : pour des raisons de sécurité, les comptes instructeur et administrateur sur demarches.gouv.fr doivent nous contacter à contact@demarches.gouv.fr pour demander ce changement. + +Cette adresse correspond à l’identifiant avec lequel vous vous connectez à demarches.gouv.fr. C’est également à cette adresse que nous envoyons les messages concernant l’avancement de votre dossier. + +## Changer mon adresse email + +Pour changer l’adresse email associée à votre compte, suivez les étapes suivantes : + +1. [Connectez-vous](/users/sign_in) à votre compte sur demarches.gouv.fr ; +2. Cliquez sur le menu contenant votre adresse email en haut à droite de la page, puis sur _« Voir mon profil »_, ou [suivez directement ce lien si vous êtes déjà connecté(e)](/profil). +![Menu Usager avec lien Voir mon profil](faq/usager-dropdown.png) + +3. Dans l’encadré _« Coordonnées »_, renseignez la nouvelle adresse email que vous souhaitez utiliser. Puis cliquez sur _« Changer mon adresse »_. **Attention** : Cette adresse ne doit pas être déjà utilisée par un autre compte sur demarches.gouv.fr. +![Section Coordonées avec formulaire de modification d’email](faq/usager-edit-email.png) + +4. Ouvrez la boîte email de votre nouvelle adresse, et cliquez sur le lien de confirmation que nous vous avons envoyé.
+ ![Capture d’écran de l’email de confirmation de changement d’adresse email](faq/usager-confirm-update-email.png) + +## Si l’adresse est déjà utilisée par un autre compte + +La nouvelle adresse email ne doit pas être déjà utilisée par un compte existant sur demarches.gouv.fr. + +**Si la nouvelle adresse est déjà utilisée, vous recevrez un email vous informant que le changement d’adresse ne peut pas être pris en compte.** + +Dans ce cas, revenez sur la page _« Profil »_, et choisissez une autre adresse email disponible. + +Par ailleurs, vous pouvez également transférer plusieurs dossiers depuis votre profil, cela vous permet tout de même de conserver votre compte. diff --git a/spec/lib/redcarpet/trusted_renderer_spec.rb b/spec/lib/redcarpet/trusted_renderer_spec.rb new file mode 100644 index 000000000..046472026 --- /dev/null +++ b/spec/lib/redcarpet/trusted_renderer_spec.rb @@ -0,0 +1,35 @@ +RSpec.describe Redcarpet::TrustedRenderer do + let(:view_context) { ActionController::Base.new.view_context } + subject(:renderer) { Redcarpet::Markdown.new(described_class.new(view_context), autolink: true) } + + context 'when rendering links' do + it 'renders internal links without target and rel attributes' do + markdown = "[Click here](/internal)" + expect(renderer.render(markdown)).to include('Click here') + end + + it 'renders external links with target="_blank" and rel="noopener noreferrer"' do + markdown = "[Visit](http://example.com)" + expect(renderer.render(markdown)).to include('Visit') + end + end + + context 'when rendering images' do + it 'renders an image tag with lazy loading' do + markdown = "![A cute cat](http://example.com/cat.jpg)" + expect(renderer.render(markdown)).to include('A cute cat') + end + end + + context 'when autolinking' do + it 'autolinks URLs' do + markdown = "Visit http://example.com" + expect(renderer.render(markdown)).to include('Visit http://example.com') + end + + it 'autolinks email addresses with mailto' do + markdown = "Email user@example.com" + expect(renderer.render(markdown)).to include('user@example.com') + end + end +end