class MfaController < ApplicationController layout :determine_layout skip_authentication only: [ :verify, :verify_code ] def new redirect_to root_path if Current.user.otp_required? Current.user.setup_mfa! unless Current.user.otp_secret.present? end def create if Current.user.verify_otp?(params[:code]) Current.user.enable_mfa! @backup_codes = Current.user.otp_backup_codes render :backup_codes else Current.user.disable_mfa! redirect_to new_mfa_path, alert: t(".invalid_code") end end def verify @user = User.find_by(id: session[:mfa_user_id]) if @user.nil? redirect_to new_session_path end end def verify_code @user = User.find_by(id: session[:mfa_user_id]) if @user&.verify_otp?(params[:code]) session.delete(:mfa_user_id) @session = create_session_for(@user) redirect_to root_path else flash.now[:alert] = t(".invalid_code") render :verify, status: :unprocessable_entity end end def disable Current.user.disable_mfa! redirect_to settings_security_path, notice: t(".success") end private def determine_layout if action_name.in?(%w[verify verify_code]) "auth" else "settings" end end end