diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 6fdbb5ad924..0633c93ae88 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -593,8 +593,27 @@ class UsersController < ApplicationController email_token_user = EmailToken.confirmable(token)&.user totp_enabled = email_token_user.totp_enabled? + second_factor_token = params[:second_factor_token] + confirm_email = false - if !totp_enabled || email_token_user.authenticate_totp(params[:second_factor_token]) + confirm_email = + if totp_enabled + @second_factor_required = true + @message = I18n.t("login.second_factor_title") + + if second_factor_token.present? + if email_token_user.authenticate_totp(second_factor_token) + true + else + @error = I18n.t("login.invalid_second_factor_code") + false + end + end + else + true + end + + if confirm_email @user = EmailToken.confirm(token) if @user && @user.admin? @@ -603,9 +622,6 @@ class UsersController < ApplicationController else @message = I18n.t("admin_login.errors.unknown_email_address") end - else - @second_factor_required = true - @message = I18n.t("login.second_factor_title") end else @message = I18n.t("admin_login.errors.invalid_token") diff --git a/app/views/users/admin_login.html.erb b/app/views/users/admin_login.html.erb index 77be764feb1..c7752523e90 100644 --- a/app/views/users/admin_login.html.erb +++ b/app/views/users/admin_login.html.erb @@ -5,12 +5,12 @@ <% if @message %> <%= @message %> - <% if @second_factor_required %> - <%=form_tag({}, method: :put) do %> - <%= label_tag(:second_factor_token, t('login.second_factor_description')) %> - <%= text_field_tag(:second_factor_token, nil, autofocus: true) %>

- <%= submit_tag t('submit')%> - <% end %> + <% if @error %>

<%= @error %>

<% end %> + + <%=form_tag({}, method: :put) do %> + <%= label_tag(:second_factor_token, t('login.second_factor_description')) %> + <%= text_field_tag(:second_factor_token, nil, autofocus: true) %>

+ <%= submit_tag t('submit')%> <% end %> <% else %> <%=form_tag({}, method: :put) do %> diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 19a324d7f4b..35f172aa04e 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -554,22 +554,35 @@ describe UsersController do describe 'when 2 factor authentication is enabled' do let(:second_factor) { Fabricate(:user_second_factor, user: admin) } + let(:email_token) { Fabricate(:email_token, user: admin) } render_views it 'does not log in when token required' do second_factor - token = admin.email_tokens.create(email: admin.email).token - get :admin_login, params: { token: token } + get :admin_login, params: { token: email_token.token } expect(response).not_to redirect_to('/') expect(session[:current_user_id]).not_to eq(admin.id) expect(response.body).to include(I18n.t('login.second_factor_description')); end - it 'logs in when a valid 2-factor token is given' do - token = admin.email_tokens.create(email: admin.email).token + describe 'invalid 2 factor token' do + it 'should display the right error' do + second_factor + put :admin_login, params: { + token: email_token.token, + second_factor_token: '13213' + } + + expect(response.status).to eq(200) + expect(response.body).to include(I18n.t('login.second_factor_description')); + expect(response.body).to include(I18n.t('login.invalid_second_factor_code')); + end + end + + it 'logs in when a valid 2-factor token is given' do put :admin_login, params: { - token: token, + token: email_token.token, second_factor_token: ROTP::TOTP.new(second_factor.data).now }