Sha256: 946b94801799849a8887152c693824ddeb429821e0f1dc44c6fb6d8dc58689bd

Contents?: true

Size: 1.63 KB

Versions: 4

Compression:

Stored size: 1.63 KB

Contents

# frozen_string_literal: true

module RailsBase::Mfa::Totp
  class ValidateCode < RailsBase::ServiceBase
    include Helper

    delegate :user, to: :context
    delegate :otp_code, to: :context

    def call
      return if validate_and_consume_otp

      context.fail!(message: "Invalid TOTP code")
    end

    def validate_and_consume_otp
      if user.consumed_timestep
        # reconstruct the timestamp of the last consumed timestep
        after_timestamp = user.consumed_timestep * otp.interval
      end

      if otp.verify(otp_code.gsub(/\s+/, ""), drift_behind: User.totp_drift_behind, drift_ahead: User.totp_drift_ahead, after: after_timestamp)
        log(level: :debug, msg: "#{lgp} Correct code provided")
        return consume_otp!
      else
        log(level: :debug, msg: "#{lgp} InValid code provided")
      end

      false
    end

    # An OTP cannot be used more than once in a given timestep
    # Storing timestep of last valid OTP is sufficient to satisfy this requirement
    def consume_otp!
      timestep = Time.now.utc.to_i / otp.interval
      if user.consumed_timestep != timestep
        user.consumed_timestep = timestep
        log(level: :debug, msg: "#{lgp} Consuming timestep based on code input")
        return user.save(validate: false)
      end

      log(level: :debug, msg: "#{lgp} Timestep for code was already consumed. Invalid code")
      false
    end

    def validate!
      raise "Expected user to be a User. " unless User === user
      raise "Expected otp_code to be present" if otp_code.nil?
      raise "Expected `otp_secret` passed in or `otp_secret` present on User" if secret.nil?
    end
  end
end

Version data entries

4 entries across 4 versions & 1 rubygems

Version Path
rails_base-0.82.0 app/services/rails_base/mfa/totp/validate_code.rb
rails_base-0.81.1 app/services/rails_base/mfa/totp/validate_code.rb
rails_base-0.81.0 app/services/rails_base/mfa/totp/validate_code.rb
rails_base-0.80.0 app/services/rails_base/mfa/totp/validate_code.rb