From 27bdb9833851b2ac096e6b548fffe14a77549ef9 Mon Sep 17 00:00:00 2001 From: Arnaud Levy <arnaud.levy@noesya.coop> Date: Fri, 23 Aug 2024 10:02:01 +0200 Subject: [PATCH] =?UTF-8?q?Am=C3=A9lioration=20des=20=C3=A9crans=20de=20co?= =?UTF-8?q?nnexion,=20notamment=20le=20code=20MFA=20(#2156)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix #2140 * better * climate --- Gemfile.lock | 80 +++++++------- README.md | 2 +- app/assets/stylesheets/commons/_devise.sass | 17 +++ app/assets/stylesheets/commons/_forms.sass | 5 - app/views/application/_footer.html.erb | 42 ++++---- app/views/application/_notice.html.erb | 18 ++-- app/views/devise/confirmations/new.html.erb | 25 ++--- app/views/devise/passwords/edit.html.erb | 60 +++++------ app/views/devise/passwords/new.html.erb | 25 ++--- app/views/devise/registrations/edit.html.erb | 1 - app/views/devise/registrations/new.html.erb | 2 +- app/views/devise/sessions/new.html.erb | 14 ++- .../max_login_attempts_reached.html.erb | 1 + .../two_factor_authentication/show.html.erb | 101 ++++++++++-------- app/views/devise/unlocks/new.html.erb | 22 ++-- app/views/extranet/layouts/devise.html.erb | 1 + app/views/layouts/devise.html.erb | 27 ++--- config/locales/devise.en.yml | 4 +- config/locales/devise.fr.yml | 4 +- config/locales/en.yml | 6 +- config/locales/fr.yml | 6 +- 21 files changed, 236 insertions(+), 227 deletions(-) create mode 100644 app/assets/stylesheets/commons/_devise.sass diff --git a/Gemfile.lock b/Gemfile.lock index fc5f7934c..f4f85a744 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -119,29 +119,29 @@ GEM annotate (3.2.0) activerecord (>= 3.2, < 8.0) rake (>= 10.4, < 14.0) - autoprefixer-rails (10.4.16.0) + autoprefixer-rails (10.4.19.0) execjs (~> 2) aws-eventstream (1.3.0) - aws-partitions (1.953.0) - aws-sdk-core (3.201.1) + aws-partitions (1.967.0) + aws-sdk-core (3.201.5) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) - aws-sigv4 (~> 1.8) + aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) aws-sdk-kms (1.88.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.156.0) + aws-sdk-s3 (1.159.0) aws-sdk-core (~> 3, >= 3.201.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sigv4 (1.8.0) + aws-sigv4 (1.9.1) aws-eventstream (~> 1, >= 1.0.2) base64 (0.2.0) bcrypt (3.1.20) bigdecimal (3.1.8) bindex (0.8.1) - bootsnap (1.18.3) + bootsnap (1.18.4) msgpack (~> 1.2) bootstrap (5.3.3) autoprefixer-rails (>= 9.1.0) @@ -179,7 +179,7 @@ GEM citeproc (~> 1.0, >= 1.0.9) csl (~> 2.0) cocoon (1.2.15) - concurrent-ruby (1.3.3) + concurrent-ruby (1.3.4) connection_pool (2.4.1) countries (6.0.1) unaccent (~> 0.3) @@ -209,7 +209,7 @@ GEM warden (~> 1.2.3) devise-i18n (1.12.1) devise (>= 4.9.0) - docile (1.4.0) + docile (1.4.1) domain_name (0.6.20240107) drb (2.2.1) encryptor (3.0.0) @@ -224,13 +224,13 @@ GEM faceted_search (3.6.2) font-awesome-sass rails (>= 5.2.0) - faraday (2.10.0) + faraday (2.10.1) faraday-net_http (>= 2.0, < 3.2) logger faraday-cookie_jar (0.0.7) faraday (>= 0.8.0) http-cookie (~> 1.0.0) - faraday-encoding (0.0.5) + faraday-encoding (0.0.6) faraday faraday-follow_redirects (0.3.0) faraday (>= 1, < 3) @@ -241,7 +241,7 @@ GEM faraday (>= 0.8) faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (3.1.0) + faraday-net_http (3.1.1) net-http faraday-retry (2.2.1) faraday (~> 2.0) @@ -254,7 +254,7 @@ GEM font-awesome-sass (6.5.2) sassc (~> 2.0) front_matter_parser (1.0.1) - fugit (1.11.0) + fugit (1.11.1) et-orbi (~> 1, >= 1.2.11) raabro (~> 1.4) geo_calc (0.7.8) @@ -279,20 +279,20 @@ GEM terminal-table (>= 1.5.1) globalid (1.2.1) activesupport (>= 6.1) - good_job (4.0.2) + good_job (4.2.0) activejob (>= 6.1.0) activerecord (>= 6.1.0) concurrent-ruby (>= 1.3.1) fugit (>= 1.11.0) railties (>= 6.1.0) thor (>= 1.0.0) - google-protobuf (4.27.2-arm64-darwin) + google-protobuf (4.27.3-arm64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.27.2-x86_64-darwin) + google-protobuf (4.27.3-x86_64-darwin) bigdecimal rake (>= 13) - google-protobuf (4.27.2-x86_64-linux) + google-protobuf (4.27.3-x86_64-linux) bigdecimal rake (>= 13) hal_openscience (0.1.0) @@ -303,10 +303,10 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) hash_dot (2.5.0) - hashdiff (1.1.0) + hashdiff (1.1.1) hashie (5.0.0) htmlentities (4.3.4) - http-cookie (1.0.6) + http-cookie (1.0.7) domain_name (~> 0.5) httparty (0.22.0) csv @@ -319,7 +319,7 @@ GEM i18n_date_range (2.1.2) rails rails-i18n - image_processing (1.12.2) + image_processing (1.13.0) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) io-console (0.7.2) @@ -337,7 +337,7 @@ GEM json (2.7.2) jwt (2.8.2) base64 - kamifusen (1.11.2) + kamifusen (1.12.0) image_processing rails kaminari (1.2.2) @@ -352,7 +352,7 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - leaflet-rails (1.9.4) + leaflet-rails (1.9.5) actionpack (>= 4.2.0) railties (>= 4.2.0) libretranslate (0.1.0) @@ -387,7 +387,7 @@ GEM nokogiri (~> 1.13) mini_magick (4.13.2) mini_mime (1.1.5) - minitest (5.24.1) + minitest (5.25.1) msgpack (1.7.2) multi_xml (0.7.1) bigdecimal (~> 3.1) @@ -408,11 +408,11 @@ GEM net-smtp (0.5.0) net-protocol nio4r (2.7.3) - nokogiri (1.16.6-arm64-darwin) + nokogiri (1.16.7-arm64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-darwin) + nokogiri (1.16.7-x86_64-darwin) racc (~> 1.4) - nokogiri (1.16.6-x86_64-linux) + nokogiri (1.16.7-x86_64-linux) racc (~> 1.4) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) @@ -442,20 +442,20 @@ GEM orm_adapter (0.5.0) pexels (0.5.0) requests (~> 1.0.2) - pg (1.5.6) + pg (1.5.7) pg_query (5.1.0) google-protobuf (>= 3.22.3) - pghero (3.5.0) - activerecord (>= 6) + pghero (3.6.0) + activerecord (>= 6.1) popper_js (2.11.8) psych (5.1.2) stringio - public_suffix (6.0.0) + public_suffix (6.0.1) puma (6.4.2) nio4r (~> 2.0) raabro (1.4.0) - racc (1.8.0) - rack (3.1.6) + racc (1.8.1) + rack (3.1.7) rack-mini-profiler (2.3.4) rack (>= 1.2.0) rack-protection (4.0.0) @@ -511,7 +511,7 @@ GEM ffi rdoc (6.7.0) psych (>= 4.0.0) - redis (5.2.0) + redis (5.3.0) redis-client (>= 0.22.0) redis-client (0.22.2) connection_pool @@ -523,7 +523,7 @@ GEM responders (3.1.1) actionpack (>= 5.2) railties (>= 5.2) - rexml (3.3.1) + rexml (3.3.6) strscan roo (2.10.1) nokogiri (~> 1) @@ -532,10 +532,11 @@ GEM ruby-saml (1.16.0) nokogiri (>= 1.13.10) rexml - ruby-vips (2.2.1) + ruby-vips (2.2.2) ffi (~> 1.12) + logger rubyzip (2.3.2) - sanitize (6.1.1) + sanitize (6.1.3) crass (~> 1.0.2) nokogiri (>= 1.12.0) sassc (2.4.0) @@ -584,7 +585,7 @@ GEM sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) - sprockets-rails (3.5.1) + sprockets-rails (3.5.2) actionpack (>= 6.1) activesupport (>= 6.1) sprockets (>= 3.0.0) @@ -614,7 +615,8 @@ GEM httparty (~> 0.20) oauth2 (>= 2.0.8) uri (0.13.0) - vcr (6.2.0) + vcr (6.3.1) + base64 version_gem (1.1.4) warden (1.2.9) rack (>= 2.0.9) @@ -638,7 +640,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.16) + zeitwerk (2.6.17) zlib (2.1.1) PLATFORMS diff --git a/README.md b/README.md index 28f9f9968..c69f6bf7b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # Osuny -Un commun numérique libre, sobre et accessible pour l'Enseignement Supérieur et la Recherche +[osuny.org](https://www.osuny.org) [](https://codeclimate.com/github/osunyorg/admin/maintainability) diff --git a/app/assets/stylesheets/commons/_devise.sass b/app/assets/stylesheets/commons/_devise.sass new file mode 100644 index 000000000..7e06cd960 --- /dev/null +++ b/app/assets/stylesheets/commons/_devise.sass @@ -0,0 +1,17 @@ +.layout-devise + display: flex + flex-direction: column + justify-content: space-between + min-height: 100vh + header + padding: 100px 0 + text-align: center + main + flex-grow: 1 + min-height: auto + footer + min-height: auto + .mfa-code + font-size: pxToRem(26) + @include media-breakpoint-up(lg) + font-size: pxToRem(32) diff --git a/app/assets/stylesheets/commons/_forms.sass b/app/assets/stylesheets/commons/_forms.sass index 2112cc485..900ce5936 100644 --- a/app/assets/stylesheets/commons/_forms.sass +++ b/app/assets/stylesheets/commons/_forms.sass @@ -23,11 +23,6 @@ textarea.form-control padding: 8px padding-top: 0 // Compensation de la hauteur des lignes -.mfa-code - font-size: pxToRem(30) !important - @include media-breakpoint-up(lg) - font-size: pxToRem(40) !important - .visibility_radio_buttons .form-check-items display: flex diff --git a/app/views/application/_footer.html.erb b/app/views/application/_footer.html.erb index abd05f1f8..85713a57f 100644 --- a/app/views/application/_footer.html.erb +++ b/app/views/application/_footer.html.erb @@ -1,24 +1,22 @@ -<footer class="mt-5 pt-5"> - <div class="container"> - <div class="mb-5 text-lg-center"> - <%= image_tag 'osuny-black.svg', width: 80 %> +<footer class="bg-black text-white py-5"> + <div class="container-fluid"> + <div class="d-md-flex justify-content-between mt-5 pt-5"> + <%= link_to 'https://www.osuny.org', target: :_blank, class: 'text-white-50' do %> + <%= t('admin.footer.signature') %> + <% end %> + <ul class="list-unstyled d-md-flex"> + <% + [ + ['Aide à la contribution', 'https://support.osuny.org'], + [t('terms_of_service'), t('terms_of_service_url')], + ['Statut', 'https://status.osuny.org'], + ].each do |item| + %> + <li> + <%= link_to item.first, item.last, target: :_blank, class: 'text-white-50' %> + </li> + <% end %> + </ul> </div> - <nav class="nav small d-block d-lg-flex justify-content-lg-center"> - <%= link_to t('terms_of_service'), - t('terms_of_service_url'), - class: 'nav-link ps-0', - target: '_blank', - rel: 'noreferrer' %> - <%= link_to t('privacy_policy'), - t('privacy_policy_url'), - class: 'nav-link ps-0', - target: '_blank', - rel: 'noreferrer' %> - <%= link_to t('cookies_policy'), - t('cookies_policy_url'), - class: 'nav-link ps-0', - target: '_blank', - rel: 'noreferrer' %> - </nav> </div> -</footer> +</footer> \ No newline at end of file diff --git a/app/views/application/_notice.html.erb b/app/views/application/_notice.html.erb index 3b4ff192c..0dad5bc23 100644 --- a/app/views/application/_notice.html.erb +++ b/app/views/application/_notice.html.erb @@ -1,12 +1,6 @@ -<div class="toasts-container" style="position: fixed; top: 20px; right: 20px; z-index: 100000;"> - <% unless notice.nil? %> - <div class="js-notyf-notice d-none"> - <%= notice %> - </div> - <% end %> - <% unless alert.nil? %> - <div class="js-notyf-alert d-none"> - <%= alert %> - </div> - <% end %> -</div> \ No newline at end of file +<% unless notice.blank? %> + <div class="alert alert-success mt-2" role="alert"><%= notice.html_safe %></div> +<% end %> +<% unless alert.blank? %> + <div class="alert alert-danger mt-2" role="alert"><%= alert.html_safe %></div> +<% end %> \ No newline at end of file diff --git a/app/views/devise/confirmations/new.html.erb b/app/views/devise/confirmations/new.html.erb index 4d24f697b..13c1166c5 100644 --- a/app/views/devise/confirmations/new.html.erb +++ b/app/views/devise/confirmations/new.html.erb @@ -1,21 +1,16 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> -<h2 class="mb-4"><%= t(".resend_confirmation_instructions") %></h2> - +<h1 class="h4 mb-4"><%= t(".resend_confirmation_instructions") %></h1> <%= simple_form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> <%= f.error_notification %> <%= f.full_error :confirmation_token %> - <div class="row"> - <div class="col-md-6"> - <%= f.input :email, - required: true, - autofocus: true, - value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), - input_html: { autocomplete: "email" } %> - </div> - <div class="col-md-6"> - <label class="form-label"> </label><br> - <%= f.button :submit, t(".resend_confirmation_instructions"), class: 'btn btn-primary' %> - </div> - </div> + <%= f.input :email, + required: true, + placeholder: User.human_attribute_name(:email), + autofocus: true, + label: false, + value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email), + input_html: { autocomplete: "email" } %> + <%= f.button :submit, t(".resend_confirmation_instructions"), class: 'btn btn-primary' %> <% end %> diff --git a/app/views/devise/passwords/edit.html.erb b/app/views/devise/passwords/edit.html.erb index 44071e8c9..4dd136439 100644 --- a/app/views/devise/passwords/edit.html.erb +++ b/app/views/devise/passwords/edit.html.erb @@ -1,41 +1,31 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> -<h2 class="mb-4"><%= t(".change_your_password") %></h2> - +<h1 class="h4 mb-4"><%= t(".change_your_password") %></h1> <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %> <%= f.error_notification %> - <%= f.input :reset_password_token, as: :hidden %> <%= f.full_error :reset_password_token %> - - <div class="row"> - <div class="col-md-6"> - <%= f.input :password, - as: :password_with_hints, - label: t(".new_password"), - required: true, - autofocus: true, - allow_password_uncloaking: true, - validators: { - length: Devise.password_length.first, - uppercase_char: true, - lowercase_char: true, - numeric_char: true, - special_char: Rails.application.config.allowed_special_chars - }, - input_html: { autocomplete: "new-password" } %> - </div> - <div class="col-md-6"> - <%= f.input :password_confirmation, - as: :password_with_sync, - label: t(".confirm_new_password"), - required: true, - allow_password_uncloaking: true, - compare_with_field: :password, - input_html: { autocomplete: "new-password" } %> - </div> - <div class="col-md-6"> - <%= f.button :submit, t(".change_my_password"), class: 'btn btn-primary' %> - </div> - </div> -<% end %> + <%= f.input :password, + as: :password_with_hints, + label: t(".new_password"), + required: true, + autofocus: true, + allow_password_uncloaking: true, + validators: { + length: Devise.password_length.first, + uppercase_char: true, + lowercase_char: true, + numeric_char: true, + special_char: Rails.application.config.allowed_special_chars + }, + input_html: { autocomplete: "new-password" } %> + <%= f.input :password_confirmation, + as: :password_with_sync, + label: t(".confirm_new_password"), + required: true, + allow_password_uncloaking: true, + compare_with_field: :password, + input_html: { autocomplete: "new-password" } %> + <%= f.button :submit, t(".change_my_password"), class: 'btn btn-primary' %> +<% end %> \ No newline at end of file diff --git a/app/views/devise/passwords/new.html.erb b/app/views/devise/passwords/new.html.erb index 0a10d6323..a96e5866d 100644 --- a/app/views/devise/passwords/new.html.erb +++ b/app/views/devise/passwords/new.html.erb @@ -1,20 +1,15 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> -<h2 class="mb-4"><%= t(".forgot_your_password") %></h2> +<h1 class="h4 mb-4"><%= t(".forgot_your_password") %></h1> <%= simple_form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %> <%= f.error_notification %> - - <div class="row"> - <div class="col-md-6"> - <%= f.input :email, - required: true, - autofocus: true, - input_html: { autocomplete: "email" } %> - </div> - <div class="col-md-6"> - <label class="form-label"> </label><br> - <%= f.button :submit, t(".send_me_reset_password_instructions"), class: 'btn btn-primary' %> - </div> - </div> -<% end %> + <%= f.input :email, + required: true, + autofocus: true, + placeholder: User.human_attribute_name(:email), + label: false, + input_html: { autocomplete: "email" } %> + <%= f.button :submit, t(".send_me_reset_password_instructions"), class: 'btn btn-primary' %> +<% end %> \ No newline at end of file diff --git a/app/views/devise/registrations/edit.html.erb b/app/views/devise/registrations/edit.html.erb index 468f4f049..49e681395 100644 --- a/app/views/devise/registrations/edit.html.erb +++ b/app/views/devise/registrations/edit.html.erb @@ -16,7 +16,6 @@ <%= render 'admin/application/i18n/form', f: f %> </div> <div class="col-lg-6"> - <%= f.input :mobile_phone %> <%= f.input :picture, as: :single_deletable_file, diff --git a/app/views/devise/registrations/new.html.erb b/app/views/devise/registrations/new.html.erb index 0617c8886..6da918858 100644 --- a/app/views/devise/registrations/new.html.erb +++ b/app/views/devise/registrations/new.html.erb @@ -1,6 +1,6 @@ <%= content_for :title, t('.title', title: current_extranet.present? ? current_extranet.name : 'Osuny') %> -<h2 class="mb-4"><%= t(".sign_up") %></h2> +<h1 class="h4 mb-4"><%= t(".sign_up") %></h1> <%= simple_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %> <%= f.error_notification %> diff --git a/app/views/devise/sessions/new.html.erb b/app/views/devise/sessions/new.html.erb index afd0b0b68..c725701c7 100644 --- a/app/views/devise/sessions/new.html.erb +++ b/app/views/devise/sessions/new.html.erb @@ -1,8 +1,12 @@ <%= content_for :title, t('.title', title: current_extranet.present? ? current_extranet.name : 'Osuny') %> +<h1 class="h4 d-none"> + <%= t('.title', title: current_extranet.present? ? current_extranet.name : 'Osuny') %> +</h1> <div class="row"> - <div class="col-md-6 mb-5"> - <h2 class="mb-4"><%= t('login.already_registered') %></h2> + <div class="col-lg-6 mb-5"> + <h2 class="h4 mb-4"><%= t('login.already_registered') %></h2> + <p><%= t('login.already_registered_details') %></p> <% if current_context.has_sso? %> <% button_label = current_context.sso_button_label.blank? ? t('login.sign_in_with_sso') : current_context.sso_button_label %> <p><%= link_to button_label, omniauth_authorize_path(resource_name, current_context.sso_provider), method: :post, class: 'btn btn-primary' %></p> @@ -38,7 +42,7 @@ </div> <% end %> </div> - <div class="mt-3"> + <div class="mt-3 small"> <% if devise_mapping.confirmable? %> <%= link_to t('devise.shared.links.didn_t_receive_confirmation_instructions'), new_confirmation_path(resource_name) %><br /> <% end %> @@ -48,8 +52,8 @@ <% end %> </div> </div> - <div class="col-md-6"> - <h2 class="mb-4"><%= t('login.not_registered_yet') %></h2> + <div class="col-lg-6"> + <h2 class="h4 mb-4"><%= t('login.not_registered_yet') %></h2> <p><%= t('login.not_registered_yet_details') %></p> <div class="form-actions"> <%= link_to t("devise.registrations.new.sign_up"), diff --git a/app/views/devise/two_factor_authentication/max_login_attempts_reached.html.erb b/app/views/devise/two_factor_authentication/max_login_attempts_reached.html.erb index 5e9459518..637515a4f 100644 --- a/app/views/devise/two_factor_authentication/max_login_attempts_reached.html.erb +++ b/app/views/devise/two_factor_authentication/max_login_attempts_reached.html.erb @@ -1,4 +1,5 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> <div class="alert alert-danger" role="alert"> <%= t('devise.two_factor_authentication.max_login_attempts_reached').html_safe %> diff --git a/app/views/devise/two_factor_authentication/show.html.erb b/app/views/devise/two_factor_authentication/show.html.erb index e743ba9f3..05dd72c73 100644 --- a/app/views/devise/two_factor_authentication/show.html.erb +++ b/app/views/devise/two_factor_authentication/show.html.erb @@ -1,50 +1,65 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> -<div class="text-lg-center"> - <h1 class="h4 mb-5"><%= t('.title') %></h1> +<h1 class="h4 mb-4"><%= t('.title') %></h1> - <p> - <% if resource.direct_otp %> - <% if resource.direct_otp_delivery_method == 'mobile_phone' %> - <%= t('devise.two_factor_authentication.enter_code_direct_otp_mobile_phone', phone: masked_phone(resource.mobile_phone)) %> - <% else %> - <%= t('devise.two_factor_authentication.enter_code_direct_otp_email', mail: masked_email(resource.email)) %> - <% end %> +<p class="mb-4"> + <% if resource.direct_otp %> + <% if resource.direct_otp_delivery_method == 'mobile_phone' %> + <%= t('devise.two_factor_authentication.enter_code_direct_otp_mobile_phone_html', phone: masked_phone(resource.mobile_phone)) %> <% else %> - <%= t('devise.two_factor_authentication.enter_code_totp') %> + <%= t('devise.two_factor_authentication.enter_code_direct_otp_email_html', mail: masked_email(resource.email)) %> <% end %> - </p> - - <%= simple_form_for(resource, url: user_two_factor_authentication_path, html: { method: :put, class: 'my-3' }) do |f| %> - <div class="form-inputs"> - <div class="input-group required mx-lg-auto mt-0" style="max-width: 220px"> - <%= text_field_tag :code, - '', - type: 'tel', - pattern: '\d*', - required: true, - autofocus: true, - autocomplete: 'off', - class: 'form-control form-control-lg mfa-code text-lg-center string required'%> - </div> - <%= f.button :submit, - t('devise.two_factor_authentication.validate'), - class: "btn btn-primary mt-2" %> - <p class="mt-4 mb-5"> - <% if resource.direct_otp %> - <%= link_to t('devise.two_factor_authentication.resend_code'), [:resend_code, resource_name, :two_factor_authentication] %> - <% else %> - <%= link_to t('devise.two_factor_authentication.send_code_instead'), [:resend_code, resource_name, :two_factor_authentication] %> - <% end %> - <% unless resource.mobile_phone.blank? # when phone is blank default code method is already :email so we don't need another link %> - • <%= link_to t('devise.two_factor_authentication.send_email_code'), [:resend_code, resource_name, :two_factor_authentication, delivery_method: :email] %> - <% end %> - </p> - </div> + <% else %> + <%= t('devise.two_factor_authentication.enter_code_totp') %> <% end %> +</p> - <%= link_to t('devise.shared.links.sign_out'), - destroy_user_session_path, - method: :delete, - class: "btn btn-outline-danger" %> -</div> \ No newline at end of file +<%= simple_form_for(resource, url: user_two_factor_authentication_path, html: { method: :put }) do |f| %> + <div class="form-inputs"> + <div class="input-group"> + <input type="tel" + name="code" + id="code" + value="" + pattern="\d*" + required="required" + autofocus="autofocus" + autocomplete="off" + style="letter-spacing: 1rem" + placeholder="______" + class="form-control form-control-lg mfa-code string required"> + <input type="submit" + name="commit" + value="<%= t('devise.two_factor_authentication.validate') %>" + class="btn btn-dark bg-black px-3 px-lg-5" + data-disable-with="<%= t('devise.two_factor_authentication.validate') %>"> + </div> + </div> +<% end %> +<div class="my-5 pt-5 small"> + <p class="mb-2"> + <%= t('devise.two_factor_authentication.help') %> + </p> + <ul class="list-unstyled"> + <li class="d-lg-inline-block"> + <% key = resource.direct_otp ? 'resend_code' : 'send_code_instead' %> + <%= link_to t("devise.two_factor_authentication.#{key}"), + [:resend_code, resource_name, :two_factor_authentication], + class: 'd-block pe-3 py-3' %> + </li> + <% unless resource.mobile_phone.blank? # when phone is blank default code method is already :email so we don't need another link %> + <li class="d-lg-inline-block"> + <%= link_to t('devise.two_factor_authentication.send_email_code'), + [:resend_code, resource_name, :two_factor_authentication, delivery_method: :email], + class: 'd-block pe-2 py-2' %> + </li> + <% end %> + <li class="d-lg-inline-block "> + <%= link_to t('devise.shared.links.sign_out'), + destroy_user_session_path, + method: :delete, + class: 'd-block pe-2 py-2' %> + </li> + </ul> +</div> diff --git a/app/views/devise/unlocks/new.html.erb b/app/views/devise/unlocks/new.html.erb index 1035f065a..dd31c15ad 100644 --- a/app/views/devise/unlocks/new.html.erb +++ b/app/views/devise/unlocks/new.html.erb @@ -1,20 +1,16 @@ <%= content_for :title, t('.title') %> +<% @small_content = true %> -<h2 class="mb-4"><%= t(".resend_unlock_instructions") %></h2> +<h1 class="h4 mb-4"><%= t(".resend_unlock_instructions") %></h1> <%= simple_form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> <%= f.error_notification %> <%= f.full_error :unlock_token %> - <div class="row"> - <div class="col-md-6"> - <%= f.input :email, - required: true, - autofocus: true, - input_html: { autocomplete: "email" } %> - </div> - <div class="col-md-6"> - <label class="form-label"> </label><br> - <%= f.button :submit, t(".resend_unlock_instructions"), class: 'btn btn-primary' %> - </div> - </div> + <%= f.input :email, + placeholder: User.human_attribute_name(:email), + label: false, + required: true, + autofocus: true, + input_html: { autocomplete: "email" } %> + <%= f.button :submit, t(".resend_unlock_instructions"), class: 'btn btn-primary' %> <% end %> diff --git a/app/views/extranet/layouts/devise.html.erb b/app/views/extranet/layouts/devise.html.erb index 69ff30bdc..c7e0f4dd3 100644 --- a/app/views/extranet/layouts/devise.html.erb +++ b/app/views/extranet/layouts/devise.html.erb @@ -24,6 +24,7 @@ <%= link_to t('terms_of_service'), terms_path, rel: 'noreferrer' if current_extranet.has_terms? %> <%= link_to t('privacy_policy'), privacy_policy_path, rel: 'noreferrer' if current_extranet.has_privacy_policy? %> <%= link_to t('cookies_policy'), cookies_policy_path, rel: 'noreferrer' if current_extranet.has_cookies_policy? %> + </nav> </footer> </div> </div> diff --git a/app/views/layouts/devise.html.erb b/app/views/layouts/devise.html.erb index 9e7d9b5f2..41244ffcd 100644 --- a/app/views/layouts/devise.html.erb +++ b/app/views/layouts/devise.html.erb @@ -10,21 +10,24 @@ <%= javascript_include_tag 'devise' %> <%= favicon_link_tag 'favicon.png' %> </head> - <body class="<%= body_classes %>"> - <div class="container"> - <h1 class="my-5 py-5 text-center"> - <%= link_to root_path do %> - <%= render 'logo' %> - <% end %> - </h1> - <% unless notice.blank? %> - <div class="alert alert-success mt-2" role="alert"><%= notice.html_safe %></div> + <body class="layout-devise <%= body_classes %>"> + <header> + <%= link_to root_path do %> + <%= render 'logo' %> <% end %> - <% unless alert.blank? %> - <div class="alert alert-danger mt-2" role="alert"><%= alert.html_safe %></div> + </header> + <main class="container-fluid"> + <% if @small_content %> + <div class="row"> + <div class="offset-md-2 col-md-8 offset-lg-3 col-lg-6 offset-xxl-4 col-xxl-4"> <% end %> + <%= render 'notice' %> <%= yield %> - </div> + <% if @small_content %> + </div> + </div> + <% end %> + </main> <%= render 'footer' %> <%= render 'bugsnag' %> </body> diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index e623f762d..b7e6c046d 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -12,10 +12,10 @@ en: edit: title: Account edition new: - title: "Register - %{title}" + title: "Register on %{title}" sessions: new: - title: "Welcome - %{title}" + title: "Welcome to %{title}" two_factor_authentication: max_login_attempts_reached: title: Maximul login attemps reached diff --git a/config/locales/devise.fr.yml b/config/locales/devise.fr.yml index 193656edf..e0f0196f1 100644 --- a/config/locales/devise.fr.yml +++ b/config/locales/devise.fr.yml @@ -12,10 +12,10 @@ fr: edit: title: Modification de votre compte new: - title: "Inscription - %{title}" + title: "Inscription sur %{title}" sessions: new: - title: "Bienvenue - %{title}" + title: "Bienvenue sur %{title}" two_factor_authentication: max_login_attempts_reached: title: Maximum d'essais atteint diff --git a/config/locales/en.yml b/config/locales/en.yml index ce31f8767..9c83ecd5a 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -205,9 +205,10 @@ en: admin_unlock: Unlock it now! attempt_failed: "Invalid Code" code_has_been_sent: "Your authentication code has been sent." - enter_code_direct_otp_email: "Enter the code that was sent to you on your email %{mail}" - enter_code_direct_otp_mobile_phone: "Enter the code that was sent to you on your mobile phone %{phone}" + enter_code_direct_otp_email_html: "To ensure a secure connection, we will send you a 6-digit, one-time code to your e-mail address %{mail}. Enter the code below." + enter_code_direct_otp_mobile_phone_html: "To ensure a secure connection, we will send you a 6-digit, one-time code to your mobile phone %{phone}. Enter the code below." enter_code_totp: "Enter the code from your authentication application" + help: "If you have a problem, you can..." max_login_attempts_reached: "You're account has been locked for security reasons.<br />Please contact an administrator." resend_code: "Resend Code" send_code_instead: "Send me a code instead" @@ -272,6 +273,7 @@ en: loading: Loading... login: already_registered: Already registered? + already_registered_details: Sign in if you already have an account. not_registered_yet: Not registered yet? not_registered_yet_details: Register if you have no account yet. or: or diff --git a/config/locales/fr.yml b/config/locales/fr.yml index 5c1d080f8..7ce90e599 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -205,9 +205,10 @@ fr: admin_unlock: Le débloquer ! attempt_failed: "Code invalide" code_has_been_sent: "Un code d'authentification vient de vous être envoyé." - enter_code_direct_otp_email: "Entrez le code qui vous a été envoyé sur votre mail %{mail}" - enter_code_direct_otp_mobile_phone: "Entrez le code qui vous a été envoyé sur votre mobile %{phone}" + enter_code_direct_otp_email_html: "Pour assurer la sécurité de votre connexion, nous vous envoyons un code à  6 chiffres, à usage unique, sur votre mail %{mail}. Entrez ce code ci-dessous." + enter_code_direct_otp_mobile_phone_html: "Pour assurer la sécurité de votre connexion, nous vous envoyons un code à  6 chiffres, à usage unique, sur votre mobile %{phone}. Entrez ce code ci-dessous." enter_code_totp: "Entrez le code de votre application d'authentification" + help: "Si vous rencontrez un problème, vous pouvez..." max_login_attempts_reached: "Votre compte a été bloqué pour des raisons de sécurité.<br />Veuillez contacter un administrateur." resend_code: "Renvoyer le code" send_code_instead: "Envoyez-moi plutôt un code" @@ -272,6 +273,7 @@ fr: loading: Chargement... login: already_registered: Déjà inscrit ? + already_registered_details: Connectez-vous si vous avez déjà un compte. not_registered_yet: Pas encore inscrit ? not_registered_yet_details: Inscrivez-vous si vous n'avez pas encore de compte. or: ou bien -- GitLab