Sha256: a7cdaf3cf243b47b9aa33af27ea05c37858353443f5fd56e6268be2454dafd11

Contents?: true

Size: 1.17 KB

Versions: 19

Compression:

Stored size: 1.17 KB

Contents

# frozen_string_literal: true

require 'rotp'
require 'rqrcode'

module QuoVadis
  class Totp < ActiveRecord::Base
    extend Hmacable

    attribute :key, :qv_encrypted, default: -> { ROTP::Base32.random }
    attribute :hmac_key, :string
    attribute :provided_hmac_key, :string

    belongs_to :account

    validate :key_not_tampered_with, if: -> { provided_hmac_key.present? }
    validates :key, presence: true


    def qr_code
      RQRCode::QRCode.new(
        ROTP::TOTP.new(key, issuer: QuoVadis.app_name).provisioning_uri(account.identifier)
      )
    end


    def hmac_key
      self.class.compute_hmac key
    end


    # Returns true and saves the record if `otp` is valid, false otherwise.
    def verify(otp)
      if (_last_used_at = ROTP::TOTP.new(key).verify otp, after: last_used_at)
        self.last_used_at = _last_used_at
        save
      else
        false
      end
    end


    def reused?(otp)
      totp = ROTP::TOTP.new key
      !totp.verify(otp, after: last_used_at) && totp.verify(otp)
    end


    private

    def key_not_tampered_with
      errors.add :key, :invalid unless self.class.timing_safe_eql? provided_hmac_key, hmac_key
    end

  end
end

Version data entries

19 entries across 19 versions & 1 rubygems

Version Path
quo_vadis-2.2.4 app/models/quo_vadis/totp.rb
quo_vadis-2.2.2 app/models/quo_vadis/totp.rb
quo_vadis-2.2.1 app/models/quo_vadis/totp.rb
quo_vadis-2.2.0 app/models/quo_vadis/totp.rb
quo_vadis-2.1.11 app/models/quo_vadis/totp.rb
quo_vadis-2.1.10 app/models/quo_vadis/totp.rb
quo_vadis-2.1.9 app/models/quo_vadis/totp.rb
quo_vadis-2.1.8 app/models/quo_vadis/totp.rb
quo_vadis-2.1.7 app/models/quo_vadis/totp.rb
quo_vadis-2.1.6 app/models/quo_vadis/totp.rb
quo_vadis-2.1.5 app/models/quo_vadis/totp.rb
quo_vadis-2.1.4 app/models/quo_vadis/totp.rb
quo_vadis-2.1.3 app/models/quo_vadis/totp.rb
quo_vadis-2.1.2 app/models/quo_vadis/totp.rb
quo_vadis-2.1.1 app/models/quo_vadis/totp.rb
quo_vadis-2.1.0 app/models/quo_vadis/totp.rb
quo_vadis-2.0.2 app/models/quo_vadis/totp.rb
quo_vadis-2.0.1 app/models/quo_vadis/totp.rb
quo_vadis-2.0.0 app/models/quo_vadis/totp.rb