Added optional two-factor authentication
This commit is contained in:
parent
237cb41ab4
commit
ba192f12e3
16 changed files with 146 additions and 15 deletions
|
@ -7,6 +7,18 @@ code {
|
|||
max-width: 400px;
|
||||
padding: 20px;
|
||||
margin: 0 auto;
|
||||
|
||||
p {
|
||||
font-size: 14px;
|
||||
line-height: 18px;
|
||||
color: $color2;
|
||||
margin-bottom: 20px;
|
||||
|
||||
strong {
|
||||
color: $color5;
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.simple_form {
|
||||
|
@ -118,7 +130,7 @@ code {
|
|||
margin-top: 30px;
|
||||
}
|
||||
|
||||
button {
|
||||
button, .block-button {
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: 0;
|
||||
|
@ -128,6 +140,9 @@ code {
|
|||
font-size: 18px;
|
||||
padding: 10px;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
text-align: center;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
font-weight: 500;
|
||||
outline: 0;
|
||||
|
@ -176,7 +191,7 @@ code {
|
|||
text-align: center;
|
||||
|
||||
a {
|
||||
color: white;
|
||||
color: $color5;
|
||||
text-decoration: none;
|
||||
|
||||
&:hover {
|
||||
|
@ -200,3 +215,16 @@ code {
|
|||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
.qr-code {
|
||||
background: #fff;
|
||||
padding: 4px;
|
||||
margin-bottom: 20px;
|
||||
box-shadow: 0 0 15px rgba($color8, 0.2);
|
||||
display: inline-block;
|
||||
|
||||
svg {
|
||||
display: block;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,8 @@ class Auth::SessionsController < Devise::SessionsController
|
|||
|
||||
layout 'auth'
|
||||
|
||||
before_action :configure_sign_in_params, only: [:create]
|
||||
|
||||
def create
|
||||
super do |resource|
|
||||
remember_me(resource)
|
||||
|
@ -13,6 +15,10 @@ class Auth::SessionsController < Devise::SessionsController
|
|||
|
||||
protected
|
||||
|
||||
def configure_sign_in_params
|
||||
devise_parameter_sanitizer.permit(:sign_in, keys: [:otp_attempt])
|
||||
end
|
||||
|
||||
def after_sign_in_path_for(_resource)
|
||||
last_url = stored_location_for(:user)
|
||||
|
||||
|
|
28
app/controllers/settings/two_factor_auths_controller.rb
Normal file
28
app/controllers/settings/two_factor_auths_controller.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Settings::TwoFactorAuthsController < ApplicationController
|
||||
layout 'auth'
|
||||
|
||||
before_action :authenticate_user!
|
||||
|
||||
def show
|
||||
return unless current_user.otp_required_for_login
|
||||
|
||||
@qrcode = RQRCode::QRCode.new(current_user.otp_provisioning_uri(current_user.email, issuer: Rails.configuration.x.local_domain))
|
||||
end
|
||||
|
||||
def enable
|
||||
current_user.otp_required_for_login = true
|
||||
current_user.otp_secret = User.generate_otp_secret
|
||||
current_user.save!
|
||||
|
||||
redirect_to settings_two_factor_auth_path
|
||||
end
|
||||
|
||||
def disable
|
||||
current_user.otp_required_for_login = false
|
||||
current_user.save!
|
||||
|
||||
redirect_to settings_two_factor_auth_path
|
||||
end
|
||||
end
|
|
@ -3,7 +3,9 @@
|
|||
class User < ApplicationRecord
|
||||
include Settings::Extend
|
||||
|
||||
devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :confirmable
|
||||
devise :registerable, :recoverable,
|
||||
:rememberable, :trackable, :validatable, :confirmable,
|
||||
:two_factor_authenticatable, otp_secret_encryption_key: ENV['OTP_SECRET']
|
||||
|
||||
belongs_to :account, inverse_of: :user
|
||||
accepts_nested_attributes_for :account
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
= simple_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
|
||||
= f.input :email, autofocus: true, placeholder: t('simple_form.labels.defaults.email'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.email') }
|
||||
= f.input :password, placeholder: t('simple_form.labels.defaults.password'), required: true, input_html: { 'aria-label' => t('simple_form.labels.defaults.password') }
|
||||
= f.input :otp_attempt, placeholder: t('simple_form.labels.defaults.otp_attempt'), input_html: { 'aria-label' => t('simple_form.labels.defaults.otp_attempt') }
|
||||
|
||||
.actions
|
||||
= f.button :button, t('auth.login'), type: :submit
|
||||
|
|
|
@ -5,4 +5,6 @@
|
|||
%li= link_to t('settings.preferences'), settings_preferences_path
|
||||
- if controller_name != 'registrations'
|
||||
%li= link_to t('auth.change_password'), edit_user_registration_path
|
||||
%li= link_to t('settings.back'), root_path
|
||||
- if controller_name != 'two_factor_auths'
|
||||
%li= link_to t('settings.two_factor_auth'), settings_two_factor_auth_path
|
||||
%li= link_to t('settings.back'), root_path
|
||||
|
|
17
app/views/settings/two_factor_auths/show.html.haml
Normal file
17
app/views/settings/two_factor_auths/show.html.haml
Normal file
|
@ -0,0 +1,17 @@
|
|||
- content_for :page_title do
|
||||
= t('settings.two_factor_auth')
|
||||
|
||||
- if current_user.otp_required_for_login
|
||||
%p= t('two_factor_auth.instructions_html')
|
||||
|
||||
.qr-code= raw @qrcode.as_svg(padding: 0, module_size: 5)
|
||||
|
||||
.simple_form
|
||||
= link_to t('two_factor_auth.disable'), disable_settings_two_factor_auth_path, data: { method: 'POST' }, class: 'block-button'
|
||||
- else
|
||||
%p= t('two_factor_auth.description_html')
|
||||
|
||||
.simple_form
|
||||
= link_to t('two_factor_auth.enable'), enable_settings_two_factor_auth_path, data: { method: 'POST' }, class: 'block-button'
|
||||
|
||||
.form-footer= render "settings/shared/links"
|
Loading…
Add table
Add a link
Reference in a new issue