app/controllers/admin/security_controller.rb



require 'rqrcode'

class Admin::SecurityController < ApplicationController
  before_action :authenticate_user!
  before_action :set_user
  before_action :set_template_names
  before_action :ensure_otp_secret, only: %i[show edit]
  before_action :set_two_factor_variables, only: %i[show edit]

  def show
    set_standard_body_style
    render :edit
  end

  def edit
    render
  end

  def update
    if @user.update(security_params)
      sign_out(@user)
      redirect_to new_user_session_path, notice: t('security_controller.password_updated')
    else
      flash[:error] = t('security_controller.error_updating_password')
      render :edit
    end
  end

  def verify_two_factor
    if @user.validate_and_consume_otp!(params[:otp_attempt])
      @user.update!(otp_required_for_login: true)
      redirect_to admin_security_path, notice: t('security_controller.two_factor_enabled')
    else
      flash[:error] = t('security_controller.two_factor_invalid_code')
      redirect_to admin_security_path
    end
  end

  def disable_two_factor
    if @user.update(otp_required_for_login: false, otp_secret: nil)
      redirect_to admin_security_path, notice: t('security_controller.two_factor_disabled')
    else
      flash[:error] = t('security_controller.two_factor_disabled_error')
      redirect_to admin_security_path
    end
  end

  private

  def set_user
    @user = current_user
  end

  def set_template_names
    @controller_name = 'user'
    @template_name = 'security'
  end

  def ensure_otp_secret
    return if @user.otp_secret.present?

    @user.update!(otp_secret: User.generate_otp_secret)
  end

  def set_two_factor_variables
    @two_factor_enabled = @user.otp_required_for_login

    return if @two_factor_enabled

    otp_uri = @user.otp_provisioning_uri(@user.email, issuer: 'TrustyCMS')
    qr = RQRCode::QRCode.new(otp_uri)
    @qr_png_data = qr.as_png(size: 200).to_data_url
  end

  def security_params
    params.require(:user).permit(:password, :password_confirmation)
  end
end