DEV: Remove redundant admin_login route, share with email_login
This commit is contained in:
parent
d50eb82d51
commit
9e399b42b9
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
require("admin-login/admin-login").default();
|
|
@ -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(
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,61 +1,10 @@
|
|||
<% if @message %>
|
||||
<%= @message %>
|
||||
<% 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 %>
|
||||
<%=form_tag({}, method: :put) do %>
|
||||
<%= label_tag(:email, t('admin_login.email_input')) %>
|
||||
<%= text_field_tag(:email, nil, autofocus: true) %><br><br>
|
||||
<%= 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 %>
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}] Ο νέος σας Λογαριασμός"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}] حساب کاربری جدید شما"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}] החשבון החדש שלך"
|
||||
|
|
|
@ -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}] Ձեր Նոր Հաշիվը"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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}] آپ کا نیا اکاؤنٹ"
|
||||
|
|
|
@ -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}] 你的新账户"
|
||||
|
|
|
@ -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}] 你的新帳號"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue