Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/controllers/sign_in_security_check_failed_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# frozen_string_literal: true

class SignInSecurityCheckFailedController < ApplicationController
def show
analytics.sign_in_security_check_failed_visited
Comment thread
aduth marked this conversation as resolved.
end
end
3 changes: 1 addition & 2 deletions app/controllers/users/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,9 @@ def valid_captcha_result?
end

def process_failed_captcha
flash[:error] = t('errors.messages.invalid_recaptcha_token')
warden.logout(:user)
warden.lock!
redirect_to root_url
redirect_to sign_in_security_check_failed_url
end

def recaptcha_form_args
Expand Down
5 changes: 5 additions & 0 deletions app/services/analytics_events.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5472,6 +5472,11 @@ def sign_in_page_visit(flash:, **extra)
track_event('Sign in page visited', flash:, **extra)
end

# User lands on security check failed page
def sign_in_security_check_failed_visited
track_event(:sign_in_security_check_failed_visited)
end

# @param [Boolean] success
# @param [Boolean] new_user
# @param [Boolean] has_other_auth_methods
Expand Down
1 change: 1 addition & 0 deletions app/services/marketing_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class UnknownArticleException < StandardError; end
manage-your-account/add-or-change-your-authentication-method
manage-your-account/personal-key
trouble-signing-in/face-or-touch-unlock
trouble-signing-in/security-check-failed
verify-your-identity/accepted-identification-documents
verify-your-identity/accepted-state-issued-identification
verify-your-identity/how-to-add-images-of-your-state-issued-id
Expand Down
31 changes: 31 additions & 0 deletions app/views/sign_in_security_check_failed/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<% self.title = t('security_check_failed.title') %>

<%= render StatusPageComponent.new(status: :warning) do |c| %>
<% c.with_header { t('security_check_failed.title') } %>
<p>
<%= t('security_check_failed.details') %>
<%= new_tab_link_to(
t('security_check_failed.learn_more', app_name: APP_NAME),
help_center_redirect_path(
category: 'trouble-signing-in',
article: 'security-check-failed',
Comment thread
mdiarra3 marked this conversation as resolved.
),
) %>
</p>

<ul class="usa-list">
<li><%= t('security_check_failed.info_p1', app_name: APP_NAME) %></li>
<li><%= t('security_check_failed.info_p2_html', piv_cac_url: login_piv_cac_url) %></li>
<li><%= t('security_check_failed.info_p3') %></li>
</ul>

<% c.with_troubleshooting_options do |tc| %>
<% tc.with_header { t('components.troubleshooting_options.default_heading') } %>
<% tc.with_option(
url: contact_redirect_url,
new_tab: true,
).with_content(t('security_check_failed.contact', app_name: APP_NAME)) %>
<% end %>
<% end %>

<%= render 'shared/cancel', link: root_url %>
7 changes: 7 additions & 0 deletions config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,13 @@ risc.security_event.errors.typ_error: typ header must be %{expected_typ}
saml_idp.auth.error.title: Error
saml_idp.shared.saml_post_binding.heading: Submit to continue
saml_idp.shared.saml_post_binding.no_js: JavaScript seems to be turned off in your browser. Normally this step happens automatically, but because you have JavaScript turned off, please click the submit button to continue signing in or signing out.
security_check_failed.contact: Contact %{app_name} support
security_check_failed.details: We don’t recognize the device or browser you’re signing in from.
security_check_failed.info_p1: 'Use the same device and browser you created your %{app_name} account with.'
security_check_failed.info_p2_html: Try <a href="%{piv_cac_url}">signing in with your government employee ID</a> if you are a government employee.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO I think it might be a little more reliable to get things through the i18n process to break the link title into its own key

Suggested change
security_check_failed.info_p2_html: Try <a href="%{piv_cac_url}">signing in with your government employee ID</a> if you are a government employee.
security_check_failed.info_p2_html: Try %{piv_cac_link_html} if you are a government employee.
security_check_failed.info_p2_link_html: signing in with your government employee ID

