diff options
Diffstat (limited to 'app/views')
17 files changed, 329 insertions, 50 deletions
diff --git a/app/views/auth/sessions/two_factor.html.haml b/app/views/auth/sessions/two_factor.html.haml index b2e36f6bc..f2f6fe19d 100644 --- a/app/views/auth/sessions/two_factor.html.haml +++ b/app/views/auth/sessions/two_factor.html.haml @@ -1,14 +1,9 @@ - content_for :page_title do = t('auth.login') -= simple_form_for(resource, as: resource_name, url: session_path(resource_name), method: :post) do |f| - %p.hint.otp-hint= t('simple_form.hints.sessions.otp') +=javascript_pack_tag 'two_factor_authentication', integrity: true, crossorigin: 'anonymous' - .fields-group - = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, autofocus: true +- if @webauthn_enabled + = render partial: 'auth/sessions/two_factor/webauthn_form', locals: { hidden: @scheme_type != 'webauthn' } - .actions - = f.button :button, t('auth.login'), type: :submit - - - if Setting.site_contact_email.present? - %p.hint.subtle-hint= t('users.otp_lost_help_html', email: mail_to(Setting.site_contact_email, nil)) += render partial: 'auth/sessions/two_factor/otp_authentication_form', locals: { hidden: @scheme_type != 'totp' } diff --git a/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml new file mode 100644 index 000000000..ab2d48c0a --- /dev/null +++ b/app/views/auth/sessions/two_factor/_otp_authentication_form.html.haml @@ -0,0 +1,18 @@ += simple_form_for(resource, + as: resource_name, + url: session_path(resource_name), + html: { method: :post, id: 'otp-authentication-form' }.merge(hidden ? { class: 'hidden' } : {})) do |f| + %p.hint.authentication-hint= t('simple_form.hints.sessions.otp') + + .fields-group + = f.input :otp_attempt, type: :number, wrapper: :with_label, label: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt'), :autocomplete => 'off' }, autofocus: true + + .actions + = f.button :button, t('auth.login'), type: :submit + + - if Setting.site_contact_email.present? + %p.hint.subtle-hint= t('users.otp_lost_help_html', email: mail_to(Setting.site_contact_email, nil)) + + - if @webauthn_enabled + .form-footer + = link_to(t('auth.link_to_webauth'), '#', id: 'link-to-webauthn') diff --git a/app/views/auth/sessions/two_factor/_webauthn_form.html.haml b/app/views/auth/sessions/two_factor/_webauthn_form.html.haml new file mode 100644 index 000000000..32ed1294a --- /dev/null +++ b/app/views/auth/sessions/two_factor/_webauthn_form.html.haml @@ -0,0 +1,17 @@ +%p.flash-message.hidden#unsupported-browser-message= t 'webauthn_credentials.not_supported' +%p.flash-message.alert.hidden#security-key-error-message= t 'webauthn_credentials.invalid_credential' + + += simple_form_for(resource, + as: resource_name, + url: session_path(resource_name), + html: { method: :post, id: 'webauthn-form' }.merge(hidden ? { class: 'hidden' } : {})) do |f| + %h3.title= t('simple_form.title.sessions.webauthn') + %p.hint= t('simple_form.hints.sessions.webauthn') + + .actions + = f.button :button, t('auth.use_security_key'), class: 'js-webauthn', type: :submit + + .form-footer + %p= t('auth.dont_have_your_security_key') + = link_to(t('auth.link_to_otp'), '#', id: 'link-to-otp') diff --git a/app/views/settings/two_factor_authentication/confirmations/new.html.haml b/app/views/settings/two_factor_authentication/confirmations/new.html.haml index 86cf1f695..671237db5 100644 --- a/app/views/settings/two_factor_authentication/confirmations/new.html.haml +++ b/app/views/settings/two_factor_authentication/confirmations/new.html.haml @@ -2,17 +2,17 @@ = t('settings.two_factor_authentication') = simple_form_for @confirmation, url: settings_two_factor_authentication_confirmation_path, method: :post do |f| - %p.hint= t('two_factor_authentication.instructions_html') + %p.hint= t('otp_authentication.instructions_html') .qr-wrapper .qr-code!= @qrcode.as_svg(padding: 0, module_size: 4) .qr-alternative - %p.hint= t('two_factor_authentication.manual_instructions') - %samp.qr-alternative__code= current_user.otp_secret.scan(/.{4}/).join(' ') + %p.hint= t('otp_authentication.manual_instructions') + %samp.qr-alternative__code= @new_otp_secret.scan(/.{4}/).join(' ') .fields-group - = f.input :otp_attempt, wrapper: :with_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true + = f.input :otp_attempt, wrapper: :with_label, hint: t('otp_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true .actions - = f.button :button, t('two_factor_authentication.enable'), type: :submit + = f.button :button, t('otp_authentication.enable'), type: :submit diff --git a/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml new file mode 100644 index 000000000..d069ba12a --- /dev/null +++ b/app/views/settings/two_factor_authentication/otp_authentication/show.html.haml @@ -0,0 +1,9 @@ +- content_for :page_title do + = t('settings.two_factor_authentication') + +.simple_form + %p.hint= t('otp_authentication.description_html') + + %hr.spacer/ + + = link_to t('otp_authentication.setup'), settings_otp_authentication_path, data: { method: :post }, class: 'block-button' diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/index.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/index.html.haml new file mode 100644 index 000000000..0dfd94ab9 --- /dev/null +++ b/app/views/settings/two_factor_authentication/webauthn_credentials/index.html.haml @@ -0,0 +1,17 @@ +- content_for :page_title do + = t('settings.webauthn_authentication') + +.table-wrapper + %table.table + %tbody + - current_user.webauthn_credentials.each do |credential| + %tr + %td= credential.nickname + %td= t('webauthn_credentials.registered_on', date: l(credential.created_at.to_date, format: :with_month_name)) + %td + = table_link_to 'trash', t('webauthn_credentials.delete'), settings_webauthn_credential_path(credential.id), method: :delete, data: { confirm: t('webauthn_credentials.delete_confirmation') } + +%hr.spacer/ + +.simple_form + = link_to t('webauthn_credentials.add'), new_settings_webauthn_credential_path, class: 'block-button' diff --git a/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml new file mode 100644 index 000000000..0b23bb689 --- /dev/null +++ b/app/views/settings/two_factor_authentication/webauthn_credentials/new.html.haml @@ -0,0 +1,16 @@ +- content_for :page_title do + = t('settings.webauthn_authentication') + += simple_form_for(:new_webauthn_credential, url: settings_webauthn_credentials_path, html: { id: :new_webauthn_credential }) do |f| + %p.flash-message.hidden#unsupported-browser-message= t 'webauthn_credentials.not_supported' + %p.flash-message.alert.hidden#security-key-error-message= t 'webauthn_credentials.invalid_credential' + + %p.hint= t('webauthn_credentials.description_html') + + .fields_group + = f.input :nickname, wrapper: :with_block_label, hint: t('webauthn_credentials.nickname_hint'), input_html: { :autocomplete => 'off' }, required: true + + .actions + = f.button :button, t('webauthn_credentials.add'), class: 'js-webauthn', type: :submit + += javascript_pack_tag 'two_factor_authentication', integrity: true, crossorigin: 'anonymous' diff --git a/app/views/settings/two_factor_authentication_methods/index.html.haml b/app/views/settings/two_factor_authentication_methods/index.html.haml new file mode 100644 index 000000000..315443e6d --- /dev/null +++ b/app/views/settings/two_factor_authentication_methods/index.html.haml @@ -0,0 +1,41 @@ +- content_for :page_title do + = t('settings.two_factor_authentication') + +- content_for :heading_actions do + = link_to t('two_factor_authentication.disable'), disable_settings_two_factor_authentication_methods_path, class: 'button button--destructive', method: :post + +%p.hint + %span.positive-hint + = fa_icon 'check' + = ' ' + = t 'two_factor_authentication.enabled' + +.table-wrapper + %table.table + %thead + %tr + %th= t('two_factor_authentication.methods') + %th + %tbody + %tr + %td= t('two_factor_authentication.otp') + %td + = table_link_to 'pencil', t('two_factor_authentication.edit'), settings_otp_authentication_path, method: :post + %tr + %td= t('two_factor_authentication.webauthn') + - if current_user.webauthn_enabled? + %td + = table_link_to 'pencil', t('two_factor_authentication.edit'), settings_webauthn_credentials_path, method: :get + - else + %td + = table_link_to 'key', t('two_factor_authentication.add'), new_settings_webauthn_credential_path, method: :get + +%hr.spacer/ + +%h3= t('two_factor_authentication.recovery_codes') +%p.muted-hint= t('two_factor_authentication.lost_recovery_codes') + +%hr.spacer/ + +.simple_form + = link_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, data: { method: :post }, class: 'block-button' diff --git a/app/views/settings/two_factor_authentications/show.html.haml b/app/views/settings/two_factor_authentications/show.html.haml deleted file mode 100644 index f1eecd000..000000000 --- a/app/views/settings/two_factor_authentications/show.html.haml +++ /dev/null @@ -1,36 +0,0 @@ -- content_for :page_title do - = t('settings.two_factor_authentication') - -- if current_user.otp_required_for_login - %p.hint - %span.positive-hint - = fa_icon 'check' - = ' ' - = t 'two_factor_authentication.enabled' - - %hr.spacer/ - - = simple_form_for @confirmation, url: settings_two_factor_authentication_path, method: :delete do |f| - .fields-group - = f.input :otp_attempt, wrapper: :with_block_label, hint: t('two_factor_authentication.code_hint'), label: t('simple_form.labels.defaults.otp_attempt'), input_html: { :autocomplete => 'off' }, required: true - - .actions - = f.button :button, t('two_factor_authentication.disable'), type: :submit, class: 'negative' - - %hr.spacer/ - - %h3= t('two_factor_authentication.recovery_codes') - %p.muted-hint= t('two_factor_authentication.lost_recovery_codes') - - %hr.spacer/ - - .simple_form - = link_to t('two_factor_authentication.generate_recovery_codes'), settings_two_factor_authentication_recovery_codes_path, data: { method: :post }, class: 'block-button' - -- else - .simple_form - %p.hint= t('two_factor_authentication.description_html') - - %hr.spacer/ - - = link_to t('two_factor_authentication.setup'), settings_two_factor_authentication_path, data: { method: :post }, class: 'block-button' diff --git a/app/views/user_mailer/webauthn_credential_added.html.haml b/app/views/user_mailer/webauthn_credential_added.html.haml new file mode 100644 index 000000000..81de84b56 --- /dev/null +++ b/app/views/user_mailer/webauthn_credential_added.html.haml @@ -0,0 +1,44 @@ +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.hero + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center.padded + %table.hero-icon{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td + = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: '' + + %h1= t 'devise.mailer.webauthn_credential.added.title' + %p.lead= "#{t 'devise.mailer.webauthn_credential.added.explanation' }:" + %p.lead= @webauthn_credential.nickname + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.content-start + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.button-cell + %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.button-primary + = link_to edit_user_registration_url do + %span= t('settings.account_settings') diff --git a/app/views/user_mailer/webauthn_credential_added.text.erb b/app/views/user_mailer/webauthn_credential_added.text.erb new file mode 100644 index 000000000..4319dddbf --- /dev/null +++ b/app/views/user_mailer/webauthn_credential_added.text.erb @@ -0,0 +1,7 @@ +<%= t 'devise.mailer.two_factor_enabled.title' %> + +=== + +<%= t 'devise.mailer.two_factor_enabled.explanation' %> + +=> <%= edit_user_registration_url %> diff --git a/app/views/user_mailer/webauthn_credential_deleted.html.haml b/app/views/user_mailer/webauthn_credential_deleted.html.haml new file mode 100644 index 000000000..7b47f0c88 --- /dev/null +++ b/app/views/user_mailer/webauthn_credential_deleted.html.haml @@ -0,0 +1,44 @@ +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.hero + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center.padded + %table.hero-icon.alert-icon{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td + = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: '' + + %h1= t 'devise.mailer.webauthn_credential.deleted.title' + %p.lead= "#{t 'devise.mailer.webauthn_credential.deleted.explanation' }:" + %p.lead= @webauthn_credential.nickname + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.content-start + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.button-cell + %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.button-primary + = link_to edit_user_registration_url do + %span= t('settings.account_settings') diff --git a/app/views/user_mailer/webauthn_credential_deleted.text.erb b/app/views/user_mailer/webauthn_credential_deleted.text.erb new file mode 100644 index 000000000..53e5bc78c --- /dev/null +++ b/app/views/user_mailer/webauthn_credential_deleted.text.erb @@ -0,0 +1,7 @@ +<%= t 'devise.mailer.webauthn_credential.deleted.title' %> + +=== + +<%= t 'devise.mailer.webauthn_credential.deleted.explanation' %> + +=> <%= edit_user_registration_url %> diff --git a/app/views/user_mailer/webauthn_disabled.html.haml b/app/views/user_mailer/webauthn_disabled.html.haml new file mode 100644 index 000000000..81a2a7954 --- /dev/null +++ b/app/views/user_mailer/webauthn_disabled.html.haml @@ -0,0 +1,43 @@ +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.hero + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center.padded + %table.hero-icon.alert-icon{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td + = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: '' + + %h1= t 'devise.mailer.webauthn_disabled.title' + %p.lead= t 'devise.mailer.webauthn_disabled.explanation' + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.content-start + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.button-cell + %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.button-primary + = link_to edit_user_registration_url do + %span= t('settings.account_settings') diff --git a/app/views/user_mailer/webauthn_disabled.text.erb b/app/views/user_mailer/webauthn_disabled.text.erb new file mode 100644 index 000000000..962df77ca --- /dev/null +++ b/app/views/user_mailer/webauthn_disabled.text.erb @@ -0,0 +1,7 @@ +<%= t 'devise.mailer.webauthn_disabled.title' %> + +=== + +<%= t 'devise.mailer.webauthn_disabled.explanation' %> + +=> <%= edit_user_registration_url %> diff --git a/app/views/user_mailer/webauthn_enabled.html.haml b/app/views/user_mailer/webauthn_enabled.html.haml new file mode 100644 index 000000000..f08e764e8 --- /dev/null +++ b/app/views/user_mailer/webauthn_enabled.html.haml @@ -0,0 +1,43 @@ +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.hero + .email-row + .col-6 + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.text-center.padded + %table.hero-icon{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td + = image_tag full_pack_url('media/images/mailer/icon_lock_open.png'), alt: '' + + %h1= t 'devise.mailer.webauthn_enabled.title' + %p.lead= t 'devise.mailer.webauthn_enabled.explanation' + +%table.email-table{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.email-body + .email-container + %table.content-section{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.content-cell.content-start + %table.column{ cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.column-cell.button-cell + %table.button{ align: 'center', cellspacing: 0, cellpadding: 0 } + %tbody + %tr + %td.button-primary + = link_to edit_user_registration_url do + %span= t('settings.account_settings') diff --git a/app/views/user_mailer/webauthn_enabled.text.erb b/app/views/user_mailer/webauthn_enabled.text.erb new file mode 100644 index 000000000..4c233fefb --- /dev/null +++ b/app/views/user_mailer/webauthn_enabled.text.erb @@ -0,0 +1,7 @@ +<%= t 'devise.mailer.webauthn_credentia.added.title' %> + +=== + +<%= t 'devise.mailer.webauthn_credentia.added.explanation' %> + +=> <%= edit_user_registration_url %> |