From 9e399b42b96f115a8367c368862d62aeecfac680 Mon Sep 17 00:00:00 2001 From: Martin Brennan Date: Mon, 13 Jan 2020 12:10:07 +1000 Subject: [PATCH] DEV: Remove redundant admin_login route, share with email_login --- .../admin-login/admin-login.js.es6 | 46 ------- .../admin-login/admin-login.no-module.js.es6 | 1 - app/controllers/session_controller.rb | 13 +- app/controllers/users_controller.rb | 77 ----------- app/views/users/admin_login.html.erb | 53 +------- config/locales/server.ca.yml | 2 +- config/locales/server.de.yml | 2 +- config/locales/server.el.yml | 2 +- config/locales/server.en.yml | 2 +- config/locales/server.es.yml | 2 +- config/locales/server.fa_IR.yml | 2 +- config/locales/server.fi.yml | 2 +- config/locales/server.fr.yml | 2 +- config/locales/server.he.yml | 2 +- config/locales/server.hy.yml | 2 +- config/locales/server.it.yml | 2 +- config/locales/server.pl_PL.yml | 2 +- config/locales/server.pt_BR.yml | 2 +- config/locales/server.sl.yml | 2 +- config/locales/server.ur.yml | 2 +- config/locales/server.zh_CN.yml | 2 +- config/locales/server.zh_TW.yml | 2 +- config/routes.rb | 2 - spec/requests/session_controller_spec.rb | 27 ++++ spec/requests/users_controller_spec.rb | 120 ------------------ 25 files changed, 55 insertions(+), 318 deletions(-) delete mode 100644 app/assets/javascripts/admin-login/admin-login.js.es6 delete mode 100644 app/assets/javascripts/admin-login/admin-login.no-module.js.es6 diff --git a/app/assets/javascripts/admin-login/admin-login.js.es6 b/app/assets/javascripts/admin-login/admin-login.js.es6 deleted file mode 100644 index e7404b386ad..00000000000 --- a/app/assets/javascripts/admin-login/admin-login.js.es6 +++ /dev/null @@ -1,46 +0,0 @@ -import { getWebauthnCredential } from "discourse/lib/webauthn"; - -export default function() { - document.getElementById( - "activate-security-key-alternative" - ).onclick = function() { - document.getElementById("second-factor-forms").style.display = "block"; - document.getElementById("primary-security-key-form").style.display = "none"; - }; - - document.getElementById("submit-security-key").onclick = function(e) { - e.preventDefault(); - getWebauthnCredential( - document.getElementById("security-key-challenge").value, - document - .getElementById("security-key-allowed-credential-ids") - .value.split(","), - credentialData => { - document.getElementById( - "security-key-credential" - ).value = JSON.stringify(credentialData); - e.target.parentElement.submit(); - }, - errorMessage => { - document.getElementById("security-key-error").innerText = errorMessage; - } - ); - }; - - const useTotp = I18n.t("login.second_factor_toggle.totp"); - const useBackup = I18n.t("login.second_factor_toggle.backup_code"); - const backupForm = document.getElementById("backup-second-factor-form"); - const primaryForm = document.getElementById("primary-second-factor-form"); - document.getElementById("toggle-form").onclick = function(event) { - event.preventDefault(); - if (backupForm.style.display === "none") { - backupForm.style.display = "block"; - primaryForm.style.display = "none"; - document.getElementById("toggle-form").innerHTML = useTotp; - } else { - backupForm.style.display = "none"; - primaryForm.style.display = "block"; - document.getElementById("toggle-form").innerHTML = useBackup; - } - }; -} diff --git a/app/assets/javascripts/admin-login/admin-login.no-module.js.es6 b/app/assets/javascripts/admin-login/admin-login.no-module.js.es6 deleted file mode 100644 index 4de268433dc..00000000000 --- a/app/assets/javascripts/admin-login/admin-login.no-module.js.es6 +++ /dev/null @@ -1 +0,0 @@ -require("admin-login/admin-login").default(); diff --git a/app/controllers/session_controller.rb b/app/controllers/session_controller.rb index b7a3fcba170..442ca7cb6d2 100644 --- a/app/controllers/session_controller.rb +++ b/app/controllers/session_controller.rb @@ -345,11 +345,14 @@ class SessionController < ApplicationController end def email_login_info - raise Discourse::NotFound if !SiteSetting.enable_local_logins_via_email - token = params[:token] matched_token = EmailToken.confirmable(token) + if !SiteSetting.enable_local_logins_via_email && + !matched_token.user.admin? # admin-login uses this route, so allow them even if disabled + raise Discourse::NotFound + end + if matched_token response = { can_login: true, @@ -382,13 +385,17 @@ class SessionController < ApplicationController end def email_login - raise Discourse::NotFound if !SiteSetting.enable_local_logins_via_email second_factor_token = params[:second_factor_token] second_factor_method = params[:second_factor_method].to_i security_key_credential = params[:security_key_credential] token = params[:token] matched_token = EmailToken.confirmable(token) + if !SiteSetting.enable_local_logins_via_email && + !matched_token&.user&.admin? # admin-login uses this route, so allow them even if disabled + raise Discourse::NotFound + end + if security_key_credential.present? if matched_token&.user&.security_keys_enabled? security_key_valid = ::Webauthn::SecurityKeyAuthenticationService.new( diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index b4a65154323..da4b6a19bc8 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -684,89 +684,12 @@ class UsersController < ApplicationController else @message = I18n.t("admin_login.errors.unknown_email_address") end - elsif (token = params[:token]).present? - valid_token = EmailToken.valid_token_format?(token) - - if valid_token - if params[:second_factor_token].present? - RateLimiter.new(nil, "second-factor-min-#{request.remote_ip}", 3, 1.minute).performed! - end - - email_token_user = EmailToken.confirmable(token)&.user - totp_enabled = email_token_user&.totp_enabled? - security_keys_enabled = email_token_user&.security_keys_enabled? - second_factor_token = params[:second_factor_token] - second_factor_method = params[:second_factor_method].to_i - confirm_email = false - @security_key_required = security_keys_enabled - - if security_keys_enabled && params[:security_key_credential].blank? - Webauthn.stage_challenge(email_token_user, secure_session) - challenge_and_credentials = Webauthn.allowed_credentials(email_token_user, secure_session) - @security_key_challenge = challenge_and_credentials[:challenge] - @security_key_allowed_credential_ids = challenge_and_credentials[:allowed_credential_ids].join(",") - end - - if security_keys_enabled && params[:security_key_credential].present? - credential = JSON.parse(params[:security_key_credential]).with_indifferent_access - - confirm_email = ::Webauthn::SecurityKeyAuthenticationService.new( - email_token_user, - credential, - challenge: Webauthn.challenge(email_token_user, secure_session), - rp_id: Webauthn.rp_id(email_token_user, secure_session), - origin: Discourse.base_url - ).authenticate_security_key - @message = I18n.t('login.security_key_invalid') if !confirm_email - elsif security_keys_enabled && second_factor_token.blank? - confirm_email = false - @message = I18n.t("login.second_factor_title") - if totp_enabled - @second_factor_required = true - @backup_codes_enabled = true - end - else - confirm_email = - if totp_enabled - @second_factor_required = true - @backup_codes_enabled = true - @message = I18n.t("login.second_factor_title") - - if second_factor_token.present? - if email_token_user.authenticate_second_factor(second_factor_token, second_factor_method) - true - else - @error = I18n.t("login.invalid_second_factor_code") - false - end - end - else - true - end - end - - if confirm_email - @user = EmailToken.confirm(token) - - if @user && @user.admin? - log_on_user(@user) - return redirect_to path("/") - else - @message = I18n.t("admin_login.errors.unknown_email_address") - end - end - else - @message = I18n.t("admin_login.errors.invalid_token") - end end render layout: 'no_ember' rescue RateLimiter::LimitExceeded @message = I18n.t("rate_limiter.slow_down") render layout: 'no_ember' - rescue ::Webauthn::SecurityKeyError => err - @message = err.message - render layout: 'no_ember' end def email_login diff --git a/app/views/users/admin_login.html.erb b/app/views/users/admin_login.html.erb index b8bca6efff9..726c62e33a7 100644 --- a/app/views/users/admin_login.html.erb +++ b/app/views/users/admin_login.html.erb @@ -1,61 +1,10 @@ <% if @message %> <%= @message %> <% if @error %>

