1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
|
- breadcrumb_title _('Two-Factor Authentication')
- page_title _('Two-Factor Authentication'), _('Account')
- add_to_breadcrumbs _('Account'), profile_account_path
- troubleshooting_link = link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication_troubleshooting.md'), target: '_blank', rel: 'noopener noreferrer'
- if @error
= render Pajamas::AlertComponent.new(title: @error[:message],
variant: :danger,
alert_options: { class: 'gl-mb-5' },
dismissible: false) do |c|
- c.with_body do
= troubleshooting_link
.row.gl-mt-3
.col-lg-4
%h4.gl-mt-0
= _('Register a one-time password authenticator')
%p
= _('Use a one-time password authenticator on your mobile device or computer to enable two-factor authentication (2FA).')
.col-lg-8
- if current_user.two_factor_otp_enabled?
%p
= _("You've already enabled two-factor authentication using a one-time password authenticator. In order to register a different device, you must first delete this authenticator.")
.gl-inline-block.gl-w-full.sm:gl-w-auto
.js-two-factor-action-confirm{ data: delete_otp_authenticator_data(current_password_required?) }
- else
%p
- register_2fa_token = _('We recommend using cloud-based authenticator applications that can restore access if you lose your hardware device.')
= register_2fa_token.html_safe
= link_to _('What are some examples?'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'enable-a-one-time-password-authenticator'), target: '_blank', rel: 'noopener noreferrer'
.gl-p-2.gl-mb-3{ style: 'background: #fff' }
= raw @qr_code
.gl-mb-5
= render Pajamas::CardComponent.new do |c|
- c.with_body do
%p.gl-mt-0.gl-mb-3.gl-font-bold
= _("Can't scan the code?")
%p.gl-mt-0.gl-mb-3
= _("To add the entry manually, provide the following details to the application on your phone.")
%p.gl-mt-0.gl-mb-0
= _('Account: %{account}') % { account: @account_string }
%p.gl-mt-0.gl-mb-0{ data: { testid: 'otp-secret-content' } }
= _('Key:')
%code.two-factor-secret= current_user.otp_secret.scan(/.{4}/).join(' ')
%p.gl-mb-0.two-factor-new-manual-content
= _('Time based: Yes')
= form_tag profile_two_factor_auth_path, method: :post do |f|
- if @otp_error
= render Pajamas::AlertComponent.new(title: @otp_error[:message],
variant: :danger,
alert_options: { class: 'gl-mb-3' },
dismissible: false) do |c|
- c.with_body do
= troubleshooting_link
- if current_password_required?
.form-group
= label_tag :current_password, _('Current password'), class: 'label-bold'
= password_field_tag :current_password, nil, autocomplete: 'current-password', required: true, class: 'form-control gl-form-input', data: { testid: 'current-password-field' }
%p.form-text.gl-text-subtle
= _('Your current password is required to register a two-factor authenticator app.')
.form-group
= label_tag :pin_code, _('Enter verification code'), class: "label-bold"
= text_field_tag :pin_code, nil, autocomplete: 'off', inputmode: 'numeric', class: "form-control gl-form-input", required: true, data: { testid: 'pin-code-field' }
.gl-mt-3
= render Pajamas::ButtonComponent.new(type: :submit, variant: :confirm, button_options: { data: { testid: 'register-2fa-app-button' } }) do
= _('Register with two-factor app')
%hr
.row.gl-mt-3
.col-lg-4
%h4.gl-mt-0
= _('Register a WebAuthn device')
%p
= _('Set up a hardware device to enable two-factor authentication (2FA).')
%p
= _("Not all browsers support WebAuthn. You must save your recovery codes after you first register a two-factor authenticator to be able to sign in, even from an unsupported browser.")
.col-lg-8
- if @webauthn_registration.errors.present?
= form_errors(@webauthn_registration)
#js-device-registration{ data: device_registration_data(current_password_required: current_password_required?, target_path: create_webauthn_profile_two_factor_auth_path, webauthn_error: @webauthn_error) }
%hr
%h5
= _('WebAuthn Devices (%{length})') % { length: @registrations.length }
- if @registrations.present?
.table-responsive
%table.table
%colgroup
%col{ width: "50%" }
%col{ width: "30%" }
%col{ width: "20%" }
%thead
%tr
%th= _('Name')
%th= s_('2FADevice|Registered On')
%th
%tbody
- @registrations.each do |registration|
%tr
%td
- if registration[:name].present?
= registration[:name]
- else
%span.gl-text-gray-500
= _("no name set")
%td= registration[:created_at].to_date.to_fs(:medium)
%td
.gl-float-right
.js-two-factor-action-confirm{ data: delete_webauthn_device_data(current_password_required?, registration[:delete_path]) }
- else
.settings-message.text-center
= _("You don't have any WebAuthn devices registered yet.")
%hr
.row.gl-mt-3
.col-lg-4
%h4.gl-mt-0
= _('Disable two-factor authentication')
%p
= _('Use this section to disable your one-time password authenticator and WebAuthn devices. You can also generate new recovery codes.')
.col-lg-8
- if current_user.two_factor_enabled?
%p
= _('If you lose your recovery codes you can generate new ones, invalidating all previous codes.')
.gl-flex.gl-flex-wrap.gl-gap-3
.gl-w-full.sm:gl-w-auto
.js-two-factor-action-confirm{ data: disable_two_factor_authentication_data(current_password_required?) }
.gl-w-full.sm:gl-w-auto
.js-two-factor-action-confirm{ data: codes_two_factor_authentication_data(current_password_required?) }
- else
%p
= _("Register a one-time password authenticator or a WebAuthn device first.")
|