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
|
- breadcrumb_title _('Two-Factor Authentication')
- page_title _('Two-Factor Authentication'), _('Account')
- add_to_breadcrumbs _('Account'), profile_account_path
- @content_class = "limit-container-width" unless fluid_layout
- webauthn_enabled = Feature.enabled?(:webauthn, default_enabled: :yaml)
.js-two-factor-auth{ 'data-two-factor-skippable' => "#{two_factor_skippable?}", 'data-two_factor_skip_url' => skip_profile_two_factor_auth_path }
.row.gl-mt-3
.col-lg-4
%h4.gl-mt-0
= _('Register Two-Factor 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 one time password authenticators. In order to register a different device, you must first disable two-factor authentication.")
%p
= _('If you lose your recovery codes you can generate new ones, invalidating all previous codes.')
.js-manage-two-factor-form{ data: { webauthn_enabled: webauthn_enabled, current_password_required: current_password_required?.to_s, profile_two_factor_auth_path: profile_two_factor_auth_path, profile_two_factor_auth_method: 'delete', codes_profile_two_factor_auth_path: codes_profile_two_factor_auth_path, codes_profile_two_factor_auth_method: 'post' } }
- else
%p
- register_2fa_token = _('We recommend cloud-based mobile authenticator apps such as Authy, Duo Mobile, and LastPass. They can restore access if you lose your hardware device.')
= register_2fa_token.html_safe
.row.gl-mb-3
.col-md-4.gl-pt-2{ style: 'background: #fff' }
= raw @qr_code
.col-md-8
.account-well
%p.gl-mt-0.gl-mb-0
= _("Can't scan the code?")
%p.gl-mt-0.gl-mb-0
= _('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: { qa_selector: 'otp_secret_content' } }
= _('Key: %{key}') %{ key: current_user.otp_secret.scan(/.{4}/).join(' ') }
%p.two-factor-new-manual-content
= _('Time based: Yes')
= form_tag profile_two_factor_auth_path, method: :post do |f|
- if @error
.gl-alert.gl-alert-danger.gl-mb-5
.gl-alert-container
.gl-alert-content
%p.gl-alert-body.gl-md-0
= @error[:message]
= link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
.form-group
= label_tag :pin_code, _('Pin code'), class: "label-bold"
= text_field_tag :pin_code, nil, class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
- 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: { qa_selector: 'current_password_field' }
%p.form-text.text-muted
= _('Your current password is required to register a two-factor authenticator app.')
.gl-mt-3
= submit_tag _('Register with two-factor app'), class: 'gl-button btn btn-confirm', data: { qa_selector: 'register_2fa_app_button' }
%hr
.row.gl-mt-3
.col-lg-4
%h4.gl-mt-0
- if webauthn_enabled
= _('Register WebAuthn Device')
- else
= _('Register Universal Two-Factor (U2F) Device')
%p
= _('Set up a hardware device as a second factor to sign in.')
%p
- if webauthn_enabled
= _("Not all browsers support WebAuthn. Therefore, we require that you set up a two-factor authentication app first. That way you'll always be able to sign in - even from an unsupported browser.")
- else
= _("Not all browsers support U2F devices. Therefore, we require that you set up a two-factor authentication app first. That way you'll always be able to sign in - even when you're using an unsupported browser.")
.col-lg-8
- registration = webauthn_enabled ? @webauthn_registration : @u2f_registration
- if registration.errors.present?
= form_errors(registration)
- if webauthn_enabled
= render "authentication/register", target_path: create_webauthn_profile_two_factor_auth_path
- else
= render "authentication/register", target_path: create_u2f_profile_two_factor_auth_path
%hr
%h5
- if webauthn_enabled
= _('WebAuthn Devices (%{length})') % { length: @registrations.length }
- else
= _('U2F Devices (%{length})') % { length: @registrations.length }
- if @registrations.present?
.table-responsive
%table.table.table-bordered.u2f-registrations
%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_s(:medium)
%td= link_to _('Delete'), registration[:delete_path], method: :delete, class: "gl-button btn btn-danger float-right", data: { confirm: _('Are you sure you want to delete this device? This action cannot be undone.'), confirm_btn_variant: "danger" }, aria: { label: _('Delete') }
- else
.settings-message.text-center
- if webauthn_enabled
= _("You don't have any WebAuthn devices registered yet.")
- else
= _("You don't have any U2F devices registered yet.")
|