<%= @error %>

<% end %> - - <% if @security_key_required %> -
-
- <%= hidden_field_tag 'security_key_challenge', @security_key_challenge, id: 'security-key-challenge' %> - <%= hidden_field_tag 'security_key_allowed_credential_ids', @security_key_allowed_credential_ids, id: 'security-key-allowed-credential-ids' %> - - <%=form_tag({}, method: :put) do %> -

<%= t('login.security_key_authenticate') %>

-

<%= t('login.security_key_description') %>

- <%= hidden_field_tag 'second_factor_method', '3' %> - <%= hidden_field_tag 'security_key_credential', nil, id: 'security-key-credential' %> - - <% if @second_factor_required %> - <%= link_to t('login.security_key_alternative'), '#', id: 'activate-security-key-alternative' %>

- <% end %> - <%= button_tag t('login.security_key_authenticate'), id: 'submit-security-key' %> - <% end %> -
- <% end %> - - <% if @second_factor_required %> -
-
- <%=form_tag({}, method: :put) do %> -
- <%= label_tag(:second_factor_token, t('login.second_factor_description')) %> - <%= render 'common/second_factor_text_field' %>

- <%= submit_tag t('submit')%> - <% end %> -
- - <%if @backup_codes_enabled%> - - <%=t "login.second_factor_backup" %> - <%end%> -
- <% end %> <% else %> <%=form_tag({}, method: :put) do %> <%= label_tag(:email, t('admin_login.email_input')) %> <%= text_field_tag(:email, nil, autofocus: true) %>

