scinote-web/app/controllers/users/sessions_controller.rb

142 lines
3.9 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
2016-02-12 23:52:43 +08:00
class Users::SessionsController < Devise::SessionsController
layout :session_layout
2020-07-01 20:41:55 +08:00
after_action :after_sign_in, only: %i(create authenticate_with_two_factor)
before_action :remove_authenticate_mesasge_if_root_path, only: :new
2022-08-08 18:24:50 +08:00
prepend_before_action :skip_timeout, only: :expire_in
rescue_from ActionController::InvalidAuthenticityToken do
redirect_to new_user_session_path
end
2016-02-12 23:52:43 +08:00
# GET /resource/sign_in
def new
@simple_sign_in = params[:simple_sign_in] == 'true'
2018-11-26 21:23:26 +08:00
# If user was redirected here from OAuth's authorize/new page (Doorkeeper
# endpoint for authorizing an OAuth client), 3rd party sign-in buttons
# (e.g. LinkedIn) should be hidden. See config/initializers/devise.rb.
2018-11-27 17:58:51 +08:00
@oauth_authorize = session['oauth_authorize'] == true
super
end
2016-02-12 23:52:43 +08:00
# POST /resource/sign_in
def create
2021-05-05 02:51:34 +08:00
super do |user|
if redirect_to_two_factor_auth?(user)
2021-09-28 18:27:51 +08:00
initial_page = stored_location_for(:user)
2021-05-05 02:51:34 +08:00
sign_out
session[:otp_user_id] = user.id
2021-09-28 18:27:51 +08:00
store_location_for(:user, initial_page)
2021-05-05 02:51:34 +08:00
redirect_to users_two_factor_auth_path
return
end
end
generate_templates_project
end
2022-08-08 18:24:50 +08:00
def expire_in
return render body: nil, status: :unauthorized if current_user.blank?
2022-11-30 19:03:27 +08:00
if current_user.remember_created_at.nil? || (current_user.remember_created_at + Devise.remember_for).past?
render plain: (Devise.timeout_in.to_i - (Time.now.to_i - user_session['last_request_at']).round) * 1000
2022-08-08 18:24:50 +08:00
else
2022-11-30 19:03:27 +08:00
render plain: [(Devise.remember_for - (Time.now.to_i - current_user.remember_created_at.to_i).round) * 1000,
(Devise.timeout_in.to_i - (Time.now.to_i - user_session['last_request_at']).round) * 1000].max
2022-08-08 18:24:50 +08:00
end
end
def revive_session; end
2020-07-13 15:51:04 +08:00
def two_factor_recovery
unless session[:otp_user_id]
redirect_to new_user_session_path
end
end
2016-02-12 23:52:43 +08:00
2021-05-05 02:51:34 +08:00
def two_factor_auth
2021-09-28 18:27:51 +08:00
@initial_page = stored_location_for(:user)
2021-05-05 02:51:34 +08:00
end
2016-02-12 23:52:43 +08:00
def after_sign_in
flash[:system_notification_modal] = true
end
2020-06-30 20:16:00 +08:00
def authenticate_with_two_factor
user = User.find_by(id: session[:otp_user_id])
unless user
flash[:alert] = t('devise.sessions.2fa.no_user_error')
redirect_to root_path && return
end
if user.valid_otp?(params[:otp])
session.delete(:otp_user_id)
sign_in(user)
generate_templates_project
2020-06-30 20:16:00 +08:00
flash[:notice] = t('devise.sessions.signed_in')
2021-09-28 18:27:51 +08:00
redirect_to params[:initial_page] || root_path
2020-06-30 20:16:00 +08:00
else
flash.now[:alert] = t('devise.sessions.2fa.error_message')
render :two_factor_auth
end
end
2020-07-13 15:51:04 +08:00
def authenticate_with_recovery_code
user = User.find_by(id: session[:otp_user_id])
unless user
flash[:alert] = t('devise.sessions.2fa.no_user_error')
redirect_to root_path && return
end
session.delete(:otp_user_id)
if user.recover_2fa!(params[:recovery_code])
sign_in(user)
generate_templates_project
2020-07-13 15:51:04 +08:00
flash[:notice] = t('devise.sessions.signed_in')
2020-07-13 22:05:23 +08:00
redirect_to root_path
2020-07-13 15:51:04 +08:00
else
2020-07-13 22:05:23 +08:00
flash[:alert] = t("devise.sessions.2fa_recovery.not_correct_code")
redirect_to new_user_session_path
2020-07-13 15:51:04 +08:00
end
2020-07-13 22:05:23 +08:00
2020-07-13 15:51:04 +08:00
end
2020-07-22 18:37:18 +08:00
private
2022-08-08 18:24:50 +08:00
def skip_timeout
request.env['devise.skip_trackable'] = true
end
2020-07-22 18:37:18 +08:00
def remove_authenticate_mesasge_if_root_path
if session[:user_return_to] == root_path && flash[:alert] == I18n.t('devise.failure.unauthenticated')
flash[:alert] = nil
end
end
def generate_templates_project
2020-06-30 20:16:00 +08:00
# Schedule templates creation for user
TemplatesService.new.schedule_creation_for_user(current_user)
rescue StandardError => e
Rails.logger.fatal("User ID #{current_user.id}: Error creating inital projects on sign_in: #{e.message}")
end
def session_layout
if @simple_sign_in
'sign_in_halt'
else
'layouts/main'
end
end
2021-05-05 23:29:21 +08:00
def bypass_two_factor_auth?
false
end
def redirect_to_two_factor_auth?(user)
user.two_factor_auth_enabled? && !bypass_two_factor_auth?
end
2016-02-12 23:52:43 +08:00
end