From 5f26394947d1150e2656bb22c5858ae5edcdcac7 Mon Sep 17 00:00:00 2001 From: erdgeist Date: Fri, 24 Jul 2026 17:20:22 +0200 Subject: Polish the OTP flows: autocomplete tokens, button dialect, QR sizing, my-account link --- app/views/admin/index.html.erb | 3 +++ app/views/otp_challenges/new.html.erb | 2 +- app/views/otp_enrollments/show.html.erb | 17 ++++++++------ app/views/sessions/new.html.erb | 4 ++-- app/views/users/edit.html.erb | 26 ++++++++++++--------- config/initializers/filter_parameter_logging.rb | 2 +- public/stylesheets/admin.css | 30 +++++++++++++++++++++++++ 7 files changed, 63 insertions(+), 21 deletions(-) diff --git a/app/views/admin/index.html.erb b/app/views/admin/index.html.erb index 319530db..4d67dd77 100644 --- a/app/views/admin/index.html.erb +++ b/app/views/admin/index.html.erb @@ -53,6 +53,9 @@

Housekeeping

+ <%= link_to edit_user_path(current_user), class: "action_button" do %> + <%= icon("user-cog", library: "tabler", "aria-hidden": true) %> My account + <% end %> <%= link_to nodes_path, class: "action_button" do %> <%= icon("list", library: "tabler", "aria-hidden": true) %> Nodes <% end %> diff --git a/app/views/otp_challenges/new.html.erb b/app/views/otp_challenges/new.html.erb index a9c7a15c..b0d204fb 100644 --- a/app/views/otp_challenges/new.html.erb +++ b/app/views/otp_challenges/new.html.erb @@ -3,7 +3,7 @@
Code
- <%= form_tag otp_challenge_path, :method => :post do %> + <%= form_tag otp_challenge_path, :method => :post, :class => "otp_form" do %> <%= text_field_tag :code, nil, :autofocus => true, :autocomplete => "one-time-code", :inputmode => "numeric" %> <%= submit_tag "Log in" %> diff --git a/app/views/otp_enrollments/show.html.erb b/app/views/otp_enrollments/show.html.erb index 9dfa3422..90c42b59 100644 --- a/app/views/otp_enrollments/show.html.erb +++ b/app/views/otp_enrollments/show.html.erb @@ -3,19 +3,22 @@
Scan
- <%= raw RQRCode::QRCode.new(current_user.pending_otp_provisioning_uri) - .as_svg(:module_size => 4, :viewbox => true, - :color => "000", :fill => "fff") %> - Or enter the secret manually: - <%= current_user.otp_pending_secret %> +
+ <%= raw RQRCode::QRCode.new(current_user.pending_otp_provisioning_uri) + .as_svg(:module_size => 4, :viewbox => true, + :color => "000", :fill => "fff") %> +
+ Or enter the secret manually: <%= current_user.otp_pending_secret %>
Confirm
- <%= form_tag otp_enrollment_path, :method => :put do %> + <%= form_tag otp_enrollment_path, :method => :put, :class => "otp_form" do %> <%= text_field_tag :code, nil, :autofocus => true, :autocomplete => "one-time-code", :inputmode => "numeric" %> - <%= submit_tag "Confirm" %> + <%= button_tag :type => "submit", :class => "action_button" do %> + <%= icon("shield-check", library: "tabler", "aria-hidden": true) %> Confirm + <% end %> <% end %> Enter the six-digit code your app shows for “<%= OTP_ISSUER %>”. diff --git a/app/views/sessions/new.html.erb b/app/views/sessions/new.html.erb index 23952b73..b23f6a0c 100644 --- a/app/views/sessions/new.html.erb +++ b/app/views/sessions/new.html.erb @@ -5,10 +5,10 @@ <% end %>
Login
-
<%= text_field_tag 'login', @login %>
+
<%= text_field_tag 'login', @login, :autocomplete => "username" %>
Password
-
<%= password_field_tag 'password', nil %>
+
<%= password_field_tag 'password', nil, :autocomplete => "current-password" %>
<%= submit_tag 'log in' %>
<% end -%> diff --git a/app/views/users/edit.html.erb b/app/views/users/edit.html.erb index 8d14a058..8adad789 100644 --- a/app/views/users/edit.html.erb +++ b/app/views/users/edit.html.erb @@ -1,4 +1,4 @@ -

Edit existing user

+

<%= @user == current_user ? "My account" : "Edit user “#{@user.login}”" %>

<% if @user.errors.any? %>
@@ -10,16 +10,16 @@ <%= form_for @user do |f| %>
Login
-
<%= f.text_field :login %>
+
<%= f.text_field :login, :autocomplete => "username" %>
E-Mail
<%= f.text_field :email %>
Password
-
<%= f.password_field :password %>
+
<%= f.password_field :password, :autocomplete => "new-password" %>
Confirm
-
<%= f.password_field :password_confirmation %>
+
<%= f.password_field :password_confirmation, :autocomplete => "new-password" %>
<% if current_user.admin? %>
Admin?
@@ -36,17 +36,23 @@
<% if current_user.otp_enrolled? %>

Enabled.

- <%= form_tag otp_enrollment_path, :method => :delete do %> - <%= password_field_tag :current_password, nil, :placeholder => "Current password" %> + <%= form_tag otp_enrollment_path, :method => :delete, :class => "otp_form" do %> + <%= text_field_tag :login, current_user.login, :autocomplete => "username", :readonly => true, :tabindex => -1, :class => "visually_hidden" %> + <%= password_field_tag :current_password, nil, :placeholder => "Current password", :autocomplete => "current-password" %> <%= text_field_tag :code, nil, :placeholder => "Current code", :autocomplete => "one-time-code", :inputmode => "numeric" %> - <%= submit_tag "Disable second factor" %> + <%= button_tag :type => "submit", :class => "action_button" do %> + <%= icon("shield-off", library: "tabler", "aria-hidden": true) %> Disable second factor + <% end %> <% end %> <% else %>

Not enrolled.

- <%= form_tag otp_enrollment_path, :method => :post do %> - <%= password_field_tag :current_password, nil, :placeholder => "Current password" %> - <%= submit_tag "Enable second factor" %> + <%= form_tag otp_enrollment_path, :method => :post, :class => "otp_form" do %> + <%= text_field_tag :login, current_user.login, :autocomplete => "username", :readonly => true, :tabindex => -1, :class => "visually_hidden" %> + <%= password_field_tag :current_password, nil, :placeholder => "Current password", :autocomplete => "current-password"%> + <%= button_tag :type => "submit", :class => "action_button" do %> + <%= icon("shield-lock", library: "tabler", "aria-hidden": true) %> Enable second factor + <% end %> <% end %> <% end %>
diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index c0b717f7..bf72b0f3 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -4,5 +4,5 @@ # Use this to limit dissemination of sensitive information. # See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ - :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc + :passw, :email, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn, :cvv, :cvc, :code, :current_password ] diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index fe702b09..23a9a581 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css @@ -1619,3 +1619,33 @@ div#draft_list table td.actions a { max-height: 20em; overflow-y: auto; } + +/* ============================================================ + User section + ============================================================ */ + +form.otp_form { + margin-top: 0.75rem; +} + +form.otp_form input[type=password], +form.otp_form input[type=text] { + display: block; + margin-bottom: 0.5rem; +} + +.visually_hidden { + position: absolute; + width: 1px; + height: 1px; + overflow: hidden; + clip-path: inset(50%); + white-space: nowrap; +} + +.otp_qr svg { + width: 220px; + height: auto; + display: block; + margin-bottom: 0.5rem; +} -- cgit v1.3