<%= submit_tag t('admin_login.submit_button'), class: "btn btn-primary" %> <% end %> -<% end %> - -<%= preload_script "ember_jquery" %> -<%= preload_script "locales/#{I18n.locale}" %> -<%= preload_script "locales/i18n" %> -<%= preload_script "discourse/lib/webauthn" %> -<%= preload_script "admin-login/admin-login" %> -<%= preload_script "admin-login/admin-login.no-module" %> +<% end %> \ No newline at end of file diff --git a/config/locales/server.ca.yml b/config/locales/server.ca.yml index bfbb3e3b10a..17a29cd2add 100644 --- a/config/locales/server.ca.yml +++ b/config/locales/server.ca.yml @@ -2761,7 +2761,7 @@ ca: admin_login: title: "Inicia sessió d'administració" subject_template: "[%{email_prefix}] Inici de sessió" - text_body_template: "Algú ha demanat iniciar sessió en el vostre compte en [%{site_name}](%{base_url}). \n\nSi no heu fet aquesta sol·licitud, podeu ignorar aquest correu de manera segura. \n\nFeu clic en l'enllaç següent per a iniciar la sessió: \n%{base_url}/u/admin-login/%{email_token}\n" + text_body_template: "Algú ha demanat iniciar sessió en el vostre compte en [%{site_name}](%{base_url}). \n\nSi no heu fet aquesta sol·licitud, podeu ignorar aquest correu de manera segura. \n\nFeu clic en l'enllaç següent per a iniciar la sessió: \n%{base_url}/session/email-login/%{email_token}\n" account_created: title: "Compte creat" subject_template: "[%{email_prefix}] El vostre compte nou" diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index a58e1390d20..0e6c0309f0f 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -3008,7 +3008,7 @@ de: Wenn du diese Anfrage nicht gestellt hast, kannst du diese E-Mail einfach ignorieren. Folge diesem Link, um dich anzumelden: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Konto erstellt" subject_template: "[%{email_prefix}] Dein neues Konto" diff --git a/config/locales/server.el.yml b/config/locales/server.el.yml index 1c9be5dd3bc..0006e48b5c4 100644 --- a/config/locales/server.el.yml +++ b/config/locales/server.el.yml @@ -2063,7 +2063,7 @@ el: Κάντε κλικ στον παρακάτω σύνδεσμο για να συνδεθείτε: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Ο Λογαριασμός Δημιουργήθηκε" subject_template: "[%{email_prefix}] Ο νέος σας Λογαριασμός" diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index 80d2a02cf4f..b21568c59f1 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -3563,7 +3563,7 @@ en: If you did not make this request, you can safely ignore this email. Click the following link to login: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Account Created" diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 00adaac191c..af09023be14 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -3166,7 +3166,7 @@ es: Si tú no realizaste esta petición, puedes ignorar este email. Haz clic en el siguiente enlace para iniciar sesión: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Cuenta creada" subject_template: "[%{email_prefix}] Tu nueva cuenta" diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index 020bc0bf58c..26b7cff2f83 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -1877,7 +1877,7 @@ fa_IR: اگر شما این درخواست را نداده‌اید، می‌توانید این ایمیل را نادیده بگیرید. برای ورود روی لینک کلیک کنید: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "حساب کاربری ایجاد شد" subject_template: "[%{email_prefix}] حساب کاربری جدید شما" diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index 7d81527c5ca..4919d8b691f 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -2895,7 +2895,7 @@ fi: Jos et ole pyynnön taustalla, voit huoletta jättää tämän viestin huomiotta. Kirjaudu sisään klikkaamalla linkkiä: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Tili luotu" subject_template: "[%{email_prefix}] Uusi käyttäjätilisi" diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 62931740786..ceb0a911467 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -3071,7 +3071,7 @@ fr: Cliquez sur le lien ci-dessous pour vous identifier : - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Compte Créé" subject_template: "[%{email_prefix}] Votre Nouveau Compte" diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 86a96c37b91..285e23344ca 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -3278,7 +3278,7 @@ he: אם לא אתם ביקשתם זאת, אתם יכולים פשוט להתעלם ממייל זה. לחצו על הקישור הבא כדי להתחבר: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "חשבון נוצר" subject_template: "[%{email_prefix}] החשבון החדש שלך" diff --git a/config/locales/server.hy.yml b/config/locales/server.hy.yml index af0c6cd5012..210c7ad7557 100644 --- a/config/locales/server.hy.yml +++ b/config/locales/server.hy.yml @@ -2681,7 +2681,7 @@ hy: Եթե Դուք չեք խնդրել, Դուք հանգիստ կարող եք անտեսել այս նամակը: Սեղմեք հետևյալ հղմանը՝ մուտք գործելու համար՝ - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Ստեղծված Հաշիվ" subject_template: "[%{email_prefix}] Ձեր Նոր Հաշիվը" diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index 96eb102b44e..0ed28cda29b 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -2845,7 +2845,7 @@ it: Se non sei stato tu a fare questa richiesta, puoi tranquillamente ignorare questa email. Clicca sul seguente collegamento per connetterti: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Account Creato" subject_template: "[%{email_prefix}] Il Tuo Nuovo Account" diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index b3980a8f058..4ec65648576 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -2347,7 +2347,7 @@ pl_PL: Jeśli to nie byłeś ty, możesz po prostu zignorować tą wiadomość. Naciśnij następujący link, aby się zalogować: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Utworzono Konto" subject_template: "[%{site_name}] Twoje Nowe Konto" diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index d0137256563..5ccedc47921 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -2914,7 +2914,7 @@ pt_BR: Se você não fez essa solicitação, pode ignorar esse e-mail com segurança. Clique no link a seguir para fazer o login: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Conta Criada" subject_template: "[%{email_prefix}] Sua Nova Conta" diff --git a/config/locales/server.sl.yml b/config/locales/server.sl.yml index 5ac34f63434..5a0a7466e94 100644 --- a/config/locales/server.sl.yml +++ b/config/locales/server.sl.yml @@ -1641,7 +1641,7 @@ sl: Če niste vi podali te zahteve, lahko zanemarite to e-sporočilo. Za prijavo sledite povezavi: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "Račun ustvarjen" subject_template: "[%{email_prefix}] Vaš nov uporabniški račun" diff --git a/config/locales/server.ur.yml b/config/locales/server.ur.yml index 070cddb1c55..0199f613191 100644 --- a/config/locales/server.ur.yml +++ b/config/locales/server.ur.yml @@ -3013,7 +3013,7 @@ ur: اگر آپ نے یہ درخواست نہیں کی، تو آپ اِس ای میل کو آرام سے نظر انداز کر سکتے ہیں۔ لاگ اِن کرنے کیلئے مندرجہ ذیل لِنک پر کلِک کریں: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "اکاؤنٹ تشکیل" subject_template: "[%{email_prefix}] آپ کا نیا اکاؤنٹ" diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index a0f3a382a90..a61075f4667 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -3019,7 +3019,7 @@ zh_CN: 如果你没有提出此请求,你可以安全地忽略此邮件。 点击以下链接登录: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "账户已创建" subject_template: "[%{email_prefix}] 你的新账户" diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index c6ac6ebc439..6d7ae180b78 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -2790,7 +2790,7 @@ zh_TW: 如果你沒有做此請求,你可以直接忽略本郵件。 點擊下面的連結以登入: - %{base_url}/u/admin-login/%{email_token} + %{base_url}/session/email-login/%{email_token} account_created: title: "建立使用者" subject_template: "[%{email_prefix}] 你的新帳號" diff --git a/config/routes.rb b/config/routes.rb index 02bcedc8663..266db71595a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -393,8 +393,6 @@ Discourse::Application.routes.draw do post "#{root_path}/email-login" => "users#email_login" get "#{root_path}/admin-login" => "users#admin_login" put "#{root_path}/admin-login" => "users#admin_login" - get "#{root_path}/admin-login/:token" => "users#admin_login" - put "#{root_path}/admin-login/:token" => "users#admin_login" post "#{root_path}/toggle-anon" => "users#toggle_anon" post "#{root_path}/read-faq" => "users#read_faq" get "#{root_path}/search/users" => "users#search_users" diff --git a/spec/requests/session_controller_spec.rb b/spec/requests/session_controller_spec.rb index 3b83d087249..e6a3556fe09 100644 --- a/spec/requests/session_controller_spec.rb +++ b/spec/requests/session_controller_spec.rb @@ -20,6 +20,19 @@ RSpec.describe SessionController do SiteSetting.enable_local_logins_via_email = true end + context "when local logins via email disabled" do + before { SiteSetting.enable_local_logins_via_email = false } + + it "only works for admins" do + get "/session/email-login/#{email_token.token}.json" + expect(response.status).to eq(404) + + user.update(admin: true) + get "/session/email-login/#{email_token.token}.json" + expect(response.status).to eq(200) + end + end + context 'missing token' do it 'returns the right response' do get "/session/email-login" @@ -93,6 +106,20 @@ RSpec.describe SessionController do SiteSetting.enable_local_logins_via_email = true end + context "when local logins via email disabled" do + before { SiteSetting.enable_local_logins_via_email = false } + + it "only works for admins" do + post "/session/email-login/#{email_token.token}.json" + expect(response.status).to eq(404) + + user.update(admin: true) + post "/session/email-login/#{email_token.token}.json" + expect(response.status).to eq(200) + expect(session[:current_user_id]).to eq(user.id) + end + end + context 'missing token' do it 'returns the right response' do post "/session/email-login" diff --git a/spec/requests/users_controller_spec.rb b/spec/requests/users_controller_spec.rb index ecfdb6aa79b..f7ba168a882 100644 --- a/spec/requests/users_controller_spec.rb +++ b/spec/requests/users_controller_spec.rb @@ -537,126 +537,6 @@ describe UsersController do expect(response_body).to_not match(I18n.t("login.second_factor_description")) end end - - context 'logs in admin' do - it 'does not log in admin with invalid token' do - SiteSetting.sso_url = "https://www.example.com/sso" - SiteSetting.enable_sso = true - get "/u/admin-login/invalid" - expect(session[:current_user_id]).to be_blank - end - - context 'valid token' do - it 'does log in admin with SSO disabled' do - SiteSetting.enable_sso = false - token = admin.email_tokens.create(email: admin.email).token - - get "/u/admin-login/#{token}" - expect(response).to redirect_to('/') - expect(session[:current_user_id]).to eq(admin.id) - end - - it 'logs in admin with SSO enabled' do - SiteSetting.sso_url = "https://www.example.com/sso" - SiteSetting.enable_sso = true - token = admin.email_tokens.create(email: admin.email).token - - get "/u/admin-login/#{token}" - expect(response).to redirect_to('/') - expect(session[:current_user_id]).to eq(admin.id) - end - end - - describe 'when 2 factor authentication is enabled' do - fab!(:second_factor) { Fabricate(:user_second_factor_totp, user: admin) } - fab!(:email_token) { Fabricate(:email_token, user: admin) } - - it 'does not log in when token required' do - second_factor - get "/u/admin-login/#{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 - - describe 'invalid 2 factor token' do - it 'should display the right error' do - second_factor - - put "/u/admin-login/#{email_token.token}", params: { - second_factor_token: '13213', - second_factor_method: UserSecondFactor.methods[:totp] - } - - 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 "/u/admin-login/#{email_token.token}", params: { - second_factor_token: ROTP::TOTP.new(second_factor.data).now, - second_factor_method: UserSecondFactor.methods[:totp] - } - - expect(response).to redirect_to('/') - expect(session[:current_user_id]).to eq(admin.id) - end - end - - describe 'when security key authentication required' do - fab!(:email_token) { Fabricate(:email_token, user: admin) } - let!(:security_key) do - Fabricate( - :user_security_key, - user: admin, - credential_id: valid_security_key_data[:credential_id], - public_key: valid_security_key_data[:public_key] - ) - end - - before do - simulate_localhost_webauthn_challenge - - # store challenge in secure session by visiting the admin login page - get "/u/admin-login/#{email_token.token}" - end - - it 'does not log in when token required' do - expect(response).not_to redirect_to('/') - expect(session[:current_user_id]).not_to eq(admin.id) - expect(response.body).to include(I18n.t('login.security_key_authenticate')) - end - - describe 'invalid security key' do - it 'should display the right error' do - put "/u/admin-login/#{email_token.token}", params: { - security_key_credential: { - signature: 'bad', - clientData: 'bad', - authenticatorData: 'bad', - credentialId: 'bad' - }.to_json, - second_factor_method: UserSecondFactor.methods[:security_key] - } - - expect(response.status).to eq(200) - expect(response.body).to include(I18n.t('webauthn.validation.not_found_error')) - end - end - - it 'logs in when a valid security key is given' do - put "/u/admin-login/#{email_token.token}", params: { - security_key_credential: valid_security_key_auth_post_data.to_json, - second_factor_method: UserSecondFactor.methods[:security_key] - } - - expect(response).to redirect_to('/') - expect(session[:current_user_id]).to eq(admin.id) - end - end - end end describe '#toggle_anon' do