rubygems/rubygems.org

View on GitHub
app/models/concerns/user_webauthn_methods.rb

Summary

Maintainability
A
0 mins
Test Coverage
module UserWebauthnMethods
  extend ActiveSupport::Concern

  included do
    has_many :webauthn_credentials, dependent: :destroy
    has_one :webauthn_verification, dependent: :destroy

    after_initialize do
      self.webauthn_id ||= WebAuthn.generate_user_id
    end
  end

  def webauthn_options_for_create
    WebAuthn::Credential.options_for_create(
      user: {
        id: webauthn_id,
        name: display_id
      },
      exclude: webauthn_credentials.pluck(:external_id),
      authenticator_selection: { user_verification: "discouraged", resident_key: "preferred" }
    )
  end

  def webauthn_enabled?
    webauthn_credentials.present?
  end

  def webauthn_disabled?
    webauthn_credentials.none?
  end

  def webauthn_only_with_recovery?
    webauthn_enabled? && totp_disabled? && mfa_hashed_recovery_codes.present?
  end

  def webauthn_options_for_get
    WebAuthn::Credential.options_for_get(
      allow: webauthn_credentials.pluck(:external_id),
      user_verification: "discouraged"
    )
  end

  def refresh_webauthn_verification
    self.webauthn_verification = WebauthnVerification.create(
      path_token: SecureRandom.base58(16),
      path_token_expires_at: 2.minutes.from_now,
      user_id: id
    )
  end

  private

  def verify_webauthn_otp(otp)
    webauthn_verification&.verify_otp(otp)
  end
end