module Devise::Models::TwoFactorable

Public Instance Methods

disable_otp!() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 73
def disable_otp!
  update_attributes!(otp_enabled: false, otp_enabled_on: nil)
end
enable_otp!() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 67
def enable_otp!
  reset_otp_credentials! if otp_persistence_seed.nil?

  update_attributes!(otp_enabled: true, otp_enabled_on: Time.now)
end
generate_otp_challenge!(expires = nil) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 77
def generate_otp_challenge!(expires = nil)
  update_attributes!(otp_session_challenge: SecureRandom.hex,
                     otp_challenge_expires: DateTime.now + (expires || self.class.otp_authentication_timeout))
  otp_session_challenge
end
next_otp_recovery_tokens(number = self.class.otp_recovery_tokens) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 102
def next_otp_recovery_tokens(number = self.class.otp_recovery_tokens)
  (otp_recovery_counter..otp_recovery_counter + number).inject({}) do |h, index|
    h[index] = recovery_otp.at(index)
    h
  end
end
otp_challenge_valid?() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 83
def otp_challenge_valid?
  (otp_challenge_expires.nil? || otp_challenge_expires > Time.now)
end
otp_provisioning_identifier() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 38
def otp_provisioning_identifier
  email
end
otp_provisioning_uri() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 34
def otp_provisioning_uri
  time_based_otp.provisioning_uri(otp_provisioning_identifier)
end
recovery_otp() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 30
def recovery_otp
  @recovery_otp ||= ROTP::HOTP.new(otp_recovery_secret)
end
reset_otp_credentials() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 42
def reset_otp_credentials
  @time_based_otp = nil
  @recovery_otp = nil
  generate_otp_auth_secret
  reset_otp_persistence
  update_attributes!(otp_enabled: false,
                     otp_session_challenge: nil,
                     otp_challenge_expires: nil,
                     otp_recovery_counter: 0)
end
reset_otp_credentials!() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 53
def reset_otp_credentials!
  reset_otp_credentials
  save!
end
reset_otp_persistence() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 58
def reset_otp_persistence
  generate_otp_persistence_seed
end
reset_otp_persistence!() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 62
def reset_otp_persistence!
  reset_otp_persistence
  save!
end
time_based_otp() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 26
def time_based_otp
  @time_based_otp ||= ROTP::TOTP.new(otp_auth_secret, issuer: (self.class.otp_issuer || Rails.application.class.parent_name).to_s)
end
valid_otp_recovery_token?(token)
valid_otp_time_token?(token)
valid_otp_token?(token, recovery = false)
Alias for: validate_otp_token
validate_otp_recovery_token(token) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 109
def validate_otp_recovery_token(token)
  recovery_otp.verify(token, otp_recovery_counter).tap do
    self.otp_recovery_counter += 1
    save!
  end
end
Also aliased as: valid_otp_recovery_token?
validate_otp_time_token(token) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 96
def validate_otp_time_token(token)
  return false if token.blank?
  validate_otp_token_with_drift(token)
end
Also aliased as: valid_otp_time_token?
validate_otp_token(token, recovery = false) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 87
def validate_otp_token(token, recovery = false)
  if recovery
    validate_otp_recovery_token token
  else
    validate_otp_time_token token
  end
end
Also aliased as: valid_otp_token?

Private Instance Methods

drift() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 127
def drift
  self.class.otp_drift_window
end
generate_otp_auth_secret() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 135
def generate_otp_auth_secret
  self.otp_auth_secret = ROTP::Base32.random_base32
  self.otp_recovery_secret = ROTP::Base32.random_base32
end
generate_otp_persistence_seed() click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 131
def generate_otp_persistence_seed
  self.otp_persistence_seed = SecureRandom.hex
end
validate_otp_token_with_drift(token) click to toggle source
# File lib/devise_two_factorable/models/two_factorable.rb, line 119
def validate_otp_token_with_drift(token)
  time_based_otp.verify(
    token,
    drift_behind: drift.minutes.seconds,
    at: Time.now + drift.minutes.seconds / 2
  )
end