The code powering m.abunchtell.com https://m.abunchtell.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

84 lines
1.9 KiB

  1. # frozen_string_literal: true
  2. class Auth::SessionsController < Devise::SessionsController
  3. include Devise::Controllers::Rememberable
  4. layout 'auth'
  5. skip_before_action :require_no_authentication, only: [:create]
  6. prepend_before_action :authenticate_with_two_factor, if: :two_factor_enabled?, only: [:create]
  7. def create
  8. super do |resource|
  9. remember_me(resource)
  10. flash[:notice] = nil
  11. end
  12. end
  13. def destroy
  14. super
  15. flash[:notice] = nil
  16. end
  17. protected
  18. def find_user
  19. if session[:otp_user_id]
  20. User.find(session[:otp_user_id])
  21. elsif user_params[:email]
  22. User.find_by(email: user_params[:email])
  23. end
  24. end
  25. def user_params
  26. params.require(:user).permit(:email, :password, :otp_attempt)
  27. end
  28. def after_sign_in_path_for(_resource)
  29. last_url = stored_location_for(:user)
  30. if [about_path].include?(last_url)
  31. root_path
  32. else
  33. last_url || root_path
  34. end
  35. end
  36. def two_factor_enabled?
  37. find_user.try(:otp_required_for_login?)
  38. end
  39. def valid_otp_attempt?(user)
  40. user.validate_and_consume_otp!(user_params[:otp_attempt]) ||
  41. user.invalidate_otp_backup_code!(user_params[:otp_attempt])
  42. rescue OpenSSL::Cipher::CipherError => _error
  43. false
  44. end
  45. def authenticate_with_two_factor
  46. user = self.resource = find_user
  47. if user_params[:otp_attempt].present? && session[:otp_user_id]
  48. authenticate_with_two_factor_via_otp(user)
  49. elsif user && user.valid_password?(user_params[:password])
  50. prompt_for_two_factor(user)
  51. end
  52. end
  53. def authenticate_with_two_factor_via_otp(user)
  54. if valid_otp_attempt?(user)
  55. session.delete(:otp_user_id)
  56. remember_me(user)
  57. sign_in(user)
  58. else
  59. flash.now[:alert] = I18n.t('users.invalid_otp_token')
  60. prompt_for_two_factor(user)
  61. end
  62. end
  63. def prompt_for_two_factor(user)
  64. session[:otp_user_id] = user.id
  65. render :two_factor
  66. end
  67. end