DEV: Remove redundant admin_login route, share with email_login

This commit is contained in:
Martin Brennan 2020-01-13 12:10:07 +10:00
parent d50eb82d51
commit 9e399b42b9
25 changed files with 55 additions and 318 deletions

View File

@ -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;
}
};
}

View File

@ -1 +0,0 @@
require("admin-login/admin-login").default();

View File

@ -345,11 +345,14 @@ class SessionController < ApplicationController
end end
def email_login_info def email_login_info
raise Discourse::NotFound if !SiteSetting.enable_local_logins_via_email
token = params[:token] token = params[:token]
matched_token = EmailToken.confirmable(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 if matched_token
response = { response = {
can_login: true, can_login: true,
@ -382,13 +385,17 @@ class SessionController < ApplicationController
end end
def email_login def email_login
raise Discourse::NotFound if !SiteSetting.enable_local_logins_via_email
second_factor_token = params[:second_factor_token] second_factor_token = params[:second_factor_token]
second_factor_method = params[:second_factor_method].to_i second_factor_method = params[:second_factor_method].to_i
security_key_credential = params[:security_key_credential] security_key_credential = params[:security_key_credential]
token = params[:token] token = params[:token]
matched_token = EmailToken.confirmable(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 security_key_credential.present?
if matched_token&.user&.security_keys_enabled? if matched_token&.user&.security_keys_enabled?
security_key_valid = ::Webauthn::SecurityKeyAuthenticationService.new( security_key_valid = ::Webauthn::SecurityKeyAuthenticationService.new(

View File

@ -684,89 +684,12 @@ class UsersController < ApplicationController
else else
@message = I18n.t("admin_login.errors.unknown_email_address") @message = I18n.t("admin_login.errors.unknown_email_address")
end 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 end
render layout: 'no_ember' render layout: 'no_ember'
rescue RateLimiter::LimitExceeded rescue RateLimiter::LimitExceeded
@message = I18n.t("rate_limiter.slow_down") @message = I18n.t("rate_limiter.slow_down")
render layout: 'no_ember' render layout: 'no_ember'
rescue ::Webauthn::SecurityKeyError => err
@message = err.message
render layout: 'no_ember'
end end
def email_login def email_login

View File

@ -1,61 +1,10 @@
<% if @message %> <% if @message %>
<%= @message %> <%= @message %>
<% if @error %><p><%= @error %></p><% end %> <% if @error %><p><%= @error %></p><% end %>
<% if @security_key_required %>
<div id="primary-security-key-form">
<div id="security-key-error"></div>
<%= 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 %>
<p><strong><%= t('login.security_key_authenticate') %></strong></p>
<p><%= t('login.security_key_description') %></p>
<%= 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' %><br/><br/>
<% end %>
<%= button_tag t('login.security_key_authenticate'), id: 'submit-security-key' %>
<% end %>
</div>
<% end %>
<% if @second_factor_required %>
<div id="second-factor-forms" style="<%= @security_key_required ? 'display: none' : '' %>">
<div id="primary-second-factor-form">
<%=form_tag({}, method: :put) do %>
<br/>
<%= label_tag(:second_factor_token, t('login.second_factor_description')) %>
<%= render 'common/second_factor_text_field' %><br><br>
<%= submit_tag t('submit')%>
<% end %>
</div>
<%if @backup_codes_enabled%>
<div id="backup-second-factor-form" style="display: none">
<%= form_tag({}, method: :put) do%>
<%= label_tag(:second_factor_token, t("login.second_factor_backup_description")) %>
<%= render 'common/second_factor_backup_input' %><br><br>
<%= submit_tag(t("submit")) %>
<%end%>
</div>
<a href id="toggle-form"><%=t "login.second_factor_backup" %></a>
<%end%>
</div>
<% end %>
<% else %> <% else %>
<%=form_tag({}, method: :put) do %> <%=form_tag({}, method: :put) do %>
<%= label_tag(:email, t('admin_login.email_input')) %> <%= label_tag(:email, t('admin_login.email_input')) %>
<%= text_field_tag(:email, nil, autofocus: true) %><br><br> <%= text_field_tag(:email, nil, autofocus: true) %><br><br>
<%= submit_tag t('admin_login.submit_button'), class: "btn btn-primary" %> <%= submit_tag t('admin_login.submit_button'), class: "btn btn-primary" %>
<% end %> <% end %>
<% 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" %>

View File

@ -2761,7 +2761,7 @@ ca:
admin_login: admin_login:
title: "Inicia sessió d'administració" title: "Inicia sessió d'administració"
subject_template: "[%{email_prefix}] Inici de sessió" 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: account_created:
title: "Compte creat" title: "Compte creat"
subject_template: "[%{email_prefix}] El vostre compte nou" subject_template: "[%{email_prefix}] El vostre compte nou"

View File

@ -3008,7 +3008,7 @@ de:
Wenn du diese Anfrage nicht gestellt hast, kannst du diese E-Mail einfach ignorieren. Wenn du diese Anfrage nicht gestellt hast, kannst du diese E-Mail einfach ignorieren.
Folge diesem Link, um dich anzumelden: Folge diesem Link, um dich anzumelden:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Konto erstellt" title: "Konto erstellt"
subject_template: "[%{email_prefix}] Dein neues Konto" subject_template: "[%{email_prefix}] Dein neues Konto"

View File

@ -2063,7 +2063,7 @@ el:
Κάντε κλικ στον παρακάτω σύνδεσμο για να συνδεθείτε: Κάντε κλικ στον παρακάτω σύνδεσμο για να συνδεθείτε:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Ο Λογαριασμός Δημιουργήθηκε" title: "Ο Λογαριασμός Δημιουργήθηκε"
subject_template: "[%{email_prefix}] Ο νέος σας Λογαριασμός" subject_template: "[%{email_prefix}] Ο νέος σας Λογαριασμός"

View File

@ -3563,7 +3563,7 @@ en:
If you did not make this request, you can safely ignore this email. If you did not make this request, you can safely ignore this email.
Click the following link to login: Click the following link to login:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Account Created" title: "Account Created"

View File

@ -3166,7 +3166,7 @@ es:
Si tú no realizaste esta petición, puedes ignorar este email. Si tú no realizaste esta petición, puedes ignorar este email.
Haz clic en el siguiente enlace para iniciar sesión: 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: account_created:
title: "Cuenta creada" title: "Cuenta creada"
subject_template: "[%{email_prefix}] Tu nueva cuenta" subject_template: "[%{email_prefix}] Tu nueva cuenta"

View File

@ -1877,7 +1877,7 @@ fa_IR:
اگر شما این درخواست را نداده‌اید، می‌توانید این ایمیل را نادیده بگیرید. اگر شما این درخواست را نداده‌اید، می‌توانید این ایمیل را نادیده بگیرید.
برای ورود روی لینک کلیک کنید: برای ورود روی لینک کلیک کنید:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "حساب کاربری ایجاد شد" title: "حساب کاربری ایجاد شد"
subject_template: "[%{email_prefix}] حساب کاربری جدید شما" subject_template: "[%{email_prefix}] حساب کاربری جدید شما"

View File

@ -2895,7 +2895,7 @@ fi:
Jos et ole pyynnön taustalla, voit huoletta jättää tämän viestin huomiotta. Jos et ole pyynnön taustalla, voit huoletta jättää tämän viestin huomiotta.
Kirjaudu sisään klikkaamalla linkkiä: Kirjaudu sisään klikkaamalla linkkiä:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Tili luotu" title: "Tili luotu"
subject_template: "[%{email_prefix}] Uusi käyttäjätilisi" subject_template: "[%{email_prefix}] Uusi käyttäjätilisi"

View File

@ -3071,7 +3071,7 @@ fr:
Cliquez sur le lien ci-dessous pour vous identifier : 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: account_created:
title: "Compte Créé" title: "Compte Créé"
subject_template: "[%{email_prefix}] Votre Nouveau Compte" subject_template: "[%{email_prefix}] Votre Nouveau Compte"

View File

@ -3278,7 +3278,7 @@ he:
אם לא אתם ביקשתם זאת, אתם יכולים פשוט להתעלם ממייל זה. אם לא אתם ביקשתם זאת, אתם יכולים פשוט להתעלם ממייל זה.
לחצו על הקישור הבא כדי להתחבר: לחצו על הקישור הבא כדי להתחבר:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "חשבון נוצר" title: "חשבון נוצר"
subject_template: "[%{email_prefix}] החשבון החדש שלך" subject_template: "[%{email_prefix}] החשבון החדש שלך"

View File

@ -2681,7 +2681,7 @@ hy:
Եթե Դուք չեք խնդրել, Դուք հանգիստ կարող եք անտեսել այս նամակը: Եթե Դուք չեք խնդրել, Դուք հանգիստ կարող եք անտեսել այս նամակը:
Սեղմեք հետևյալ հղմանը՝ մուտք գործելու համար՝ Սեղմեք հետևյալ հղմանը՝ մուտք գործելու համար՝
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Ստեղծված Հաշիվ" title: "Ստեղծված Հաշիվ"
subject_template: "[%{email_prefix}] Ձեր Նոր Հաշիվը" subject_template: "[%{email_prefix}] Ձեր Նոր Հաշիվը"

View File

@ -2845,7 +2845,7 @@ it:
Se non sei stato tu a fare questa richiesta, puoi tranquillamente ignorare questa email. Se non sei stato tu a fare questa richiesta, puoi tranquillamente ignorare questa email.
Clicca sul seguente collegamento per connetterti: Clicca sul seguente collegamento per connetterti:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Account Creato" title: "Account Creato"
subject_template: "[%{email_prefix}] Il Tuo Nuovo Account" subject_template: "[%{email_prefix}] Il Tuo Nuovo Account"

View File

@ -2347,7 +2347,7 @@ pl_PL:
Jeśli to nie byłeś ty, możesz po prostu zignorować tą wiadomość. Jeśli to nie byłeś ty, możesz po prostu zignorować tą wiadomość.
Naciśnij następujący link, aby się zalogować: 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: account_created:
title: "Utworzono Konto" title: "Utworzono Konto"
subject_template: "[%{site_name}] Twoje Nowe Konto" subject_template: "[%{site_name}] Twoje Nowe Konto"

View File

@ -2914,7 +2914,7 @@ pt_BR:
Se você não fez essa solicitação, pode ignorar esse e-mail com segurança. 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: 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: account_created:
title: "Conta Criada" title: "Conta Criada"
subject_template: "[%{email_prefix}] Sua Nova Conta" subject_template: "[%{email_prefix}] Sua Nova Conta"

View File

@ -1641,7 +1641,7 @@ sl:
Če niste vi podali te zahteve, lahko zanemarite to e-sporočilo. Če niste vi podali te zahteve, lahko zanemarite to e-sporočilo.
Za prijavo sledite povezavi: Za prijavo sledite povezavi:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "Račun ustvarjen" title: "Račun ustvarjen"
subject_template: "[%{email_prefix}] Vaš nov uporabniški račun" subject_template: "[%{email_prefix}] Vaš nov uporabniški račun"

View File

@ -3013,7 +3013,7 @@ ur:
اگر آپ نے یہ درخواست نہیں کی، تو آپ اِس ای میل کو آرام سے نظر انداز کر سکتے ہیں۔ اگر آپ نے یہ درخواست نہیں کی، تو آپ اِس ای میل کو آرام سے نظر انداز کر سکتے ہیں۔
لاگ اِن کرنے کیلئے مندرجہ ذیل لِنک پر کلِک کریں: لاگ اِن کرنے کیلئے مندرجہ ذیل لِنک پر کلِک کریں:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "اکاؤنٹ تشکیل" title: "اکاؤنٹ تشکیل"
subject_template: "[%{email_prefix}] آپ کا نیا اکاؤنٹ" subject_template: "[%{email_prefix}] آپ کا نیا اکاؤنٹ"

View File

@ -3019,7 +3019,7 @@ zh_CN:
如果你没有提出此请求,你可以安全地忽略此邮件。 如果你没有提出此请求,你可以安全地忽略此邮件。
点击以下链接登录: 点击以下链接登录:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "账户已创建" title: "账户已创建"
subject_template: "[%{email_prefix}] 你的新账户" subject_template: "[%{email_prefix}] 你的新账户"

View File

@ -2790,7 +2790,7 @@ zh_TW:
如果你沒有做此請求,你可以直接忽略本郵件。 如果你沒有做此請求,你可以直接忽略本郵件。
點擊下面的連結以登入: 點擊下面的連結以登入:
%{base_url}/u/admin-login/%{email_token} %{base_url}/session/email-login/%{email_token}
account_created: account_created:
title: "建立使用者" title: "建立使用者"
subject_template: "[%{email_prefix}] 你的新帳號" subject_template: "[%{email_prefix}] 你的新帳號"

View File

@ -393,8 +393,6 @@ Discourse::Application.routes.draw do
post "#{root_path}/email-login" => "users#email_login" post "#{root_path}/email-login" => "users#email_login"
get "#{root_path}/admin-login" => "users#admin_login" get "#{root_path}/admin-login" => "users#admin_login"
put "#{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}/toggle-anon" => "users#toggle_anon"
post "#{root_path}/read-faq" => "users#read_faq" post "#{root_path}/read-faq" => "users#read_faq"
get "#{root_path}/search/users" => "users#search_users" get "#{root_path}/search/users" => "users#search_users"

View File

@ -20,6 +20,19 @@ RSpec.describe SessionController do
SiteSetting.enable_local_logins_via_email = true SiteSetting.enable_local_logins_via_email = true
end 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 context 'missing token' do
it 'returns the right response' do it 'returns the right response' do
get "/session/email-login" get "/session/email-login"
@ -93,6 +106,20 @@ RSpec.describe SessionController do
SiteSetting.enable_local_logins_via_email = true SiteSetting.enable_local_logins_via_email = true
end 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 context 'missing token' do
it 'returns the right response' do it 'returns the right response' do
post "/session/email-login" post "/session/email-login"

View File

@ -537,126 +537,6 @@ describe UsersController do
expect(response_body).to_not match(I18n.t("login.second_factor_description")) expect(response_body).to_not match(I18n.t("login.second_factor_description"))
end end
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 end
describe '#toggle_anon' do describe '#toggle_anon' do