recovery_codes.rb 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class Auth::TwoFactor::RecoveryCodes < Auth::TwoFactor::Method
  3. NUMBER_OF_CODES = 10
  4. CODE_LENGTH = 16
  5. def verify(code)
  6. return verify_result(false) if !exists? || code.blank?
  7. configuration = user_two_factor_preference_configuration
  8. hashed_code = configuration[:codes].detect { |saved_code| PasswordHash.verified?(saved_code, code) }
  9. return verify_result(false) if hashed_code.blank?
  10. configuration[:codes].delete(hashed_code)
  11. verify_result(true, new_configuration: configuration)
  12. end
  13. def generate
  14. codes = []
  15. NUMBER_OF_CODES.times do
  16. # The hex string has length 2*n.
  17. codes << SecureRandom.hex(CODE_LENGTH / 2)
  18. end
  19. hashed_codes = codes.map { |code| PasswordHash.crypt(code) }
  20. create_user_config({ codes: hashed_codes })
  21. codes
  22. end
  23. def related_setting_name
  24. 'two_factor_authentication_recovery_codes'
  25. end
  26. def exists?
  27. user_two_factor_preference.present?
  28. end
  29. def user_two_factor_preference
  30. user&.two_factor_preferences&.recovery_codes
  31. end
  32. end