and then update the callsite to be like

    <li><%= t('security_check_failed.info_p2_html', piv_cac_link_html: link_to(t('security_check_failed.info_p2_link_html'), login_piv_cac_url) %></li> 

security_check_failed.info_p3: Turn off any VPN, ad blockers, and clear your cache.
security_check_failed.learn_more: Learn more about %{app_name}’s security checks
security_check_failed.title: Security check failed
service_providers.errors.generic_sp_name: This agency
service_providers.errors.inactive.button_text: View my %{app_name} account
service_providers.errors.inactive.heading: '%{sp_name} no longer uses %{app_name}'
Expand Down
7 changes: 7 additions & 0 deletions config/locales/es.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1498,6 +1498,13 @@ risc.security_event.errors.typ_error: encabezado de tipo debe ser %{expected_typ
saml_idp.auth.error.title: Error
saml_idp.shared.saml_post_binding.heading: Enviar para continuar
saml_idp.shared.saml_post_binding.no_js: JavaScript parece estar desactivado en su navegador. Por lo general, este paso es automático, pero, debido a que tiene JavaScript desactivado, haga clic en el botón Enviar para continuar iniciando sesión o cerrándola.
security_check_failed.contact: Contacte con el servicio de asistencia de %{app_name}
security_check_failed.details: No reconocemos el dispositivo o el navegador desde el que está iniciando sesión.
security_check_failed.info_p1: 'Utilice el mismo dispositivo y navegador con el que creó su cuenta en %{app_name}.'
security_check_failed.info_p2_html: Intente <a href="%{piv_cac_url}">iniciar sesión con su identificación de empleado del gobierno</a> si es un empleado del gobierno.
security_check_failed.info_p3: Desactive cualquier VPN, bloqueador de anuncios y borre su caché.
security_check_failed.learn_more: Obtenga más información sobre las comprobaciones de seguridad de %{app_name}
security_check_failed.title: Falló la comprobación de seguridad
service_providers.errors.generic_sp_name: Esta agencia
service_providers.errors.inactive.button_text: Ver mi cuenta de %{app_name}
service_providers.errors.inactive.heading: '%{sp_name} ya no utiliza %{app_name}'
Expand Down
7 changes: 7 additions & 0 deletions config/locales/fr.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1487,6 +1487,13 @@ risc.security_event.errors.typ_error: l’en-tête typ doit être %{expected_typ
saml_idp.auth.error.title: Erreur
saml_idp.shared.saml_post_binding.heading: Valider pour continuer
saml_idp.shared.saml_post_binding.no_js: JavaScript semble être désactivé dans votre navigateur. Normalement, cette étape se produit automatiquement, mais comme vous avez désactivé JavaScript, veuillez cliquer sur le bouton « Valider » pour poursuivre la connexion ou la déconnexion.
security_check_failed.contact: Contactez l’assistance %{app_name}
security_check_failed.details: Nous ne reconnaissons pas l’appareil ou le navigateur à partir duquel vous vous connectez.
security_check_failed.info_p1: 'Utilisez le même appareil et le même navigateur que ceux avec lesquels vous aviez créé votre compte %{app_name}.'
security_check_failed.info_p2_html: Essayez <a href="%{piv_cac_url}">de vous connecter avec votre carte d’employé fédéral</a> si vous êtes employé fédéral.
security_check_failed.info_p3: Désactivez tout éventuel VPN ou bloqueur de publicité et videz votre cache.
security_check_failed.learn_more: En savoir plus sur les tests de sécurité de %{app_name}
security_check_failed.title: Échec du test de sécurité
service_providers.errors.generic_sp_name: Cet organisme
service_providers.errors.inactive.button_text: Voir mon compte %{app_name}
service_providers.errors.inactive.heading: '%{sp_name} n’utilise plus %{app_name}'
Expand Down
7 changes: 7 additions & 0 deletions config/locales/zh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1503,6 +1503,13 @@ risc.security_event.errors.typ_error: 类型标头必须是 %{expected_typ}
saml_idp.auth.error.title: 错误
saml_idp.shared.saml_post_binding.heading: 提交来继续
saml_idp.shared.saml_post_binding.no_js: 你浏览器中的 JavaScript 似乎已关闭。该步骤通常会自动发生,但因为你把 JavaScript 关闭,请点击提交按钮来继续登入或登出。
security_check_failed.contact: 请联系 %{app_name}支持
security_check_failed.details: 我们不认识您登录正在使用的设备或浏览器。
security_check_failed.info_p1: '使用您设立自己 %{app_name} 账户时的同一设备和浏览器。'
security_check_failed.info_p2_html: '如果您是政府雇员,尝试<a href="%{piv_cac_url}">用您的政府雇员身份证件登录。</a>'
security_check_failed.info_p3: 关闭任何 VPN 和广告拦截器并清除缓存。
security_check_failed.learn_more: 了解 %{app_name} 安全检查的更多信息
security_check_failed.title: 安全检查未通过
service_providers.errors.generic_sp_name: 该机构
service_providers.errors.inactive.button_text: 查看我的 %{app_name} 账户
service_providers.errors.inactive.heading: '%{sp_name} 不再使用 %{app_name}'
Expand Down
2 changes: 2 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,8 @@
post '/test/device_profiling' => 'test/device_profiling#create'
end

get '/sign_in_security_check_failed' => 'sign_in_security_check_failed#show'

get '/auth_method_confirmation' => 'mfa_confirmation#show'
post '/auth_method_confirmation/skip' => 'mfa_confirmation#skip'

Expand Down
19 changes: 19 additions & 0 deletions spec/controllers/sign_in_security_check_failed_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'rails_helper'

RSpec.describe SignInSecurityCheckFailedController do
let(:user) { build_stubbed(:user, :fully_registered) }

before do
stub_sign_in(user)
end

Comment thread
mdiarra3 marked this conversation as resolved.
Outdated
it 'renders the show template' do
stub_analytics

get :show

expect(@analytics).to have_logged_event(:sign_in_security_check_failed_visited)

expect(response).to render_template :show
end
Comment thread
mdiarra3 marked this conversation as resolved.
Outdated
end
12 changes: 12 additions & 0 deletions spec/controllers/users/sessions_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,18 @@
)
end

it 'redirects unsuccessful authentication for failed reCAPTCHA to failed page' do
user = create(:user, :fully_registered)

allow(FeatureManagement).to receive(:sign_in_recaptcha_enabled?).and_return(true)
allow(IdentityConfig.store).to receive(:recaptcha_mock_validator).and_return(true)
allow(IdentityConfig.store).to receive(:sign_in_recaptcha_score_threshold).and_return(0.2)

post :create, params: { user: { email: user.email, password: user.password, score: 0.1 } }

expect(response).to redirect_to sign_in_security_check_failed_url
end

it 'tracks count of multiple unsuccessful authentication attempts' do
user = create(
:user,
Expand Down
17 changes: 17 additions & 0 deletions spec/features/users/sign_in_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -968,6 +968,23 @@
end
end

context 'Recaptcha check fails' do
let(:user) { create(:user, :fully_registered) }
before do
allow(FeatureManagement).to receive(:sign_in_recaptcha_enabled?).and_return(true)
allow(IdentityConfig.store).to receive(:recaptcha_mock_validator).and_return(true)
allow(IdentityConfig.store).to receive(:sign_in_recaptcha_score_threshold).and_return(0.2)
end

it 'redirects user to security check failed page' do
visit new_user_session_path
fill_in :user_recaptcha_mock_score, with: '0.1'
fill_in_credentials_and_submit(user.email, user.password)

expect(current_path).to eq sign_in_security_check_failed_path
end
end

context 'check_password_compromised feature toggle is true' do
before do
allow(FeatureManagement).to receive(:check_password_enabled?).and_return(true)
Expand Down