module Rodauth

  1. lib/rodauth.rb
  2. lib/rodauth/features/account_expiration.rb
  3. lib/rodauth/features/active_sessions.rb
  4. lib/rodauth/features/argon2.rb
  5. lib/rodauth/features/audit_logging.rb
  6. lib/rodauth/features/base.rb
  7. lib/rodauth/features/change_login.rb
  8. lib/rodauth/features/change_password.rb
  9. lib/rodauth/features/change_password_notify.rb
  10. lib/rodauth/features/close_account.rb
  11. lib/rodauth/features/close_account_email.rb
  12. lib/rodauth/features/confirm_password.rb
  13. lib/rodauth/features/create_account.rb
  14. lib/rodauth/features/disallow_common_passwords.rb
  15. lib/rodauth/features/disallow_password_reuse.rb
  16. lib/rodauth/features/email_auth.rb
  17. lib/rodauth/features/email_base.rb
  18. lib/rodauth/features/http_basic_auth.rb
  19. lib/rodauth/features/internal_request.rb
  20. lib/rodauth/features/json.rb
  21. lib/rodauth/features/jwt.rb
  22. lib/rodauth/features/jwt_cors.rb
  23. lib/rodauth/features/jwt_refresh.rb
  24. lib/rodauth/features/lockout.rb
  25. lib/rodauth/features/login.rb
  26. lib/rodauth/features/login_password_requirements_base.rb
  27. lib/rodauth/features/logout.rb
  28. lib/rodauth/features/otp.rb
  29. lib/rodauth/features/otp_lockout_email.rb
  30. lib/rodauth/features/otp_modify_email.rb
  31. lib/rodauth/features/otp_unlock.rb
  32. lib/rodauth/features/password_complexity.rb
  33. lib/rodauth/features/password_expiration.rb
  34. lib/rodauth/features/password_grace_period.rb
  35. lib/rodauth/features/password_pepper.rb
  36. lib/rodauth/features/path_class_methods.rb
  37. lib/rodauth/features/recovery_codes.rb
  38. lib/rodauth/features/remember.rb
  39. lib/rodauth/features/require_domain.rb
  40. lib/rodauth/features/require_hmac_secret.rb
  41. lib/rodauth/features/reset_password.rb
  42. lib/rodauth/features/reset_password_notify.rb
  43. lib/rodauth/features/reset_password_verifies_account.rb
  44. lib/rodauth/features/session_expiration.rb
  45. lib/rodauth/features/single_session.rb
  46. lib/rodauth/features/sms_codes.rb
  47. lib/rodauth/features/two_factor_base.rb
  48. lib/rodauth/features/update_password_hash.rb
  49. lib/rodauth/features/verify_account.rb
  50. lib/rodauth/features/verify_account_grace_period.rb
  51. lib/rodauth/features/verify_login_change.rb
  52. lib/rodauth/features/webauthn.rb
  53. lib/rodauth/features/webauthn_autofill.rb
  54. lib/rodauth/features/webauthn_login.rb
  55. lib/rodauth/features/webauthn_modify_email.rb
  56. lib/rodauth/features/webauthn_verify_account.rb
  57. lib/rodauth/migrations.rb
  58. lib/rodauth/version.rb
  59. show all

:nocov:

:nocov:

Methods

Public Class

  1. configure
  2. create_database_authentication_functions
  3. create_database_previous_password_check_functions
  4. drop_database_authentication_functions
  5. drop_database_previous_password_check_functions
  6. lib
  7. load_dependencies
  8. new
  9. version

Public Instance

  1. _account_from_email_auth_key
  2. _account_from_id
  3. _account_from_login
  4. _account_from_refresh_token
  5. _account_from_reset_password_key
  6. _account_from_session
  7. _account_from_unlock_key
  8. _account_from_verify_account_key
  9. _account_from_verify_login_change_key
  10. _account_refresh_token_split
  11. _around_rodauth
  12. _email_auth_request
  13. _field_attributes
  14. _field_error_attributes
  15. _filter_links
  16. _formatted_field_error
  17. _get_remember_cookie
  18. _initialize_instance_variables
  19. _json_response_body
  20. _jwt_decode_opts
  21. _jwt_decode_secrets
  22. _login
  23. _login_form_footer
  24. _login_form_footer_links
  25. _login_response
  26. _merge_fixed_locals_opts
  27. _multi_phase_login_forms
  28. _new_account
  29. _otp
  30. _otp_add_key
  31. _otp_for_key
  32. _otp_interval
  33. _otp_key
  34. _otp_tmp_key
  35. _otp_valid_code?
  36. _otp_valid_code_for_old_secret
  37. _override_webauthn_credential_response_verify
  38. _process_raw_hmac
  39. _recovery_codes
  40. _return_json_response
  41. _set_otp_unlock_info
  42. _set_remember_cookie
  43. _setup_account_lockouts_hash
  44. _sms_request_response
  45. _template_opts
  46. _two_factor_auth_links
  47. _two_factor_auth_response
  48. _two_factor_remove_all_from_session
  49. _two_factor_remove_links
  50. _two_factor_setup_links
  51. _update_login
  52. _view
  53. _view_opts
  54. account!
  55. account_activity_ds
  56. account_ds
  57. account_expired?
  58. account_expired_at
  59. account_from_email_auth_key
  60. account_from_id
  61. account_from_key
  62. account_from_login
  63. account_from_refresh_token
  64. account_from_remember_cookie
  65. account_from_reset_password_key
  66. account_from_session
  67. account_from_unlock_key
  68. account_from_verify_account_key
  69. account_from_verify_login_change_key
  70. account_from_webauthn_login
  71. account_id
  72. account_id_or_session_value
  73. account_in_unverified_grace_period?
  74. account_initial_status_value
  75. account_lockouts_ds
  76. account_login_failures_ds
  77. account_password_hash_column
  78. account_reload
  79. account_session_status_filter
  80. account_table_ds
  81. account_webauthn_ids
  82. account_webauthn_usage
  83. account_webauthn_user_id
  84. active_remember_key_ds
  85. active_sessions_ds
  86. active_sessions_insert_hash
  87. active_sessions_update_hash
  88. add_active_session
  89. add_audit_log
  90. add_field_error_class
  91. add_previous_password_hash
  92. add_recovery_code
  93. add_recovery_codes
  94. add_remember_key
  95. add_webauthn_credential
  96. after_change_password
  97. after_close_account
  98. after_create_account
  99. after_login
  100. after_login_entered_during_multi_phase_login
  101. after_login_failure
  102. after_logout
  103. after_otp_authentication_failure
  104. after_otp_disable
  105. after_otp_setup
  106. after_otp_unlock_auth_failure
  107. after_otp_unlock_auth_success
  108. after_otp_unlock_not_yet_available
  109. after_refresh_token
  110. after_reset_password
  111. after_sms_confirm
  112. after_sms_disable
  113. after_webauthn_remove
  114. after_webauthn_setup
  115. allow_email_auth?
  116. allow_param_fallback_for_session_param?
  117. allow_resending_verify_account_email?
  118. already_logged_in
  119. apply_key_for_update
  120. argon2_hash_algorithm?
  121. argon2_hash_cost
  122. argon2_password_hash_match?
  123. argon2_password_hash_using_salt_and_secret
  124. argon2_salt_option
  125. audit_log_ds
  126. audit_log_insert_hash
  127. audit_log_message
  128. audit_log_message_default
  129. audit_log_metadata
  130. auth_class_eval
  131. authenticated?
  132. authenticated_by
  133. authenticated_webauthn_id
  134. auto_add_missing_recovery_codes
  135. auto_remove_recovery_codes
  136. autocomplete_for_field?
  137. autologin_session
  138. autologin_type
  139. base32_encode
  140. base_url
  141. before_change_login_route
  142. before_change_password_route
  143. before_create_account_route
  144. before_login_attempt
  145. before_logout
  146. before_otp_setup
  147. before_otp_setup_route
  148. before_reset_password
  149. before_reset_password_request
  150. before_rodauth
  151. before_sms_confirm
  152. before_two_factor_auth_route
  153. before_two_factor_manage_route
  154. before_unlock_account
  155. before_unlock_account_request
  156. before_verify_account
  157. before_verify_account_route
  158. before_view_recovery_codes
  159. before_webauthn_auth_route
  160. before_webauthn_login_route
  161. before_webauthn_remove_route
  162. before_webauthn_setup
  163. before_webauthn_setup_route
  164. button
  165. button_fixed_locals
  166. button_opts
  167. can_add_recovery_codes?
  168. catch_error
  169. change_login
  170. change_login_notice_flash
  171. change_login_requires_password?
  172. change_password_requires_password?
  173. check_account_expiration
  174. check_active_session
  175. check_already_logged_in
  176. check_csrf
  177. check_csrf?
  178. check_password_change_allowed
  179. check_session_expiration
  180. check_single_session
  181. clear_cached_otp
  182. clear_invalid_login_attempts
  183. clear_session
  184. clear_tokens
  185. close_account
  186. close_account_requires_password?
  187. compute_hmac
  188. compute_hmacs
  189. compute_old_hmac
  190. compute_raw_hmac
  191. compute_raw_hmac_with_secret
  192. confirm_password
  193. confirm_password_redirect
  194. convert_email_token_key
  195. convert_response_header_key
  196. convert_session_key
  197. convert_timestamp
  198. convert_token_id
  199. convert_token_id_to_integer
  200. convert_token_key
  201. create_account_autologin?
  202. create_account_notice_flash
  203. create_account_set_password?
  204. create_email
  205. create_email_auth_key
  206. create_email_to
  207. create_reset_password_key
  208. create_verify_account_key
  209. create_verify_login_change_email
  210. create_verify_login_change_key
  211. csrf_tag
  212. currently_active_session?
  213. database_function_password_match?
  214. db
  215. delete_account
  216. delete_account_on_close?
  217. disable_remember_login
  218. domain
  219. email_auth_ds
  220. email_auth_email_link
  221. email_auth_email_recently_sent?
  222. email_auth_key_insert_hash
  223. email_auth_request_form
  224. email_from
  225. email_to
  226. expire_session
  227. extend_remember_deadline
  228. extend_remember_deadline_while_logged_in?
  229. extract_password_hash_cost
  230. features
  231. field_attributes
  232. field_error
  233. field_error_attributes
  234. flash
  235. forget_login
  236. formatted_field_error
  237. function_name
  238. generate_active_sessions_key
  239. generate_email_auth_key_value
  240. generate_refresh_token
  241. generate_remember_key_value
  242. generate_reset_password_key_value
  243. generate_unlock_account_key
  244. generate_verify_account_key_value
  245. generate_verify_login_change_key_value
  246. get_active_refresh_token
  247. get_activity_timestamp
  248. get_email_auth_email_last_sent
  249. get_email_auth_key
  250. get_password_changed_at
  251. get_password_hash
  252. get_password_reset_key
  253. get_remember_key
  254. get_reset_password_email_last_sent
  255. get_reset_password_key
  256. get_unlock_account_email_last_sent
  257. get_unlock_account_key
  258. get_verify_account_email_last_sent
  259. get_verify_account_key
  260. get_verify_login_change_login_and_key
  261. handle_duplicate_active_session_id
  262. handle_invalid_reset_password_key
  263. handle_invalid_verify_account_key
  264. handle_webauthn_sign_count_verification_error
  265. has_password?
  266. hmac_secret_rotation?
  267. hook_action
  268. http_basic_auth
  269. inactive_session_cond
  270. include_success_messages?
  271. input_field_string
  272. inputmode_for_field?
  273. instance_variables_to_inspect
  274. internal_request?
  275. internal_request_configuration
  276. invalid_login_attempted
  277. invalid_previous_password_message
  278. json_request?
  279. json_response
  280. json_response_error?
  281. jwt_cors_allow?
  282. jwt_payload
  283. jwt_refresh_token_account_ds
  284. jwt_refresh_token_account_token_ds
  285. jwt_refresh_token_ds
  286. jwt_refresh_token_insert_hash
  287. jwt_refresh_token_match?
  288. jwt_secret
  289. jwt_session_hash
  290. jwt_token
  291. last_account_activity_at
  292. last_account_login_at
  293. load_memory
  294. loaded_templates
  295. locked_out?
  296. logged_in_via_remember_key?
  297. login
  298. login_confirm_label
  299. login_confirmation_matches?
  300. login_does_not_meet_requirements_message
  301. login_failed_reset_password_request_form
  302. login_field_autocomplete_value
  303. login_form_footer_links
  304. login_hidden_field
  305. login_input_type
  306. login_meets_email_requirements?
  307. login_meets_length_requirements?
  308. login_meets_requirements?
  309. login_param_value
  310. login_required
  311. login_return_to_requested_location_path
  312. login_session
  313. login_too_long_message
  314. login_too_many_bytes_message
  315. login_too_short_message
  316. login_uses_email?
  317. login_valid_email?
  318. logout
  319. logout_additional_form_tags
  320. missing_recommended_configuration
  321. modifications_require_password?
  322. new_account
  323. new_password_matches_current_password?
  324. new_recovery_code
  325. new_webauthn_credential
  326. no_longer_active_session
  327. normalize_login
  328. normalize_session_or_flash_key
  329. null_byte_parameter_value
  330. only_json?
  331. open_account?
  332. otp_add_key
  333. otp_available?
  334. otp_exists?
  335. otp_hmac_old_secret
  336. otp_hmac_secret
  337. otp_issuer
  338. otp_key_ds
  339. otp_keys_use_hmac?
  340. otp_last_use
  341. otp_locked_out?
  342. otp_lockout_redirect
  343. otp_new_secret
  344. otp_provisioning_name
  345. otp_provisioning_uri
  346. otp_qr_code
  347. otp_record_authentication_failure
  348. otp_remove
  349. otp_remove_auth_failures
  350. otp_tmp_key
  351. otp_unlock_auth_failure
  352. otp_unlock_auth_success
  353. otp_unlock_available?
  354. otp_unlock_data
  355. otp_unlock_deadline
  356. otp_unlock_deadline_passed?
  357. otp_unlock_ds
  358. otp_unlock_next_auth_attempt_after
  359. otp_unlock_not_available_set_refresh_header
  360. otp_unlock_num_successes
  361. otp_unlock_refresh_tag
  362. otp_unlock_reset
  363. otp_unlock_success_cooldown_seconds
  364. otp_update_last_use
  365. otp_user_key
  366. otp_valid_code?
  367. otp_valid_key?
  368. over_max_bytesize_param_value
  369. param
  370. param_or_nil
  371. password_bytesize
  372. password_confirm_label
  373. password_does_not_contain_null_byte?
  374. password_does_not_meet_requirements_message
  375. password_doesnt_match_previous_password?
  376. password_expiration_ds
  377. password_expired?
  378. password_field_autocomplete_value
  379. password_has_enough_character_groups?
  380. password_has_no_invalid_pattern?
  381. password_hash
  382. password_hash_cost
  383. password_hash_ds
  384. password_hash_match?
  385. password_hash_using_salt
  386. password_match?
  387. password_meets_length_requirements?
  388. password_meets_requirements?
  389. password_not_in_dictionary?
  390. password_not_one_of_the_most_common?
  391. password_not_too_many_repeating_characters?
  392. password_one_of_most_common?
  393. password_recently_entered?
  394. password_reset_ds
  395. password_too_long_message
  396. password_too_many_bytes_message
  397. password_too_short_message
  398. possible_authentication_methods
  399. post_configure
  400. previous_password_ds
  401. raises_uniqueness_violation?
  402. random_key
  403. raw_param
  404. recovery_code_match?
  405. recovery_codes_available?
  406. recovery_codes_ds
  407. recovery_codes_primary?
  408. recovery_codes_remove
  409. redirect
  410. remember_key_ds
  411. remember_login
  412. remembered_session_id
  413. remove_active_session
  414. remove_all_active_sessions
  415. remove_all_active_sessions_except_current
  416. remove_all_active_sessions_except_for
  417. remove_all_webauthn_keys_and_user_ids
  418. remove_current_session
  419. remove_email_auth_key
  420. remove_inactive_sessions
  421. remove_jwt_refresh_token_key
  422. remove_lockout_metadata
  423. remove_remember_key
  424. remove_reset_password_key
  425. remove_session_value
  426. remove_verify_account_key
  427. remove_verify_login_change_key
  428. remove_webauthn_key
  429. render
  430. render_multi_phase_login_forms
  431. request
  432. require_account
  433. require_account_session
  434. require_authentication
  435. require_current_password
  436. require_http_basic_auth
  437. require_login
  438. require_login_confirmation?
  439. require_login_redirect
  440. require_otp_setup
  441. require_password_authentication
  442. require_password_authentication?
  443. require_response
  444. require_sms_available
  445. require_sms_not_setup
  446. require_sms_setup
  447. require_two_factor_authenticated
  448. require_two_factor_not_authenticated
  449. require_two_factor_setup
  450. require_webauthn_setup
  451. rescue_jwt_payload
  452. reset_password_account_status_value
  453. reset_password_email_link
  454. reset_password_email_recently_sent?
  455. reset_password_key_insert_hash
  456. reset_password_request_for_unverified_account
  457. reset_single_session_key
  458. response
  459. retry_on_uniqueness_violation
  460. return_json_response
  461. return_response
  462. route!
  463. route_path
  464. route_url
  465. save_account
  466. select_key_for_update!
  467. send_email
  468. send_verify_login_change_email
  469. serialize_audit_log_metadata
  470. session
  471. session_inactivity_deadline_condition
  472. session_jwt
  473. session_lifetime_deadline_condition
  474. session_param
  475. session_value
  476. set_account
  477. set_deadline_value
  478. set_deadline_values?
  479. set_email_auth_email_last_sent
  480. set_error_flash
  481. set_error_reason
  482. set_expired
  483. set_field_error
  484. set_http_basic_auth_error_response
  485. set_jwt
  486. set_jwt_refresh_token_hmac_session_key
  487. set_jwt_token
  488. set_last_password_entry
  489. set_login_requirement_error_message
  490. set_new_account_password
  491. set_notice_flash
  492. set_notice_now_flash
  493. set_password
  494. set_password_requirement_error_message
  495. set_redirect_error_flash
  496. set_redirect_error_status
  497. set_remember_cookie
  498. set_reset_password_email_last_sent
  499. set_response_error_reason_status
  500. set_response_error_status
  501. set_response_header
  502. set_session_return_to_path
  503. set_session_value
  504. set_single_session_key
  505. set_title
  506. set_unlock_account_email_last_sent
  507. set_verify_account_email_last_sent
  508. setup_account_verification
  509. show_lockout_page
  510. show_otp_auth_link?
  511. single_session_ds
  512. skip_login_field_on_login?
  513. skip_password_field_on_login?
  514. skip_status_checks?
  515. sms
  516. sms_auth_message
  517. sms_available?
  518. sms_code
  519. sms_code_issued_at
  520. sms_code_match?
  521. sms_codes_primary?
  522. sms_confirm
  523. sms_confirm_failure
  524. sms_confirm_message
  525. sms_confirmation_match?
  526. sms_current_auth?
  527. sms_disable
  528. sms_ds
  529. sms_failures
  530. sms_locked_out?
  531. sms_needs_confirmation?
  532. sms_needs_confirmation_notice_flash
  533. sms_new_auth_code
  534. sms_new_confirm_code
  535. sms_normalize_phone
  536. sms_phone
  537. sms_record_failure
  538. sms_remove_expired_confirm_code
  539. sms_remove_failures
  540. sms_send
  541. sms_send_auth_code
  542. sms_send_confirm_code
  543. sms_set_code
  544. sms_setup
  545. sms_setup?
  546. sms_valid_phone?
  547. split_token
  548. template_path
  549. throw_basic_auth_error
  550. throw_error
  551. throw_error_reason
  552. throw_error_status
  553. throw_rodauth_error
  554. timing_safe_eql?
  555. token_link
  556. token_param_value
  557. transaction
  558. translate
  559. two_factor_auth_links
  560. two_factor_authenticate
  561. two_factor_authenticated?
  562. two_factor_authentication_setup?
  563. two_factor_login_type_match?
  564. two_factor_modifications_require_password?
  565. two_factor_partially_authenticated?
  566. two_factor_password_match?
  567. two_factor_remove
  568. two_factor_remove_auth_failures
  569. two_factor_remove_links
  570. two_factor_remove_session
  571. two_factor_setup_links
  572. two_factor_update_session
  573. unique_constraint_violation_class
  574. unlock_account
  575. unlock_account_email_link
  576. unlock_account_email_recently_sent?
  577. unlock_account_key
  578. unlock_account_key_value
  579. unverified_grace_period_expired?
  580. update_account
  581. update_activity
  582. update_current_session?
  583. update_hash_ds
  584. update_last_activity
  585. update_last_login
  586. update_login
  587. update_password_changed_at
  588. update_password_hash?
  589. update_session
  590. update_single_session_key
  591. update_sms
  592. use_database_authentication_functions?
  593. use_date_arithmetic?
  594. use_json?
  595. use_jwt?
  596. use_multi_phase_login?
  597. use_request_specific_csrf_tokens?
  598. use_scope_clear_session?
  599. uses_instance_variables
  600. uses_two_factor_authentication?
  601. valid_jwt?
  602. valid_login_entered?
  603. valid_new_webauthn_credential?
  604. valid_return_to_path?
  605. valid_webauthn_credential_auth?
  606. verified_account?
  607. verify_account
  608. verify_account_check_already_logged_in
  609. verify_account_ds
  610. verify_account_email_link
  611. verify_account_email_recently_sent?
  612. verify_account_email_resend
  613. verify_account_key_insert_hash
  614. verify_account_set_password?
  615. verify_account_view
  616. verify_login_change
  617. verify_login_change_account_status_value
  618. verify_login_change_ds
  619. verify_login_change_email_body
  620. verify_login_change_email_link
  621. verify_login_change_key_insert_hash
  622. verify_login_change_old_login
  623. view
  624. webauthn_account_id
  625. webauthn_allow
  626. webauthn_auth_additional_form_tags
  627. webauthn_auth_credential_from_form_submission
  628. webauthn_auth_data
  629. webauthn_auth_form_path
  630. webauthn_authenticator_selection
  631. webauthn_create_relying_party_opts
  632. webauthn_credential_options_for_get
  633. webauthn_extensions
  634. webauthn_form_submission_call
  635. webauthn_key_insert_hash
  636. webauthn_keys_ds
  637. webauthn_login_options?
  638. webauthn_login_verification_factor?
  639. webauthn_modification_authenticated?
  640. webauthn_origin
  641. webauthn_relying_party
  642. webauthn_remove_authenticated_session
  643. webauthn_rp_id
  644. webauthn_rp_name
  645. webauthn_setup?
  646. webauthn_setup_credential_from_form_submission
  647. webauthn_setup_data
  648. webauthn_update_session
  649. webauthn_user_ids_ds
  650. webauthn_user_name
  651. webauthn_user_verification

Constants

FEATURES = {}  
INVALID_DOMAIN = "invalidurl @@.com"  
MAJOR = 2  

The major version of Rodauth, updated only for major changes that are likely to require modification to apps using Rodauth.

MINOR = 47  

The minor version of Rodauth, updated for new feature releases of Rodauth.

OPTS = {}.freeze  
SCOPE_INSTANCE_VARIABLES = [:@_rodauths, :@_rodauth].freeze  
TINY = 0  

The patch version of Rodauth, updated only for bug fixes from the last feature release.

VERSION = "#{MAJOR}.#{MINOR}.#{TINY}".freeze  

The full version of Rodauth as a string

VERSION_NUMBER = MAJOR*10000 + MINOR*100 + TINY  

The full version of Rodauth as a number (1.17.0 => 11700)

Public Instance Aliases

account_session_value -> account_id
ignore_uniqueness_violation -> raises_uniqueness_violation?

If you just want to ignore uniqueness violations, this alias makes more sense.

logged_in? -> session_value
raised_uniqueness_violation -> raises_uniqueness_violation?

If you would like to operate/reraise the exception, this alias makes more sense.

webauthn_get_relying_party_opts -> webauthn_create_relying_party_opts

Public Class methods

configure(app, opts=OPTS, &block)
[show source]
   # File lib/rodauth.rb
53 def self.configure(app, opts=OPTS, &block)
54   json_opt = app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
55   csrf = app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_csrf])
56   app.opts[:rodauth_route_csrf] = case csrf
57   when false, :rack_csrf
58     false
59   else
60     json_opt != :only
61   end
62   auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= opts[:auth_class] || Class.new(Auth)
63   if !auth_class.roda_class
64     auth_class.roda_class = app
65   elsif auth_class.roda_class != app
66     auth_class = app.opts[:rodauths][opts[:name]] = Class.new(auth_class)
67     auth_class.roda_class = app
68   end
69   auth_class.class_eval{@configuration_name = opts[:name] unless defined?(@configuration_name)}
70   auth_class.configure(&block) if block
71   auth_class.send(:make_shape_friendly)
72   auth_class.allocate.post_configure if auth_class.method_defined?(:post_configure)
73 end
create_database_authentication_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
  4   def self.create_database_authentication_functions(db, opts={})
  5     table_name = opts[:table_name] || :account_password_hashes
  6     get_salt_name = opts[:get_salt_name] || :rodauth_get_salt
  7     valid_hash_name = opts[:valid_hash_name] || :rodauth_valid_password_hash
  8     argon2 = opts[:argon2]
  9 
 10     case db.database_type
 11     when :postgres
 12       search_path = opts[:search_path] || 'public, pg_temp'
 13       primary_key_type =
 14         case db.schema(table_name).find { |row| row.first == :id }[1][:db_type]
 15         when 'uuid' then :uuid
 16         else :int8
 17         end
 18       table_name = db.literal(table_name) unless table_name.is_a?(String)
 19 
 20       argon_sql = <<END
 21 CASE
 22     WHEN password_hash ~ '^\\$argon2id'
 23       THEN substring(password_hash from '\\$argon2id\\$v=\\d+\\$m=\\d+,t=\\d+,p=\\d+\\$.+\\$')
 24     ELSE substr(password_hash, 0, 30)
 25   END INTO salt
 26 END
 27       db.run <<END
 28 CREATE OR REPLACE FUNCTION #{get_salt_name}(acct_id #{primary_key_type}) RETURNS text AS $$
 29 DECLARE salt text;
 30 BEGIN
 31 SELECT
 32 #{argon2 ? argon_sql : "substr(password_hash, 0, 30) INTO salt"}
 33 FROM #{table_name}
 34 WHERE acct_id = id;
 35 RETURN salt;
 36 END;
 37 $$ LANGUAGE plpgsql
 38 SECURITY DEFINER
 39 SET search_path = #{search_path};
 40 END
 41 
 42       db.run <<END
 43 CREATE OR REPLACE FUNCTION #{valid_hash_name}(acct_id #{primary_key_type}, hash text) RETURNS boolean AS $$
 44 DECLARE valid boolean;
 45 BEGIN
 46 SELECT password_hash = hash INTO valid 
 47 FROM #{table_name}
 48 WHERE acct_id = id;
 49 RETURN valid;
 50 END;
 51 $$ LANGUAGE plpgsql
 52 SECURITY DEFINER
 53 SET search_path = #{search_path};
 54 END
 55     when :mysql
 56       argon_sql = <<END
 57 CASE
 58   WHEN password_hash REGEXP '^.argon2id'
 59     THEN left(password_hash, CHAR_LENGTH(password_hash) - INSTR(REVERSE(password_hash), '$'))
 60   ELSE substr(password_hash, 1, 30)
 61   END
 62 END
 63       db.run <<END
 64 CREATE FUNCTION #{get_salt_name}(acct_id int8) RETURNS varchar(255)
 65 SQL SECURITY DEFINER
 66 READS SQL DATA
 67 BEGIN
 68 RETURN (SELECT
 69 #{argon2 ? argon_sql : "substr(password_hash, 1, 30)"}
 70 FROM #{table_name}
 71 WHERE acct_id = id);
 72 END;
 73 END
 74 
 75       db.run <<END
 76 CREATE FUNCTION #{valid_hash_name}(acct_id int8, hash varchar(255)) RETURNS tinyint(1)
 77 SQL SECURITY DEFINER
 78 READS SQL DATA
 79 BEGIN
 80 DECLARE valid tinyint(1);
 81 DECLARE csr CURSOR FOR 
 82 SELECT password_hash = hash
 83 FROM #{table_name}
 84 WHERE acct_id = id;
 85 OPEN csr;
 86 FETCH csr INTO valid;
 87 CLOSE csr;
 88 RETURN valid;
 89 END;
 90 END
 91     when :mssql
 92       argon_sql = <<END
 93 CASE
 94   WHEN password_hash LIKE '[$]argon2id%'
 95     THEN left(password_hash, len(password_hash) - charindex('$', reverse(password_hash)))
 96   ELSE substring(password_hash, 0, 30)
 97   END
 98 END
 99       db.run <<END
100 CREATE FUNCTION #{get_salt_name}(@account_id bigint) RETURNS nvarchar(255)
101 WITH EXECUTE AS OWNER
102 AS
103 BEGIN
104 DECLARE @salt nvarchar(255);
105 SELECT @salt =
106 #{argon2 ? argon_sql : "substring(password_hash, 0, 30)"}
107 FROM #{table_name}
108 WHERE id = @account_id;
109 RETURN @salt;
110 END;
111 END
112 
113       db.run <<END
114 CREATE FUNCTION #{valid_hash_name}(@account_id bigint, @hash nvarchar(255)) RETURNS bit
115 WITH EXECUTE AS OWNER
116 AS
117 BEGIN
118 DECLARE @valid bit;
119 DECLARE @ph nvarchar(255);
120 SELECT @ph = password_hash
121 FROM #{table_name}
122 WHERE id = @account_id;
123 IF(@hash = @ph)
124   SET @valid = 1;
125 ELSE
126   SET @valid = 0
127 RETURN @valid;
128 END;
129 END
130     end
131   end
create_database_previous_password_check_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
153 def self.create_database_previous_password_check_functions(db, opts={})
154   create_database_authentication_functions(db, {:table_name=>:account_previous_password_hashes, :get_salt_name=>:rodauth_get_previous_salt, :valid_hash_name=>:rodauth_previous_password_hash_match}.merge(opts))
155 end
drop_database_authentication_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
133 def self.drop_database_authentication_functions(db, opts={})
134   table_name = opts[:table_name] || :account_password_hashes
135   get_salt_name = opts[:get_salt_name] || :rodauth_get_salt
136   valid_hash_name = opts[:valid_hash_name] || :rodauth_valid_password_hash
137 
138   case db.database_type
139   when :postgres
140     primary_key_type =
141       case db.schema(table_name).find { |row| row.first == :id }[1][:db_type]
142       when 'uuid' then :uuid
143       else :int8
144       end
145     db.run "DROP FUNCTION #{get_salt_name}(#{primary_key_type})"
146     db.run "DROP FUNCTION #{valid_hash_name}(#{primary_key_type}, text)"
147   when :mysql, :mssql
148     db.run "DROP FUNCTION #{get_salt_name}"
149     db.run "DROP FUNCTION #{valid_hash_name}"
150   end
151 end
drop_database_previous_password_check_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
157 def self.drop_database_previous_password_check_functions(db, opts={})
158   drop_database_authentication_functions(db, {:table_name=>:account_previous_password_hashes, :get_salt_name=>:rodauth_get_previous_salt, :valid_hash_name=>:rodauth_previous_password_hash_match}.merge(opts))
159 end
lib(opts=OPTS, &block)
[show source]
   # File lib/rodauth.rb
13 def self.lib(opts=OPTS, &block) 
14   require 'roda'
15   c = Class.new(Roda)
16   c.plugin(:rodauth, opts) do
17     enable :internal_request
18     instance_exec(&block)
19   end
20   c.freeze
21   c.rodauth
22 end
load_dependencies(app, opts=OPTS, &_)
[show source]
   # File lib/rodauth.rb
24 def self.load_dependencies(app, opts=OPTS, &_)
25   json_opt = opts.fetch(:json, app.opts[:rodauth_json])
26   if json_opt
27     app.plugin :json
28     app.plugin :json_parser
29   end
30 
31   unless json_opt == :only
32     unless opts[:render] == false
33       require 'tilt/string'
34       app.plugin :render
35     end
36 
37     case opts.fetch(:csrf, app.opts[:rodauth_csrf])
38     when false
39       # nothing
40     when :rack_csrf
41       # :nocov:
42       app.plugin :csrf
43       # :nocov:
44     else
45       app.plugin :route_csrf
46     end
47 
48     app.plugin :flash unless opts[:flash] == false
49     app.plugin :h
50   end
51 end
new(scope)
[show source]
    # File lib/rodauth/features/base.rb
180 def initialize(scope)
181   @scope = scope
182   _initialize_instance_variables
183 end
version()
[show source]
   # File lib/rodauth/version.rb
21 def self.version
22   VERSION
23 end

Public Instance methods

_account_from_email_auth_key(token)
[show source]
    # File lib/rodauth/features/email_auth.rb
247 def _account_from_email_auth_key(token)
248   account_from_key(token, account_open_status_value){|id| get_email_auth_key(id)}
249 end
_account_from_id(id, status_id=nil)
[show source]
    # File lib/rodauth/features/base.rb
890 def _account_from_id(id, status_id=nil)
891   ds = account_ds(id)
892   ds = ds.where(account_status_column=>status_id) if status_id && !skip_status_checks?
893   ds.first
894 end
_account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
877 def _account_from_login(login)
878   ds = account_table_ds.where(login_column=>login)
879   ds = ds.select(*account_select) if account_select
880   ds = ds.where(account_status_column=>[account_unverified_status_value, account_open_status_value]) unless skip_status_checks?
881   ds.first
882 end
_account_from_refresh_token(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
124 def _account_from_refresh_token(token)
125   id, token_id, key = _account_refresh_token_split(token)
126 
127   unless key &&
128          (id.to_s == session_value.to_s) &&
129          (actual = get_active_refresh_token(id, token_id)) &&
130          (timing_safe_eql?(key, convert_token_key(actual)) || (hmac_secret_rotation? && timing_safe_eql?(key, compute_old_hmac(actual)))) &&
131          jwt_refresh_token_match?(key)
132     return
133   end
134 
135   ds = account_ds(id)
136   ds = ds.where(account_session_status_filter) unless skip_status_checks?
137   ds.first
138 end
_account_from_reset_password_key(token)
[show source]
    # File lib/rodauth/features/reset_password.rb
260 def _account_from_reset_password_key(token)
261   account_from_key(token, reset_password_account_status_value){|id| get_password_reset_key(id)}
262 end
_account_from_session()
[show source]
    # File lib/rodauth/features/base.rb
884 def _account_from_session
885   ds = account_ds(session_value)
886   ds = ds.where(account_session_status_filter) unless skip_status_checks?
887   ds.first
888 end
_account_from_unlock_key(token)
[show source]
    # File lib/rodauth/features/lockout.rb
315 def _account_from_unlock_key(token)
316   account_from_key(token){|id| apply_key_for_update(account_lockouts_ds(id)).get(account_lockouts_key_column)}
317 end
_account_from_verify_account_key(token)
[show source]
    # File lib/rodauth/features/verify_account.rb
319 def _account_from_verify_account_key(token)
320   account_from_key(token, account_unverified_status_value){|id| get_verify_account_key(id)}
321 end
_account_from_verify_login_change_key(token)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
216 def _account_from_verify_login_change_key(token)
217   account_from_key(token, verify_login_change_account_status_value) do |id|
218     @verify_login_change_new_login, key = get_verify_login_change_login_and_key(id)
219     key
220   end
221 end
_account_refresh_token_split(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
140 def _account_refresh_token_split(token)
141   id, token = split_token(token)
142   return unless token && (id = convert_token_id(id))
143 
144   token_id, key = split_token(token)
145   return unless key && (token_id = convert_token_id(token_id))
146 
147   [id, token_id, key]
148 end
_around_rodauth()
[show source]
    # File lib/rodauth/features/base.rb
599 def _around_rodauth
600   yield
601 end
_email_auth_request()
[show source]
    # File lib/rodauth/features/email_auth.rb
194 def _email_auth_request
195   if email_auth_email_recently_sent?
196     set_redirect_error_flash email_auth_email_recently_sent_error_flash
197     redirect email_auth_email_recently_sent_redirect
198   end
199 
200   generate_email_auth_key_value
201   transaction do
202     before_email_auth_request
203     create_email_auth_key
204     send_email_auth_email
205     after_email_auth_request
206   end
207 
208   email_auth_email_sent_response
209 end
_field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
909 def _field_attributes(field)
910   nil
911 end
_field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
913 def _field_error_attributes(field)
914   " aria-invalid=\"true\" aria-describedby=\"#{field}_error_message\" "
915 end
_formatted_field_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
917 def _formatted_field_error(field, error)
918   "<span class=\"#{input_field_error_message_class}\" id=\"#{field}_error_message\">#{error}</span>"
919 end
_initialize_instance_variables()
[show source]
    # File lib/rodauth/features/base.rb
596 def _initialize_instance_variables
597 end
_json_response_body(hash)
[show source]
    # File lib/rodauth/features/json.rb
228 def _json_response_body(hash)
229   request.send(:convert_to_json, hash)
230 end
_jwt_decode_opts()
[show source]
    # File lib/rodauth/features/jwt.rb
106 def _jwt_decode_opts
107   jwt_decode_opts
108 end
_jwt_decode_secrets()
[show source]
    # File lib/rodauth/features/jwt.rb
111 def _jwt_decode_secrets
112   secrets = [jwt_secret, jwt_old_secret]
113   secrets.compact!
114   secrets
115 end
_login(auth_type)
[show source]
    # File lib/rodauth/features/login.rb
186 def _login(auth_type)
187   warn("Deprecated #_login method called, use #login instead.")
188   login(auth_type)
189 end
_login_response()
[show source]
    # File lib/rodauth/features/login.rb
166 def _login_response
167   set_notice_flash login_notice_flash
168   redirect(saved_login_redirect || login_redirect)
169 end
_merge_fixed_locals_opts(opts, fixed_locals)
[show source]
     # File lib/rodauth/features/base.rb
1075 def _merge_fixed_locals_opts(opts, fixed_locals)
1076   if use_template_fixed_locals? && !opts[:locals]
1077     fixed_locals_opts = {default_fixed_locals: fixed_locals}
1078     fixed_locals_opts.merge!(opts[:template_opts]) if opts[:template_opts]
1079     opts[:template_opts] = fixed_locals_opts
1080   end
1081 end
_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/email_auth.rb
188 def _multi_phase_login_forms
189   forms = super
190   forms << [30, email_auth_request_form, :_email_auth_request] if valid_login_entered? && allow_email_auth?
191   forms
192 end
_new_account(login)
[show source]
    # File lib/rodauth/features/create_account.rb
122 def _new_account(login)
123   acc = {login_column=>login}
124   unless skip_status_checks?
125     acc[account_status_column] = account_initial_status_value
126   end
127   acc
128 end
_otp()
[show source]
    # File lib/rodauth/features/otp.rb
457 def _otp
458   _otp_for_key(otp_user_key)
459 end
_otp_add_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
442 def _otp_add_key(secret)
443   # Uniqueness errors can't be handled here, as we can't be sure the secret provided
444   # is the same as the current secret.
445   otp_key_ds.insert(otp_keys_id_column=>session_value, otp_keys_column=>secret)
446 end
_otp_for_key(key)
[show source]
    # File lib/rodauth/features/otp.rb
453 def _otp_for_key(key)
454   otp_class.new(key, :issuer=>otp_issuer, :digits=>otp_digits, :interval=>otp_interval)
455 end
_otp_interval()
[show source]
    # File lib/rodauth/features/otp.rb
434 def _otp_interval
435   otp_interval || 30
436 end
_otp_key()
[show source]
    # File lib/rodauth/features/otp.rb
448 def _otp_key
449   @otp_user_key = nil
450   otp_key_ds.get(otp_keys_column) || false
451 end
_otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
428 def _otp_tmp_key(secret)
429   @otp_tmp_key = true
430   @otp_user_key = nil
431   @otp_key = secret
432 end
_otp_valid_code?(ot_pass, otp)
[show source]
    # File lib/rodauth/features/otp.rb
269 def _otp_valid_code?(ot_pass, otp)
270   return false unless otp_exists?
271   ot_pass = ot_pass.gsub(/\s+/, '')
272   if drift = otp_drift
273     # :nocov:
274     if otp.respond_to?(:verify_with_drift)
275       otp.verify_with_drift(ot_pass, drift)
276     # :nocov:
277     else
278       otp.verify(ot_pass, :drift_behind=>drift, :drift_ahead=>drift, :after=>otp_last_use)
279     end
280   # :nocov:
281   elsif otp.respond_to?(:verify_with_drift)
282     otp.verify(ot_pass)
283   # :nocov:
284   else
285     otp.verify(ot_pass, :after=>otp_last_use)
286   end
287 end
_otp_valid_code_for_old_secret()

Called for valid OTP codes for old secrets

[show source]
    # File lib/rodauth/features/otp.rb
439 def _otp_valid_code_for_old_secret
440 end
_override_webauthn_credential_response_verify(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
443 def _override_webauthn_credential_response_verify(webauthn_credential)
444   # no need to override
445 end
_process_raw_hmac(hmac)
[show source]
    # File lib/rodauth/features/base.rb
603 def _process_raw_hmac(hmac)
604   s = [hmac].pack('m')
605   s.chomp!("=\n")
606   s.tr!('+/', '-_')
607   s
608 end
_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
265 def _recovery_codes
266   recovery_codes_ds.select_map(recovery_codes_column)
267 end
_return_json_response()
[show source]
    # File lib/rodauth/features/json.rb
218 def _return_json_response
219   response.status ||= json_response_error_status if json_response_error?
220   response.headers[convert_response_header_key('content-type')] ||= json_response_content_type
221   return_response _json_response_body(json_response)
222 end
_set_otp_unlock_info()
[show source]
   # File lib/rodauth/features/json.rb
88 def _set_otp_unlock_info
89   if use_json?
90     json_response[:num_successes] = otp_unlock_num_successes
91     json_response[:required_successes] = otp_unlock_auths_required
92     json_response[:next_attempt_after] = otp_unlock_next_auth_attempt_after.to_i
93   end
94 end
_setup_account_lockouts_hash(account_id, key)
[show source]
    # File lib/rodauth/features/lockout.rb
175 def _setup_account_lockouts_hash(account_id, key)
176   hash = {account_lockouts_id_column=>account_id, account_lockouts_key_column=>key}
177   set_deadline_value(hash, account_lockouts_deadline_column, account_lockouts_deadline_interval)
178   hash
179 end
_sms_request_response()
[show source]
    # File lib/rodauth/features/sms_codes.rb
476 def _sms_request_response
477   set_notice_flash sms_request_notice_flash
478   redirect sms_auth_redirect
479 end
_template_opts(opts, page)

Set the template path only if there isn’t an overridden template in the application. Result should replace existing template opts.

[show source]
     # File lib/rodauth/features/base.rb
1085 def _template_opts(opts, page)
1086   opts = scope.send(:find_template, scope.send(:parse_template_opts, page, opts))
1087   unless File.file?(scope.send(:template_path, opts))
1088     opts[:path] = template_path(page)
1089   end
1090   opts
1091 end
_two_factor_auth_response()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
250 def _two_factor_auth_response
251   saved_two_factor_auth_redirect = remove_session_value(two_factor_auth_redirect_session_key)
252   set_notice_flash two_factor_auth_notice_flash
253   redirect(saved_two_factor_auth_redirect || two_factor_auth_redirect)
254 end
_two_factor_remove_all_from_session()
[show source]
    # File lib/rodauth/features/otp.rb
376 def _two_factor_remove_all_from_session
377   two_factor_remove_session('totp')
378   super
379 end
_update_login(login)
[show source]
   # File lib/rodauth/features/change_login.rb
83 def _update_login(login)
84   updated = nil
85   raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
86   if raised
87     set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
88   end
89   change_made = updated && !raised
90   clear_tokens(:change_login) if change_made
91   change_made
92 end
_view(meth, page)
[show source]
     # File lib/rodauth/features/base.rb
1093 def _view(meth, page)
1094   unless scope.respond_to?(meth)
1095     raise ConfigurationError, "attempted to render a built-in view/email template (#{page.inspect}), but rendering is disabled"
1096   end
1097 
1098   scope.send(meth, _view_opts(page))
1099 end
_view_opts(page)
[show source]
     # File lib/rodauth/features/base.rb
1065 def _view_opts(page)
1066   opts = template_opts.dup
1067   _merge_fixed_locals_opts(opts, '(rodauth: self.rodauth)')
1068   opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
1069   opts[:locals][:rodauth] = self
1070   opts[:cache] = cache_templates
1071   opts[:cache_key] = :"rodauth_#{page}"
1072   _template_opts(opts, page)
1073 end
account!()
[show source]
    # File lib/rodauth/features/base.rb
424 def account!
425   @account_retrieval_type ? @account : (session_value && account_from_session)
426 end
account_activity_ds(account_id)
[show source]
    # File lib/rodauth/features/account_expiration.rb
104 def account_activity_ds(account_id)
105   db[account_activity_table].
106     where(account_activity_id_column=>account_id)
107 end
account_ds(id=account_id)
[show source]
    # File lib/rodauth/features/base.rb
929 def account_ds(id=account_id)
930   raise ArgumentError, "invalid account id passed to account_ds" unless id
931   ds = account_table_ds.where(account_id_column=>id)
932   ds = ds.select(*account_select) if account_select
933   ds
934 end
account_expired?()
[show source]
   # File lib/rodauth/features/account_expiration.rb
54 def account_expired?
55   columns = [account_activity_last_activity_column, account_activity_last_login_column, account_activity_expired_column]
56   last_activity, last_login, expired = account_activity_ds(account_id).get(columns)
57   return true if expired
58   timestamp = convert_timestamp(expire_account_on_last_activity? ? last_activity : last_login)
59   return false unless timestamp
60   timestamp < Time.now - expire_account_after
61 end
account_expired_at()
[show source]
   # File lib/rodauth/features/account_expiration.rb
35 def account_expired_at
36   get_activity_timestamp(account_id, account_activity_expired_column)
37 end
account_from_email_auth_key(key)
[show source]
    # File lib/rodauth/features/email_auth.rb
142 def account_from_email_auth_key(key)
143   set_account(_account_from_email_auth_key(key), :email_auth)
144 end
account_from_id(id, status_id=nil)
[show source]
    # File lib/rodauth/features/base.rb
432 def account_from_id(id, status_id=nil)
433   set_account(_account_from_id(id, status_id), :id)
434 end
account_from_key(token, status_id=nil)
[show source]
    # File lib/rodauth/features/email_base.rb
100 def account_from_key(token, status_id=nil)
101   id, key = split_token(token)
102   return unless key && (id = convert_token_id(id))
103 
104   return unless actual = yield(id)
105 
106   unless (hmac_secret && timing_safe_eql?(key, convert_email_token_key(actual))) ||
107      (hmac_secret_rotation? && timing_safe_eql?(key, compute_old_hmac(actual))) ||
108      ((!hmac_secret || allow_raw_email_token?) && timing_safe_eql?(key, actual))
109     return
110   end
111   _account_from_id(id, status_id)
112 end
account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
317 def account_from_login(login)
318   set_account(_account_from_login(login), :login)
319 end
account_from_refresh_token(token)
[show source]
   # File lib/rodauth/features/jwt_refresh.rb
96 def account_from_refresh_token(token)
97   set_account(_account_from_refresh_token(token), :jwt_refresh)
98 end
account_from_reset_password_key(key)
[show source]
   # File lib/rodauth/features/password_expiration.rb
45 def account_from_reset_password_key(key)
46   if a = super
47     check_password_change_allowed
48   end
49   a
50 end
account_from_session()
[show source]
    # File lib/rodauth/features/base.rb
428 def account_from_session
429   set_account(_account_from_session, :session)
430 end
account_from_unlock_key(key)
[show source]
    # File lib/rodauth/features/lockout.rb
226 def account_from_unlock_key(key)
227   set_account(_account_from_unlock_key(key), :unlock)
228 end
account_from_verify_account_key(key)
[show source]
    # File lib/rodauth/features/verify_account.rb
199 def account_from_verify_account_key(key)
200   set_account(_account_from_verify_account_key(key), :verify_account)
201 end
account_from_verify_login_change_key(key)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
124 def account_from_verify_login_change_key(key)
125   set_account(_account_from_verify_login_change_key(key), :verify_login_change)
126 end
account_from_webauthn_login()
[show source]
   # File lib/rodauth/features/webauthn_autofill.rb
45 def account_from_webauthn_login
46   return super if param_or_nil(login_param)
47 
48   credential_id = webauthn_auth_data["id"]
49   account_id = db[webauthn_keys_table]
50     .where(webauthn_keys_webauthn_id_column => credential_id)
51     .get(webauthn_keys_account_id_column)
52 
53   unless account_id
54     throw_error_reason(:invalid_webauthn_id, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_webauthn_id_message)
55   end
56 
57   account_from_id(account_id)
58 end
account_id()
[show source]
    # File lib/rodauth/features/base.rb
307 def account_id
308   account[account_id_column]
309 end
account_id_or_session_value()
[show source]
    # File lib/rodauth/features/base.rb
610 def account_id_or_session_value
611   if @account
612     account_id
613   elsif !@account_retrieval_type
614     session_value
615   end
616 end
account_in_unverified_grace_period?()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
85 def account_in_unverified_grace_period?
86   return false unless account!
87   account[account_status_column] == account_unverified_status_value &&
88     verify_account_grace_period &&
89     !verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
90 end
account_initial_status_value()
[show source]
    # File lib/rodauth/features/base.rb
420 def account_initial_status_value
421   account_open_status_value
422 end
account_lockouts_ds(id=account_id)
[show source]
    # File lib/rodauth/features/lockout.rb
311 def account_lockouts_ds(id=account_id)
312   db[account_lockouts_table].where(account_lockouts_id_column=>id)
313 end
account_login_failures_ds()
[show source]
    # File lib/rodauth/features/lockout.rb
307 def account_login_failures_ds
308   db[account_login_failures_table].where(account_login_failures_id_column=>account_id)
309 end
account_password_hash_column()

If the account_password_hash_column is set, the password hash is verified in ruby, it will not use a database function to do so, it will check the password hash using bcrypt.

[show source]
    # File lib/rodauth/features/base.rb
341 def account_password_hash_column
342   nil
343 end
account_reload(current_retrieval_type, new_retrieval_type)
[show source]
    # File lib/rodauth/features/base.rb
674 def account_reload(current_retrieval_type, new_retrieval_type)
675   return unless @current_route
676 
677 
678   if current_retrieval_type == new_retrieval_type
679     warn "account retrieved multiple times during rodauth route with retrieval type #{current_retrieval_type}"
680   else
681     raise Error, "account retrieved multiple times during rodauth route, original retrieval type: #{current_retrieval_type}, new retrieval type: #{new_retrieval_type}"
682   end
683 end
account_session_status_filter()
[show source]
    # File lib/rodauth/features/base.rb
921 def account_session_status_filter
922   {account_status_column=>account_open_status_value}
923 end
account_table_ds()
[show source]
    # File lib/rodauth/features/base.rb
936 def account_table_ds
937   db[accounts_table]
938 end
account_webauthn_ids()
[show source]
    # File lib/rodauth/features/webauthn.rb
271 def account_webauthn_ids
272   webauthn_keys_ds.select_map(webauthn_keys_webauthn_id_column)
273 end
account_webauthn_usage()
[show source]
    # File lib/rodauth/features/webauthn.rb
275 def account_webauthn_usage
276   webauthn_keys_ds.select_hash(webauthn_keys_webauthn_id_column, webauthn_keys_last_use_column)
277 end
account_webauthn_user_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
279 def account_webauthn_user_id
280   unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
281     webauthn_id = WebAuthn.generate_user_id
282     if e = raised_uniqueness_violation do
283           webauthn_user_ids_ds.insert(
284             webauthn_user_ids_account_id_column => webauthn_account_id,
285             webauthn_user_ids_webauthn_id_column => webauthn_id
286           )
287         end
288       # If two requests to create a webauthn user id are sent at the same time and an insert
289       # is attempted for both, one will fail with a unique constraint violation.  In that case
290       # it is safe for the second one to use the webauthn user id inserted by the other request.
291       # If there is still no webauthn user id at this point, then we'll just reraise the
292       # exception.
293       # :nocov:
294       raise e unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
295       # :nocov:
296     end
297   end
298 
299   webauthn_id
300 end
active_remember_key_ds(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
269 def active_remember_key_ds(id=account_id)
270   remember_key_ds(id).where(Sequel.expr(remember_deadline_column) > Sequel::CURRENT_TIMESTAMP)
271 end
active_sessions_ds()
[show source]
    # File lib/rodauth/features/active_sessions.rb
236 def active_sessions_ds
237   db[active_sessions_table].
238     where(active_sessions_account_id_column=>account_id_or_session_value)
239 end
active_sessions_insert_hash()
[show source]
    # File lib/rodauth/features/active_sessions.rb
199 def active_sessions_insert_hash
200   {active_sessions_account_id_column => session_value, active_sessions_session_id_column => compute_hmac(active_sessions_key)}
201 end
active_sessions_update_hash()
[show source]
    # File lib/rodauth/features/active_sessions.rb
203 def active_sessions_update_hash
204   h = {active_sessions_last_use_column => Sequel::CURRENT_TIMESTAMP}
205 
206   if hmac_secret_rotation?
207     h[active_sessions_session_id_column] = compute_hmac(session[session_id_session_key])
208   end
209 
210   h
211 end
add_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
70 def add_active_session
71   key = generate_active_sessions_key
72   set_session_value(session_id_session_key, key)
73   if e = raises_uniqueness_violation?{active_sessions_ds.insert(active_sessions_insert_hash)}
74     handle_duplicate_active_session_id(e)
75   end
76   nil
77 end
add_audit_log(account_id, action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
40 def add_audit_log(account_id, action)
41   if hash = audit_log_insert_hash(account_id, action)
42     audit_log_ds.insert(hash)
43   end
44 end
add_field_error_class(field)
[show source]
    # File lib/rodauth/features/base.rb
222 def add_field_error_class(field)
223   if field_error(field)
224     " #{input_field_error_class}"
225   end
226 end
add_previous_password_hash(hash)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
27 def add_previous_password_hash(hash) 
28   ds = previous_password_ds
29 
30   unless @dont_check_previous_password
31     keep_before = ds.reverse(previous_password_id_column).
32       limit(nil, previous_passwords_to_check).
33       get(previous_password_id_column)
34 
35     if keep_before
36       ds.where(Sequel.expr(previous_password_id_column) <= keep_before).
37         delete
38     end
39   end
40 
41   # This should never raise uniqueness violations, as it uses a serial primary key
42   ds.insert(previous_password_account_id_column=>account_id, previous_password_hash_column=>hash)
43 end
add_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
192 def add_recovery_code
193   # This should never raise uniqueness violations unless the recovery code is the same, and the odds of that
194   # are 1/256**32 assuming a good random number generator.  Still, attempt to handle that case by retrying
195   # on such a uniqueness violation.
196   retry_on_uniqueness_violation do
197     recovery_codes_ds.insert(recovery_codes_id_column=>session_value, recovery_codes_column=>new_recovery_code)
198   end
199 end
add_recovery_codes(number)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
182 def add_recovery_codes(number)
183   return if number <= 0
184   transaction do
185     number.times do
186       add_recovery_code
187     end
188   end
189   @recovery_codes = nil
190 end
add_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
163 def add_remember_key
164   hash = {remember_id_column=>account_id, remember_key_column=>remember_key_value}
165   set_deadline_value(hash, remember_deadline_column, remember_deadline_interval)
166 
167   if e = raised_uniqueness_violation{remember_key_ds.insert(hash)}
168     # If inserting into the remember key table causes a violation, we can pull the
169     # existing row from the table.  If there is no invalid row, we can then reraise.
170     raise e unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
171   end
172 end
add_webauthn_credential(_)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
153 def add_webauthn_credential(_)
154   super if defined?(super)
155   auto_add_missing_recovery_codes
156 end
after_change_password()
[show source]
   # File lib/rodauth/features/change_password_notify.rb
11 def after_change_password
12   super
13   send_password_changed_email
14 end
after_close_account()
[show source]
    # File lib/rodauth/features/account_expiration.rb
 99 def after_close_account
100   super if defined?(super)
101   account_activity_ds(account_id).delete
102 end
after_create_account()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
89 def after_create_account
90   if account_password_hash_column && !(respond_to?(:verify_account_set_password?) && verify_account_set_password?)
91     add_previous_password_hash(password_hash(param(password_param)))
92   end
93   super if defined?(super)
94 end
after_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
217 def after_login
218   # Remove the email auth key after any login, even if
219   # it is a password login.  This is done to invalidate
220   # the email login when a user has a password and requests
221   # email authentication, but then remembers their password
222   # and doesn't need the link.  At that point, the link
223   # that allows login access to the account becomes a
224   # security liability, and it is best to remove it.
225   remove_email_auth_key
226   super
227 end
after_login_entered_during_multi_phase_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
160 def after_login_entered_during_multi_phase_login
161   # If forcing email auth, just send the email link.
162   _email_auth_request if force_email_auth?
163 
164   super
165 end
after_login_failure()
[show source]
    # File lib/rodauth/features/lockout.rb
278 def after_login_failure
279   invalid_login_attempted
280   super
281 end
after_logout()
[show source]
    # File lib/rodauth/features/remember.rb
245 def after_logout
246   forget_login
247   super if defined?(super)
248 end
after_otp_authentication_failure()
[show source]
   # File lib/rodauth/features/otp_lockout_email.rb
18 def after_otp_authentication_failure
19   super
20 
21   if otp_locked_out? && send_otp_locked_out_email?
22     send_otp_locked_out_email
23   end
24 end
after_otp_disable()
[show source]
   # File lib/rodauth/features/otp_modify_email.rb
18 def after_otp_disable
19   super
20   send_otp_disabled_email
21 end
after_otp_setup()
[show source]
    # File lib/rodauth/features/active_sessions.rb
153 def after_otp_setup
154   super if defined?(super)
155   remove_all_active_sessions_except_current if @clear_active_sessions_after_two_factor_setup
156 end
after_otp_unlock_auth_failure()
[show source]
    # File lib/rodauth/features/json.rb
104 def after_otp_unlock_auth_failure
105   super if defined?(super)
106   _set_otp_unlock_info
107 end
after_otp_unlock_auth_success()
[show source]
    # File lib/rodauth/features/json.rb
 96 def after_otp_unlock_auth_success
 97   super if defined?(super)
 98   if otp_locked_out?
 99     _set_otp_unlock_info
100     json_response[:deadline] = otp_unlock_deadline.to_i
101   end
102 end
after_otp_unlock_not_yet_available()
[show source]
    # File lib/rodauth/features/json.rb
109 def after_otp_unlock_not_yet_available
110   super if defined?(super)
111   _set_otp_unlock_info
112 end
after_refresh_token()
[show source]
    # File lib/rodauth/features/active_sessions.rb
137 def after_refresh_token
138   super if defined?(super)
139   if prev_key = session[session_id_session_key]
140     key = generate_active_sessions_key
141     set_session_value(session_id_session_key, key)
142     active_sessions_ds.
143       where(active_sessions_session_id_column => compute_hmacs(prev_key)).
144       update(active_sessions_session_id_column => compute_hmac(key))
145   end
146 end
after_reset_password()
[show source]
   # File lib/rodauth/features/password_grace_period.rb
48 def after_reset_password
49   super if defined?(super)
50   @last_password_entry = Time.now.to_i
51 end
after_sms_confirm()
[show source]
    # File lib/rodauth/features/active_sessions.rb
158 def after_sms_confirm
159   super if defined?(super)
160   remove_all_active_sessions_except_current if @clear_active_sessions_after_two_factor_setup
161 end
after_sms_disable()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
235 def after_sms_disable
236   super if defined?(super)
237   auto_remove_recovery_codes
238 end
after_webauthn_remove()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
240 def after_webauthn_remove
241   super if defined?(super)
242   auto_remove_recovery_codes
243 end
after_webauthn_setup()
[show source]
    # File lib/rodauth/features/active_sessions.rb
163 def after_webauthn_setup
164   super if defined?(super)
165   remove_all_active_sessions_except_current if @clear_active_sessions_after_two_factor_setup
166 end
allow_email_auth?()
[show source]
    # File lib/rodauth/features/email_auth.rb
213 def allow_email_auth?
214   defined?(super) ? super : true
215 end
allow_param_fallback_for_session_param?()
[show source]
   # File lib/rodauth/features/email_base.rb
78 def allow_param_fallback_for_session_param?
79   return super if defined?(super)
80   false
81 end
allow_resending_verify_account_email?()
[show source]
    # File lib/rodauth/features/verify_account.rb
165 def allow_resending_verify_account_email?
166   account[account_status_column] == account_unverified_status_value
167 end
already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
350 def already_logged_in
351   # RODAUTH3: Move to login feature, halt or redirect by default
352   nil
353 end
apply_key_for_update(ds)
[show source]
   # File lib/rodauth/features/email_base.rb
91 def apply_key_for_update(ds)
92   if @key_for_update
93     @key_for_update = nil
94     ds.for_update
95   else
96     ds
97   end
98 end
argon2_hash_algorithm?(hash)

:nocov:

[show source]
    # File lib/rodauth/features/argon2.rb
107 def argon2_hash_algorithm?(hash)
108   hash.start_with?('$argon2id$')
109 end
argon2_hash_cost()
[show source]
   # File lib/rodauth/features/argon2.rb
78 def argon2_hash_cost
79   { t_cost: 1, m_cost: 5, p_cost: 1 }
80 end
argon2_password_hash_match?(hash, password)
[show source]
    # File lib/rodauth/features/argon2.rb
111 def argon2_password_hash_match?(hash, password)
112   ret = ::Argon2::Password.verify_password(password, hash, argon2_secret)
113 
114   if ret == false && argon2_old_secret != argon2_secret && (ret = ::Argon2::Password.verify_password(password, hash, argon2_old_secret))
115     @update_password_hash = true
116   end
117 
118   ret
119 end
argon2_password_hash_using_salt_and_secret(password, salt, secret)
[show source]
   # File lib/rodauth/features/argon2.rb
62 def argon2_password_hash_using_salt_and_secret(password, salt, secret)
63   argon2_params = Hash[extract_password_hash_cost(salt)]
64   argon2_params[argon2_salt_option] = salt.split('$').last.unpack("m")[0]
65   argon2_params[:secret] = secret
66   ::Argon2::Password.new(argon2_params).create(password)
67 end
argon2_salt_option()
[show source]
   # File lib/rodauth/features/argon2.rb
36 def argon2_salt_option
37   :salt_do_not_supply
38 end
audit_log_ds()
[show source]
   # File lib/rodauth/features/audit_logging.rb
84 def audit_log_ds
85   ds = db[audit_logging_table]
86   # :nocov:
87   if db.database_type == :postgres
88   # :nocov:
89     # For PostgreSQL, use RETURNING NULL. This allows the feature
90     # to be used with INSERT but not SELECT permissions on the
91     # table, useful for audit logging where the database user
92     # the application is running as should not need to read the
93     # logs.
94     ds = ds.returning(nil)
95   end
96   ds
97 end
audit_log_insert_hash(account_id, action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
46 def audit_log_insert_hash(account_id, action)
47   if message = audit_log_message(action)
48     {
49       audit_logging_account_id_column => account_id,
50       audit_logging_message_column => message,
51       audit_logging_metadata_column => serialize_audit_log_metadata(audit_log_metadata(action))
52     }
53   end
54 end
audit_log_message(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
64 def audit_log_message(action)
65   meth = :"audit_log_message_for_#{action}"
66   if respond_to?(meth, true)
67     send(meth)
68   else
69     audit_log_message_default(action)
70   end
71 end
audit_log_message_default(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
60 def audit_log_message_default(action)
61   action.to_s
62 end
audit_log_metadata(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
73 def audit_log_metadata(action)
74   meth = :"audit_log_metadata_for_#{action}"
75   if respond_to?(meth, true)
76     send(meth)
77   else
78     audit_log_metadata_default
79   end
80 end
auth_class_eval(&block)
[show source]
    # File lib/rodauth/features/base.rb
155 def auth_class_eval(&block)
156   auth.class_eval(&block)
157 end
authenticated?()
[show source]
    # File lib/rodauth/features/base.rb
407 def authenticated?
408   logged_in?
409 end
authenticated_by()
[show source]
    # File lib/rodauth/features/base.rb
511 def authenticated_by
512   session[authenticated_by_session_key]
513 end
authenticated_webauthn_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
251 def authenticated_webauthn_id
252   session[authenticated_webauthn_id_session_key]
253 end
auto_add_missing_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
253 def auto_add_missing_recovery_codes
254   if auto_add_recovery_codes?
255     add_recovery_codes(recovery_codes_limit - recovery_codes.length)
256   end
257 end
auto_remove_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
259 def auto_remove_recovery_codes
260   if auto_remove_recovery_codes? && (%w'totp webauthn sms_code' & possible_authentication_methods).empty?
261     recovery_codes_remove
262   end
263 end
autocomplete_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
252 def autocomplete_for_field?(_param)
253   mark_input_fields_with_autocomplete?
254 end
autologin_session(autologin_type)
[show source]
    # File lib/rodauth/features/base.rb
524 def autologin_session(autologin_type)
525   login_session('autologin')
526   set_session_value(autologin_type_session_key, autologin_type)
527 end
autologin_type()
[show source]
    # File lib/rodauth/features/base.rb
520 def autologin_type
521   session[autologin_type_session_key]
522 end
base32_encode(data, length)
[show source]
    # File lib/rodauth/features/otp.rb
423 def base32_encode(data, length)
424   chars = 'abcdefghijklmnopqrstuvwxyz234567'
425   length.times.map{|i|chars[data[i].ord % 32]}.join
426 end
base_url()
[show source]
    # File lib/rodauth/features/base.rb
570 def base_url
571   url = String.new("#{request.scheme}://#{domain}")
572   url << ":#{request.port}" if request.port != Rack::Request::DEFAULT_PORTS[request.scheme]
573   url
574 end
before_change_login_route()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
58 def before_change_login_route
59   unless verified_account?
60     set_redirect_error_flash unverified_change_login_error_flash
61     redirect unverified_change_login_redirect
62   end
63   super if defined?(super)
64 end
before_change_password_route()
[show source]
   # File lib/rodauth/features/password_expiration.rb
89 def before_change_password_route
90   check_password_change_allowed
91   super
92 end
before_create_account_route()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
79 def before_create_account_route
80   super if defined?(super)
81   @dont_check_previous_password = true
82 end
before_login_attempt()
[show source]
    # File lib/rodauth/features/lockout.rb
266 def before_login_attempt
267   if locked_out?
268     show_lockout_page
269   end
270   super
271 end
before_logout()
[show source]
    # File lib/rodauth/features/active_sessions.rb
168 def before_logout
169   if param_or_nil(global_logout_param)
170     remove_remember_key(session_value) if respond_to?(:remove_remember_key)
171     remove_all_active_sessions
172   else
173     remove_current_session
174   end
175   super
176 end
before_otp_setup()
[show source]
    # File lib/rodauth/features/active_sessions.rb
178 def before_otp_setup
179   @clear_active_sessions_after_two_factor_setup = !two_factor_authentication_setup?
180   super if defined?(super)
181 end
before_otp_setup_route()
[show source]
    # File lib/rodauth/features/json.rb
178 def before_otp_setup_route
179   super if defined?(super)
180   if use_json? && otp_keys_use_hmac? && !param_or_nil(otp_setup_raw_param)
181     _otp_tmp_key(otp_new_secret)
182     json_response[otp_setup_param] = otp_user_key
183     json_response[otp_setup_raw_param] = otp_key
184   end
185 end
before_reset_password()
[show source]
   # File lib/rodauth/features/account_expiration.rb
79 def before_reset_password
80   check_account_expiration
81   super if defined?(super)
82 end
before_reset_password_request()
[show source]
   # File lib/rodauth/features/account_expiration.rb
84 def before_reset_password_request
85   check_account_expiration
86   super if defined?(super)
87 end
before_rodauth()
[show source]
    # File lib/rodauth/features/json.rb
187 def before_rodauth
188   if json_request?
189     if json_check_accept? && (accept = request.env['HTTP_ACCEPT']) && accept !~ json_accept_regexp
190       response.status = 406
191       json_response[json_response_error_key] = json_not_accepted_error_message
192       _return_json_response
193     end
194 
195     unless request.post?
196       response.status = 405
197       set_response_header('allow', 'POST')
198       json_response[json_response_error_key] = json_non_post_error_message
199       return_json_response
200     end
201   elsif only_json?
202     response.status = json_response_error_status
203     return_response non_json_request_error_message
204   end
205 
206   super
207 end
before_sms_confirm()
[show source]
    # File lib/rodauth/features/active_sessions.rb
183 def before_sms_confirm
184   @clear_active_sessions_after_two_factor_setup = !two_factor_authentication_setup?
185   super if defined?(super)
186 end
before_two_factor_auth_route()
[show source]
    # File lib/rodauth/features/json.rb
124 def before_two_factor_auth_route
125   super if defined?(super)
126   if use_json?
127     json_response[:auth_links] = two_factor_auth_links.sort.map{|_,link| link}
128     json_response[json_response_success_key] ||= "" if include_success_messages?
129     return_json_response
130   end
131 end
before_two_factor_manage_route()
[show source]
    # File lib/rodauth/features/json.rb
114 def before_two_factor_manage_route
115   super if defined?(super)
116   if use_json?
117     json_response[:setup_links] = two_factor_setup_links.sort.map{|_,link| link}
118     json_response[:remove_links] = two_factor_remove_links.sort.map{|_,link| link}
119     json_response[json_response_success_key] ||= "" if include_success_messages?
120     return_json_response
121   end
122 end
before_unlock_account()
[show source]
   # File lib/rodauth/features/account_expiration.rb
89 def before_unlock_account
90   check_account_expiration
91   super if defined?(super)
92 end
before_unlock_account_request()
[show source]
   # File lib/rodauth/features/account_expiration.rb
94 def before_unlock_account_request
95   check_account_expiration
96   super if defined?(super)
97 end
before_verify_account()
[show source]
   # File lib/rodauth/features/webauthn_verify_account.rb
32 def before_verify_account
33   super
34   if features.include?(:json) && use_json? && !param_or_nil(webauthn_setup_param)
35     cred = new_webauthn_credential
36     json_response[webauthn_setup_param] = cred.as_json
37     json_response[webauthn_setup_challenge_param] = cred.challenge
38     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
39   end
40   @webauthn_credential = webauthn_setup_credential_from_form_submission
41   add_webauthn_credential(@webauthn_credential)
42 end
before_verify_account_route()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
84 def before_verify_account_route
85   super if defined?(super)
86   @dont_check_previous_password = true
87 end
before_view_recovery_codes()
[show source]
    # File lib/rodauth/features/json.rb
133 def before_view_recovery_codes
134   super if defined?(super)
135   if use_json?
136     json_response[:codes] = recovery_codes
137     json_response[json_response_success_key] ||= "" if include_success_messages?
138   end
139 end
before_webauthn_auth_route()
[show source]
    # File lib/rodauth/features/json.rb
151 def before_webauthn_auth_route
152   super if defined?(super)
153   if use_json? && !param_or_nil(webauthn_auth_param)
154     cred = webauthn_credential_options_for_get
155     json_response[webauthn_auth_param] = cred.as_json
156     json_response[webauthn_auth_challenge_param] = cred.challenge
157     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
158   end
159 end
before_webauthn_login_route()
[show source]
    # File lib/rodauth/features/json.rb
161 def before_webauthn_login_route
162   super if defined?(super)
163   if use_json? && !param_or_nil(webauthn_auth_param) && webauthn_login_options?
164     cred = webauthn_credential_options_for_get
165     json_response[webauthn_auth_param] = cred.as_json
166     json_response[webauthn_auth_challenge_param] = cred.challenge
167     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
168   end
169 end
before_webauthn_remove_route()
[show source]
    # File lib/rodauth/features/json.rb
171 def before_webauthn_remove_route
172   super if defined?(super)
173   if use_json? && !param_or_nil(webauthn_remove_param)
174     json_response[webauthn_remove_param] = account_webauthn_usage
175   end
176 end
before_webauthn_setup()
[show source]
    # File lib/rodauth/features/active_sessions.rb
188 def before_webauthn_setup
189   @clear_active_sessions_after_two_factor_setup = !two_factor_authentication_setup?
190   super if defined?(super)
191 end
before_webauthn_setup_route()
[show source]
    # File lib/rodauth/features/json.rb
141 def before_webauthn_setup_route
142   super if defined?(super)
143   if use_json? && !param_or_nil(webauthn_setup_param)
144     cred = new_webauthn_credential
145     json_response[webauthn_setup_param] = cred.as_json
146     json_response[webauthn_setup_challenge_param] = cred.challenge
147     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
148   end
149 end
button(value, opts=OPTS)
[show source]
    # File lib/rodauth/features/base.rb
461 def button(value, opts=OPTS)
462   scope.render(button_opts(value, opts))
463 end
button_fixed_locals()
[show source]
    # File lib/rodauth/features/base.rb
656 def button_fixed_locals
657   '(value:, opts:)'
658 end
button_opts(value, opts)
[show source]
    # File lib/rodauth/features/base.rb
452 def button_opts(value, opts)
453   opts = Hash[template_opts].merge!(opts)
454   _merge_fixed_locals_opts(opts, button_fixed_locals)
455   opts[:locals] = {:value=>value, :opts=>opts}
456   opts[:cache] = cache_templates
457   opts[:cache_key] = :rodauth_button
458   _template_opts(opts, 'button')
459 end
can_add_recovery_codes?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
178 def can_add_recovery_codes?
179   recovery_codes.length < recovery_codes_limit
180 end
catch_error(&block)
[show source]
    # File lib/rodauth/features/base.rb
779 def catch_error(&block)
780   catch(:rodauth_error, &block)
781 end
change_login(login)
[show source]
   # File lib/rodauth/features/change_login.rb
68 def change_login(login)
69   if account_ds.get(login_column).downcase == login.downcase
70     set_login_requirement_error_message(:same_as_current_login, same_as_current_login_message)
71     return false
72   end
73 
74   update_login(login)
75 end
change_login_notice_flash()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
142 def change_login_notice_flash
143   change_login_needs_verification_notice_flash
144 end
change_login_requires_password?()
[show source]
   # File lib/rodauth/features/change_login.rb
64 def change_login_requires_password?
65   modifications_require_password?
66 end
change_password_requires_password?()
[show source]
   # File lib/rodauth/features/change_password.rb
78 def change_password_requires_password?
79   modifications_require_password?
80 end
check_account_expiration()
[show source]
   # File lib/rodauth/features/account_expiration.rb
63 def check_account_expiration
64   if account_expired?
65     set_expired unless account_expired_at
66     set_redirect_error_flash account_expiration_error_flash
67     redirect account_expiration_redirect
68   end
69   update_last_login
70 end
check_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
56 def check_active_session
57   if logged_in? && !currently_active_session?
58     no_longer_active_session
59   end
60 end
check_already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
345 def check_already_logged_in
346   # RODAUTH3: Move to login feature
347   already_logged_in if logged_in?
348 end
check_csrf()
[show source]
    # File lib/rodauth/features/base.rb
436 def check_csrf
437   scope.check_csrf!(check_csrf_opts, &check_csrf_block)
438 end
check_csrf?()
[show source]
    # File lib/rodauth/features/base.rb
841 def check_csrf?
842   scope.opts[:rodauth_route_csrf]
843 end
check_password_change_allowed()
[show source]
   # File lib/rodauth/features/password_expiration.rb
30 def check_password_change_allowed
31   if password_changed_at = get_password_changed_at
32     if password_changed_at > Time.now - allow_password_change_after
33       set_redirect_error_flash password_not_changeable_yet_error_flash
34       redirect password_not_changeable_yet_redirect
35     end
36   end
37 end
check_session_expiration()
[show source]
   # File lib/rodauth/features/session_expiration.rb
15 def check_session_expiration
16   return unless logged_in?
17 
18   unless session.has_key?(session_last_activity_session_key) && session.has_key?(session_created_session_key)
19     if session_expiration_default
20       expire_session
21     end
22 
23     return
24   end
25 
26   time = Time.now.to_i
27 
28   if session[session_last_activity_session_key] + session_inactivity_timeout < time
29     expire_session
30   end
31   set_session_value(session_last_activity_session_key, time)
32 
33   if session[session_created_session_key] + max_session_lifetime < time
34     expire_session
35   end
36 end
check_single_session()
[show source]
   # File lib/rodauth/features/single_session.rb
56 def check_single_session
57   if logged_in? && !currently_active_session?
58     no_longer_active_session
59   end
60 end
clear_cached_otp()
[show source]
    # File lib/rodauth/features/otp.rb
381 def clear_cached_otp
382   @otp = nil
383 end
clear_invalid_login_attempts()
[show source]
    # File lib/rodauth/features/lockout.rb
171 def clear_invalid_login_attempts
172   unlock_account
173 end
clear_session()
[show source]
    # File lib/rodauth/features/base.rb
363 def clear_session
364   if use_scope_clear_session?
365     scope.clear_session
366   else
367     session.clear
368   end
369 end
clear_tokens(reason)
[show source]
    # File lib/rodauth/features/active_sessions.rb
130 def clear_tokens(reason)
131   super
132   remove_all_active_sessions_except_current
133 end
close_account()
[show source]
   # File lib/rodauth/features/close_account.rb
67 def close_account
68   unless skip_status_checks?
69     update_account(account_status_column=>account_closed_status_value)
70   end
71 
72   unless account_password_hash_column
73     password_hash_ds.delete
74   end
75 end
close_account_requires_password?()
[show source]
   # File lib/rodauth/features/close_account.rb
63 def close_account_requires_password?
64   modifications_require_password?
65 end
compute_hmac(data)

Return urlsafe base64 HMAC for data, assumes hmac_secret is set.

[show source]
    # File lib/rodauth/features/base.rb
286 def compute_hmac(data)
287   _process_raw_hmac(compute_raw_hmac(data))
288 end
compute_hmacs(data)

Return array of hmacs. Array has two strings if hmac_old_secret is set, or one string otherwise.

[show source]
    # File lib/rodauth/features/base.rb
297 def compute_hmacs(data)
298   hmacs = [compute_hmac(data)]
299 
300   if hmac_old_secret
301     hmacs << compute_old_hmac(data)
302   end
303 
304   hmacs
305 end
compute_old_hmac(data)

Return urlsafe base64 HMAC for data using hmac_old_secret, assumes hmac_old_secret is set.

[show source]
    # File lib/rodauth/features/base.rb
291 def compute_old_hmac(data)
292   _process_raw_hmac(compute_raw_hmac_with_secret(data, hmac_old_secret))
293 end
compute_raw_hmac(data)
[show source]
    # File lib/rodauth/features/base.rb
900 def compute_raw_hmac(data)
901   raise ConfigurationError, "hmac_secret not set" unless hmac_secret
902   compute_raw_hmac_with_secret(data, hmac_secret)
903 end
compute_raw_hmac_with_secret(data, secret)
[show source]
    # File lib/rodauth/features/base.rb
905 def compute_raw_hmac_with_secret(data, secret)
906   OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, secret, data)
907 end
confirm_password()
[show source]
   # File lib/rodauth/features/confirm_password.rb
63 def confirm_password
64   authenticated_by.delete('autologin')
65   authenticated_by.delete('remember')
66   authenticated_by.delete('email_auth')
67   authenticated_by.delete('password')
68   authenticated_by.unshift("password")
69   remove_session_value(autologin_type_session_key)
70   nil
71 end
confirm_password_redirect()
[show source]
   # File lib/rodauth/features/confirm_password.rb
73 def confirm_password_redirect
74   remove_session_value(confirm_password_redirect_session_key) || default_redirect
75 end
convert_email_token_key(key)
[show source]
   # File lib/rodauth/features/email_base.rb
83 def convert_email_token_key(key)
84   convert_token_key(key)
85 end
convert_response_header_key(key)
[show source]
    # File lib/rodauth/features/base.rb
623 def convert_response_header_key(key)
624   key
625 end
convert_session_key(key)
[show source]
    # File lib/rodauth/features/base.rb
758 def convert_session_key(key)
759   key = :"#{session_key_prefix}#{key}" if session_key_prefix
760   normalize_session_or_flash_key(key)
761 end
convert_timestamp(timestamp)

This is needed for jdbc/sqlite, which returns timestamp columns as strings

[show source]
    # File lib/rodauth/features/base.rb
945 def convert_timestamp(timestamp)
946   timestamp = db.to_application_timestamp(timestamp) if timestamp.is_a?(String)
947   timestamp
948 end
convert_token_id(id)
[show source]
    # File lib/rodauth/features/base.rb
711 def convert_token_id(id)
712   if convert_token_id_to_integer?
713     convert_token_id_to_integer(id)
714   else
715     id
716   end
717 end
convert_token_id_to_integer(id)
[show source]
    # File lib/rodauth/features/base.rb
719 def convert_token_id_to_integer(id)
720   if id = (Integer(id, 10) rescue nil)
721     if id > 9223372036854775807 || id < -9223372036854775808
722       # Only allow 64-bit signed integer range to avoid problems on PostgreSQL
723       id = nil
724     end
725   end
726 
727   id
728 end
convert_token_key(key)
[show source]
    # File lib/rodauth/features/base.rb
699 def convert_token_key(key)
700   if key && hmac_secret
701     compute_hmac(key)
702   else
703     key
704   end
705 end
create_account_autologin?()
[show source]
    # File lib/rodauth/features/verify_account.rb
219 def create_account_autologin?
220   false
221 end
create_account_notice_flash()
[show source]
    # File lib/rodauth/features/verify_account.rb
186 def create_account_notice_flash
187   verify_account_email_sent_notice_flash
188 end
create_account_set_password?()
[show source]
    # File lib/rodauth/features/verify_account.rb
223 def create_account_set_password?
224   return false if verify_account_set_password?
225   super
226 end
create_email(subject, body)
[show source]
   # File lib/rodauth/features/email_base.rb
47 def create_email(subject, body)
48   create_email_to(email_to, subject, body)
49 end
create_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
113 def create_email_auth_key
114   transaction do
115     if email_auth_key_value = get_email_auth_key(account_id)
116       set_email_auth_email_last_sent
117       @email_auth_key_value = email_auth_key_value
118     elsif e = raised_uniqueness_violation{email_auth_ds.insert(email_auth_key_insert_hash)}
119       # If inserting into the email auth table causes a violation, we can pull the
120       # existing email auth key from the table, or reraise.
121       raise e unless @email_auth_key_value = get_email_auth_key(account_id)
122     end
123   end
124 end
create_email_to(to, subject, body)
[show source]
   # File lib/rodauth/features/email_base.rb
51 def create_email_to(to, subject, body)
52   m = Mail.new
53   m.from = email_from
54   m.to = to
55   m.subject = "#{email_subject_prefix}#{subject}"
56   m.body = body
57   m
58 end
create_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
162 def create_reset_password_key
163   transaction do
164     if reset_password_key_value = get_password_reset_key(account_id)
165       set_reset_password_email_last_sent
166       @reset_password_key_value = reset_password_key_value
167     elsif e = raised_uniqueness_violation{password_reset_ds.insert(reset_password_key_insert_hash)}
168       # If inserting into the reset password table causes a violation, we can pull the
169       # existing reset password key from the table, or reraise.
170       raise e unless @reset_password_key_value = get_password_reset_key(account_id)
171     end
172   end
173 end
create_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
298 def create_verify_account_key
299   ds = verify_account_ds
300   transaction do
301     if ds.empty?
302       if e = raised_uniqueness_violation{ds.insert(verify_account_key_insert_hash)}
303         # If inserting into the verify account table causes a violation, we can pull the
304         # key from the verify account table, or reraise.
305         raise e unless @verify_account_key_value = get_verify_account_key(account_id)
306       end
307     end
308   end
309 end
create_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
204 def create_verify_login_change_email(login)
205   create_email_to(login, verify_login_change_email_subject, verify_login_change_email_body)
206 end
create_verify_login_change_key(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
182 def create_verify_login_change_key(login)
183   ds = verify_login_change_ds
184   transaction do
185     ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
186     if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
187       old_login, key = get_verify_login_change_login_and_key(account_id)
188       # If inserting into the verify login change table causes a violation, we can pull the
189       # key from the verify login change table if the logins match, or reraise.
190       @verify_login_change_key_value = if old_login.downcase == login.downcase
191         key
192       end
193       raise e unless @verify_login_change_key_value
194     end
195   end
196 end
csrf_tag(path=request.path)
[show source]
    # File lib/rodauth/features/base.rb
440 def csrf_tag(path=request.path)
441   return unless scope.respond_to?(:csrf_tag)
442 
443   if use_request_specific_csrf_tokens?
444     scope.csrf_tag(path)
445   else
446     # :nocov:
447     scope.csrf_tag
448     # :nocov:
449   end
450 end
currently_active_session?()
[show source]
   # File lib/rodauth/features/active_sessions.rb
42 def currently_active_session?
43   return false unless session_id = session[session_id_session_key]
44 
45   remove_inactive_sessions
46   ds = active_sessions_ds.
47     where(active_sessions_session_id_column => compute_hmacs(session_id))
48 
49   if update_current_session?
50     ds.update(active_sessions_update_hash) == 1
51   else
52     ds.count == 1
53   end
54 end
database_function_password_match?(name, hash_id, password, salt)
[show source]
    # File lib/rodauth/features/argon2.rb
121 def database_function_password_match?(name, hash_id, password, salt)
122   return true if super
123 
124   if use_argon2? && argon2_hash_algorithm?(salt) && argon2_old_secret != argon2_secret && (ret = db.get(Sequel.function(function_name(name), hash_id, argon2_password_hash_using_salt_and_secret(password, salt, argon2_old_secret))))
125     @update_password_hash = true
126   end
127 
128   !!ret
129 end
db()
[show source]
    # File lib/rodauth/features/base.rb
325 def db
326   Sequel::DATABASES.first or raise "Sequel database connection is missing"
327 end
delete_account()
[show source]
   # File lib/rodauth/features/close_account.rb
77 def delete_account
78   account_ds.delete
79 end
delete_account_on_close?()
[show source]
   # File lib/rodauth/features/close_account.rb
81 def delete_account_on_close?
82   skip_status_checks?
83 end
disable_remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
159 def disable_remember_login
160   remove_remember_key
161 end
domain()
[show source]
    # File lib/rodauth/features/base.rb
576 def domain
577   request.host
578 end
email_auth_ds(id=account_id)
[show source]
    # File lib/rodauth/features/email_auth.rb
243 def email_auth_ds(id=account_id)
244   db[email_auth_table].where(email_auth_id_column=>id)
245 end
email_auth_email_recently_sent?()
[show source]
    # File lib/rodauth/features/email_auth.rb
177 def email_auth_email_recently_sent?
178   (email_last_sent = get_email_auth_email_last_sent) && (Time.now - email_last_sent < email_auth_skip_resend_email_within)
179 end
email_auth_key_insert_hash()
[show source]
    # File lib/rodauth/features/email_auth.rb
237 def email_auth_key_insert_hash
238   hash = {email_auth_id_column=>account_id, email_auth_key_column=>email_auth_key_value}
239   set_deadline_value(hash, email_auth_deadline_column, email_auth_deadline_interval)
240   hash
241 end
email_auth_request_form()
[show source]
    # File lib/rodauth/features/email_auth.rb
156 def email_auth_request_form
157   render('email-auth-request-form')
158 end
email_from()
[show source]
   # File lib/rodauth/features/email_base.rb
33 def email_from
34   "webmaster@#{domain}"
35 end
email_to()
[show source]
   # File lib/rodauth/features/email_base.rb
37 def email_to
38   account[login_column]
39 end
expire_session()
[show source]
   # File lib/rodauth/features/session_expiration.rb
38 def expire_session
39   clear_session
40   set_redirect_error_status session_expiration_error_status
41   set_error_reason :session_expired
42   set_redirect_error_flash session_expiration_error_flash
43   redirect session_expiration_redirect
44 end
extend_remember_deadline()
[show source]
    # File lib/rodauth/features/remember.rb
216 def extend_remember_deadline
217   active_remember_key_ds.update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
218   remember_login
219 end
extend_remember_deadline_while_logged_in?()
[show source]
    # File lib/rodauth/features/remember.rb
204 def extend_remember_deadline_while_logged_in?
205   return false unless extend_remember_deadline?
206 
207   if extended_at = session[remember_deadline_extended_session_key]
208     extended_at + extend_remember_deadline_period < Time.now.to_i
209   elsif logged_in_via_remember_key?
210     # Handle existing sessions before the change to extend remember deadline
211     # while logged in.
212     true
213   end
214 end
extract_password_hash_cost(hash)
[show source]
   # File lib/rodauth/features/argon2.rb
70 def extract_password_hash_cost(hash)
71   return super unless argon2_hash_algorithm?(hash)
72 
73   /\A\$argon2id\$v=\d+\$m=(\d+),t=(\d+),p=(\d+)/ =~ hash
74   { t_cost: $2.to_i, m_cost: Math.log2($1.to_i).to_i, p_cost: $3.to_i }
75 end
features()
[show source]
    # File lib/rodauth/features/base.rb
185 def features
186   self.class.features
187 end
field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
260 def field_attributes(field)
261   _field_attributes(field) || default_field_attributes
262 end
field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
217 def field_error(field)
218   return nil unless @field_errors
219   @field_errors[field]
220 end
field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
264 def field_error_attributes(field)
265   if field_error(field)
266     _field_error_attributes(field)
267   end
268 end
flash()
[show source]
    # File lib/rodauth/features/base.rb
201 def flash
202   scope.flash
203 end
forget_login()
[show source]
    # File lib/rodauth/features/remember.rb
142 def forget_login
143   opts = Hash[remember_cookie_options]
144   opts[:path] = "/" unless opts.key?(:path)
145   ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, opts)
146 end
formatted_field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
270 def formatted_field_error(field)
271   if error = field_error(field)
272     _formatted_field_error(field, error)
273   end
274 end
function_name(name)
[show source]
    # File lib/rodauth/features/base.rb
845 def function_name(name)
846   if db.database_type == :mssql
847     # :nocov:
848     "dbo.#{name}"
849     # :nocov:
850   else
851     name
852   end
853 end
generate_active_sessions_key()
[show source]
    # File lib/rodauth/features/active_sessions.rb
195 def generate_active_sessions_key
196   @active_sessions_key = random_key
197 end
generate_email_auth_key_value()
[show source]
    # File lib/rodauth/features/email_auth.rb
229 def generate_email_auth_key_value
230   @email_auth_key_value = random_key
231 end
generate_refresh_token()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
200 def generate_refresh_token
201   hash = jwt_refresh_token_insert_hash
202   [account_id, jwt_refresh_token_ds.insert(hash), convert_token_key(hash[jwt_refresh_token_key_column])].join(token_separator)
203 end
generate_remember_key_value()
[show source]
    # File lib/rodauth/features/remember.rb
257 def generate_remember_key_value
258   @remember_key_value = random_key
259 end
generate_reset_password_key_value()
[show source]
    # File lib/rodauth/features/reset_password.rb
238 def generate_reset_password_key_value
239   @reset_password_key_value = random_key
240 end
generate_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
288 def generate_unlock_account_key
289   random_key
290 end
generate_verify_account_key_value()
[show source]
    # File lib/rodauth/features/verify_account.rb
294 def generate_verify_account_key_value
295   @verify_account_key_value = random_key
296 end
generate_verify_login_change_key_value()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
178 def generate_verify_login_change_key_value
179   @verify_login_change_key_value = random_key
180 end
get_active_refresh_token(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
169 def get_active_refresh_token(account_id, token_id)
170   jwt_refresh_token_account_ds(account_id).
171     where(Sequel::CURRENT_TIMESTAMP > jwt_refresh_token_deadline_column).
172     delete
173 
174   ds = jwt_refresh_token_account_token_ds(account_id, token_id)
175   if @jwt_refresh_key_for_update
176     ds = ds.for_update
177     @jwt_refresh_key_for_update = nil
178   end
179   ds.get(jwt_refresh_token_key_column)
180 end
get_activity_timestamp(account_id, column)
[show source]
    # File lib/rodauth/features/account_expiration.rb
109 def get_activity_timestamp(account_id, column)
110   convert_timestamp(account_activity_ds(account_id).get(column))
111 end
get_email_auth_email_last_sent()
[show source]
    # File lib/rodauth/features/email_auth.rb
130 def get_email_auth_email_last_sent
131   if column = email_auth_email_last_sent_column
132     if ts = email_auth_ds.get(column)
133       convert_timestamp(ts)
134     end
135   end
136 end
get_email_auth_key(id)
[show source]
    # File lib/rodauth/features/email_auth.rb
150 def get_email_auth_key(id)
151   ds = email_auth_ds(id)
152   ds.where(Sequel::CURRENT_TIMESTAMP > email_auth_deadline_column).delete
153   apply_key_for_update(ds).get(email_auth_key_column)
154 end
get_password_changed_at()
[show source]
   # File lib/rodauth/features/password_expiration.rb
26 def get_password_changed_at
27   convert_timestamp(password_expiration_ds.get(password_expiration_changed_at_column))
28 end
get_password_hash()

Get the password hash for the user. When using database authentication functions, note that only the salt is returned.

[show source]
    # File lib/rodauth/features/base.rb
861 def get_password_hash
862   if account_password_hash_column
863     account[account_password_hash_column] if account!
864   elsif use_database_authentication_functions?
865     db.get(Sequel.function(function_name(:rodauth_get_salt), account_id_or_session_value))
866   else
867     # :nocov:
868     password_hash_ds.get(password_hash_column)
869     # :nocov:
870   end
871 end
get_password_reset_key(id)
[show source]
    # File lib/rodauth/features/reset_password.rb
191 def get_password_reset_key(id)
192   # RODAUTH3: Remove method and call get_reset_password_key directly
193   get_reset_password_key(id)
194 end
get_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
148 def get_remember_key
149   unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
150    generate_remember_key_value
151    transaction do
152      remove_remember_key
153      add_remember_key
154    end
155   end
156   nil
157 end
get_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
206 def get_reset_password_email_last_sent
207   if column = reset_password_email_last_sent_column
208     if ts = password_reset_ds.get(column)
209       convert_timestamp(ts)
210     end
211   end
212 end
get_reset_password_key(id)
[show source]
    # File lib/rodauth/features/reset_password.rb
196 def get_reset_password_key(id)
197   ds = password_reset_ds(id)
198   ds.where(Sequel::CURRENT_TIMESTAMP > reset_password_deadline_column).delete
199   apply_key_for_update(ds).get(reset_password_key_column)
200 end
get_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
234 def get_unlock_account_email_last_sent
235   if column = account_lockouts_email_last_sent_column
236     if ts = account_lockouts_ds.get(column)
237       convert_timestamp(ts)
238     end
239   end
240 end
get_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
222 def get_unlock_account_key
223   account_lockouts_ds.get(account_lockouts_key_column)
224 end
get_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
232 def get_verify_account_email_last_sent
233   if column = verify_account_email_last_sent_column
234     if ts = verify_account_ds.get(column)
235       convert_timestamp(ts)
236     end
237   end
238 end
get_verify_account_key(id)
[show source]
    # File lib/rodauth/features/verify_account.rb
211 def get_verify_account_key(id)
212   apply_key_for_update(verify_account_ds(id)).get(verify_account_key_column)
213 end
get_verify_login_change_login_and_key(id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
136 def get_verify_login_change_login_and_key(id)
137   ds = verify_login_change_ds(id)
138   ds.where(Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column).delete
139   apply_key_for_update(ds).get([verify_login_change_login_column, verify_login_change_key_column])
140 end
handle_duplicate_active_session_id(_e)
[show source]
   # File lib/rodauth/features/active_sessions.rb
79 def handle_duplicate_active_session_id(_e)
80   # Do nothing by default as session is already tracked.  This will result in
81   # the current session and the existing session with the same id
82   # being tracked together, so that a logout of one will logout
83   # the other, and updating the last use on one will update the other,
84   # but this should be acceptable.  However, this can be overridden if different
85   # behavior is desired.
86 end
handle_invalid_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
268 def handle_invalid_reset_password_key
269   remove_session_value(reset_password_session_key)
270   set_redirect_error_status(invalid_key_error_status)
271   set_error_reason :invalid_reset_password_key
272   set_redirect_error_flash reset_password_error_flash
273   redirect reset_password_email_sent_redirect
274 end
handle_invalid_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
323 def handle_invalid_verify_account_key
324   remove_session_value(verify_account_session_key)
325   set_redirect_error_status(invalid_key_error_status)
326   set_error_reason :invalid_verify_account_key
327   set_redirect_error_flash verify_account_error_flash
328   redirect verify_account_redirect
329 end
handle_webauthn_sign_count_verification_error()
[show source]
    # File lib/rodauth/features/webauthn.rb
352 def handle_webauthn_sign_count_verification_error
353   throw_error_reason(:invalid_webauthn_sign_count, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message) 
354 end
has_password?()
[show source]
    # File lib/rodauth/features/base.rb
588 def has_password?
589   return @has_password unless @has_password.nil?
590   return false unless account_id_or_session_value
591   @has_password = !!get_password_hash
592 end
hmac_secret_rotation?()
[show source]
    # File lib/rodauth/features/base.rb
896 def hmac_secret_rotation?
897   hmac_secret && hmac_old_secret && hmac_secret != hmac_old_secret
898 end
hook_action(hook_type, action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
31 def hook_action(hook_type, action)
32   super
33 
34   # In after_logout, session is already cleared, so use before_logout in that case
35   if (hook_type == :after || action == :logout) && (id = account_id_or_session_value)
36     add_audit_log(id, action)
37   end
38 end
http_basic_auth()
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
36 def http_basic_auth
37   unless @checked_http_basic_auth.nil?
38     return (@checked_http_basic_auth ? true : nil)
39   end
40 
41   @checked_http_basic_auth = false
42   return unless token = ((v = request.env['HTTP_AUTHORIZATION']) && v[/\A *Basic (.*)\Z/, 1])
43 
44   username, password = token.unpack("m*").first.split(/:/, 2)
45   return unless username && password
46 
47   catch_error do
48     unless account_from_login(username)
49       after_no_matching_login
50       throw_basic_auth_error(login_param, no_matching_login_message)
51     end
52 
53     before_login_attempt
54 
55     unless open_account?
56       throw_basic_auth_error(login_param, no_matching_login_message)
57     end
58 
59     unless password_match?(password)
60       after_login_failure
61       throw_basic_auth_error(password_param, invalid_password_message)
62     end
63 
64     transaction do
65       before_login
66       login_session('password')
67       after_login
68     end
69 
70     @checked_http_basic_auth = true
71     return true
72   end
73 
74   nil
75 end
inactive_session_cond()
[show source]
    # File lib/rodauth/features/active_sessions.rb
225 def inactive_session_cond
226   cond = session_inactivity_deadline_condition
227   cond2 = session_lifetime_deadline_condition
228   return false unless cond || cond2
229   Sequel.|(*[cond, cond2].compact)
230 end
include_success_messages?()
[show source]
    # File lib/rodauth/features/json.rb
224 def include_success_messages?
225   !json_response_success_key.nil?
226 end
input_field_string(param, id, opts=OPTS)
[show source]
    # File lib/rodauth/features/base.rb
228 def input_field_string(param, id, opts=OPTS)
229   type = opts.fetch(:type, "text")
230 
231   unless type == "password"
232     value = opts.fetch(:value){scope.h param(param)}
233   end
234 
235   field_class = opts.fetch(:class, "form-control")
236 
237   if autocomplete_for_field?(param) && opts[:autocomplete]
238     autocomplete = "autocomplete=\"#{opts[:autocomplete]}\""
239   end
240 
241   if inputmode_for_field?(param) && opts[:inputmode]
242     inputmode = "inputmode=\"#{opts[:inputmode]}\""
243   end
244 
245   if mark_input_fields_as_required? && opts[:required] != false
246     required = "required=\"required\""
247   end
248 
249   "<input #{opts[:attr]} #{autocomplete} #{inputmode} #{required} #{field_attributes(param)} #{field_error_attributes(param)} type=\"#{type}\" class=\"#{field_class}#{add_field_error_class(param)}\" name=\"#{param}\" id=\"#{id}\" value=\"#{value}\"/> #{formatted_field_error(param) unless opts[:skip_error_message]}"
250 end
inputmode_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
256 def inputmode_for_field?(_param)
257   mark_input_fields_with_inputmode?
258 end
instance_variables_to_inspect()

:nocov:

[show source]
     # File lib/rodauth/features/base.rb
1029 def instance_variables_to_inspect
1030   instance_variables.reject{|v| instance_variable_get(v).nil?}
1031 end
internal_request?()
[show source]
     # File lib/rodauth/features/base.rb
1010 def internal_request?
1011   false
1012 end
internal_request_configuration(&block)
[show source]
    # File lib/rodauth/features/internal_request.rb
391 def internal_request_configuration(&block)
392   @auth.instance_exec do
393     (@internal_request_configuration_blocks ||= []) << block
394   end
395 end
invalid_login_attempted()
[show source]
    # File lib/rodauth/features/lockout.rb
181 def invalid_login_attempted
182   ds = account_login_failures_ds.
183       where(account_login_failures_id_column=>account_id)
184 
185   number = if db.database_type == :postgres
186     ds.returning(account_login_failures_number_column).
187       with_sql(:update_sql, account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1).
188       single_value
189   else
190     # :nocov:
191     if ds.update(account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1) > 0
192       ds.get(account_login_failures_number_column)
193     end
194     # :nocov:
195   end
196 
197   unless number
198     # Ignoring the violation is safe here.  It may allow slightly more than max_invalid_logins invalid logins before
199     # lockout, but allowing a few extra is OK if the race is lost.
200     ignore_uniqueness_violation{account_login_failures_ds.insert(account_login_failures_id_column=>account_id)}
201     number = 1
202   end
203 
204   if number >= max_invalid_logins
205     @unlock_account_key_value = generate_unlock_account_key
206     hash = _setup_account_lockouts_hash(account_id, unlock_account_key_value)
207 
208     if e = raised_uniqueness_violation{account_lockouts_ds.insert(hash)}
209       # If inserting into the lockout table raises a violation, we should just be able to pull the already inserted
210       # key out of it.  If that doesn't return a valid key, we should reraise the error.
211       raise e unless @unlock_account_key_value = account_lockouts_ds.get(account_lockouts_key_column)
212 
213       after_account_lockout
214       show_lockout_page
215     else
216       after_account_lockout
217       e
218     end
219   end
220 end
invalid_previous_password_message()
[show source]
   # File lib/rodauth/features/change_password.rb
82 def invalid_previous_password_message
83   invalid_password_message
84 end
json_request?()
[show source]
   # File lib/rodauth/features/json.rb
59 def json_request?
60   return @json_request unless @json_request.nil?
61   @json_request = !(request.content_type !~ json_request_content_type_regexp)
62 end
json_response()
[show source]
    # File lib/rodauth/features/json.rb
232 def json_response
233   @json_response ||= {}
234 end
json_response_error?()
[show source]
   # File lib/rodauth/features/json.rb
73 def json_response_error?
74   !!json_response[json_response_error_key]
75 end
jwt_cors_allow?()
[show source]
   # File lib/rodauth/features/jwt_cors.rb
16 def jwt_cors_allow?
17   return false unless origin = request.env['HTTP_ORIGIN']
18 
19   case allowed = jwt_cors_allow_origin
20   when String
21     timing_safe_eql?(origin, allowed)
22   when Array
23     allowed.any?{|s| timing_safe_eql?(origin, s)}
24   when Regexp
25     allowed =~ origin
26   when true
27     true
28   else
29     false
30   end
31 end
jwt_payload()
[show source]
    # File lib/rodauth/features/jwt.rb
124 def jwt_payload
125   return @jwt_payload unless @jwt_payload.nil?
126   @jwt_payload = JWT.decode(jwt_token, _jwt_decode_secrets, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
127 rescue JWT::DecodeError => e
128   rescue_jwt_payload(e)
129 end
jwt_refresh_token_account_ds(account_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
182 def jwt_refresh_token_account_ds(account_id)
183   jwt_refresh_token_ds.where(jwt_refresh_token_account_id_column => account_id)
184 end
jwt_refresh_token_account_token_ds(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
186 def jwt_refresh_token_account_token_ds(account_id, token_id)
187   jwt_refresh_token_account_ds(account_id).
188     where(jwt_refresh_token_id_column=>token_id)
189 end
jwt_refresh_token_ds()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
191 def jwt_refresh_token_ds
192   db[jwt_refresh_token_table]
193 end
jwt_refresh_token_insert_hash()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
205 def jwt_refresh_token_insert_hash
206   hash = {jwt_refresh_token_account_id_column => account_id, jwt_refresh_token_key_column => random_key}
207   set_deadline_value(hash, jwt_refresh_token_deadline_column, jwt_refresh_token_deadline_interval)
208   hash
209 end
jwt_refresh_token_match?(key)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
158 def jwt_refresh_token_match?(key)
159   # We don't need to match tokens if we are requiring a valid current access token
160   return true unless allow_refresh_with_expired_jwt_access_token?
161 
162   # If allowing with expired jwt access token, check the expired session contains
163   # hmac matching submitted and active refresh token.
164   s = session[jwt_refresh_token_hmac_session_key].to_s
165   h = session[jwt_refresh_token_data_session_key].to_s + key
166   timing_safe_eql?(compute_hmac(h), s) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(h), s))
167 end
jwt_secret()
[show source]
   # File lib/rodauth/features/jwt.rb
68 def jwt_secret
69   raise ConfigurationError, "jwt_secret not set"
70 end
jwt_session_hash()
[show source]
   # File lib/rodauth/features/jwt.rb
72 def jwt_session_hash
73   jwt_session_key ? {jwt_session_key=>session} : session
74 end
jwt_token()
[show source]
   # File lib/rodauth/features/jwt.rb
80 def jwt_token
81   return @jwt_token if @jwt_token
82 
83   if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
84     @jwt_token = v.sub(jwt_authorization_remove, '')
85   end
86 end
last_account_activity_at()
[show source]
   # File lib/rodauth/features/account_expiration.rb
27 def last_account_activity_at
28   get_activity_timestamp(session_value, account_activity_last_activity_column)
29 end
last_account_login_at()
[show source]
   # File lib/rodauth/features/account_expiration.rb
31 def last_account_login_at
32   get_activity_timestamp(session_value, account_activity_last_login_column)
33 end
load_memory()
[show source]
    # File lib/rodauth/features/remember.rb
118 def load_memory
119   if logged_in?
120     if extend_remember_deadline_while_logged_in?
121       if account_from_session
122         extend_remember_deadline
123       else
124         forget_login
125         clear_session
126       end
127     end
128   elsif account_from_remember_cookie
129     before_load_memory
130     login_session('remember')
131     extend_remember_deadline if extend_remember_deadline?
132     after_load_memory
133   end
134 end
loaded_templates()
[show source]
    # File lib/rodauth/features/base.rb
950 def loaded_templates
951   []
952 end
locked_out?()
[show source]
    # File lib/rodauth/features/lockout.rb
152 def locked_out?
153   if t = convert_timestamp(account_lockouts_ds.get(account_lockouts_deadline_column))
154     if Time.now < t
155       true
156     else
157       unlock_account
158       false
159     end
160   else
161     false
162   end
163 end
logged_in_via_remember_key?()
[show source]
    # File lib/rodauth/features/remember.rb
178 def logged_in_via_remember_key?
179   authenticated_by.include?('remember')
180 end
login(auth_type)
[show source]
    # File lib/rodauth/features/login.rb
 97 def login(auth_type)
 98   @saved_login_redirect = remove_session_value(login_redirect_session_key)
 99   transaction do
100     before_login
101     login_session(auth_type)
102     yield if block_given?
103     after_login
104   end
105   require_response(:_login_response)
106 end
login_confirm_label()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
49 def login_confirm_label
50   "Confirm #{login_label}"
51 end
login_confirmation_matches?(login, login_confirmation)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
159 def login_confirmation_matches?(login, login_confirmation)
160   login.casecmp?(login_confirmation)
161 end
login_does_not_meet_requirements_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
137 def login_does_not_meet_requirements_message
138   "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
139 end
login_failed_reset_password_request_form()
[show source]
    # File lib/rodauth/features/reset_password.rb
242 def login_failed_reset_password_request_form
243   render("reset-password-request")
244 end
login_field_autocomplete_value()
[show source]
    # File lib/rodauth/features/base.rb
329 def login_field_autocomplete_value
330   login_uses_email? ? "email" : "on"
331 end
login_hidden_field()
[show source]
    # File lib/rodauth/features/login.rb
140 def login_hidden_field
141   "<input type='hidden' name=\"#{login_param}\" value=\"#{scope.h param(login_param)}\" />"
142 end
login_input_type()
[show source]
    # File lib/rodauth/features/base.rb
355 def login_input_type
356   login_uses_email? ? 'email' : 'text'
357 end
login_meets_email_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
185 def login_meets_email_requirements?(login)
186   return true unless require_email_address_logins?
187   return true if login_valid_email?(login)
188   set_login_requirement_error_message(:login_not_valid_email, login_not_valid_email_message)
189   return false
190 end
login_meets_length_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
170 def login_meets_length_requirements?(login)
171   if login_minimum_length > login.length
172     set_login_requirement_error_message(:login_too_short, login_too_short_message)
173     false
174   elsif login_maximum_length < login.length
175     set_login_requirement_error_message(:login_too_long, login_too_long_message)
176     false
177   elsif login_maximum_bytes < login.bytesize
178     set_login_requirement_error_message(:login_too_many_bytes, login_too_many_bytes_message)
179     false
180   else
181     true
182   end
183 end
login_meets_requirements?(login)
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
57 def login_meets_requirements?(login)
58   login_meets_length_requirements?(login) && \
59     login_meets_email_requirements?(login)
60 end
login_param_value()

The normalized value of the login parameter

[show source]
    # File lib/rodauth/features/base.rb
553 def login_param_value
554   normalize_login(param(login_param))
555 end
login_required()
[show source]
    # File lib/rodauth/features/base.rb
374 def login_required
375   set_redirect_error_status(login_required_error_status)
376   set_error_reason :login_required
377   set_redirect_error_flash require_login_error_flash
378   redirect require_login_redirect
379 end
login_return_to_requested_location_path()
[show source]
    # File lib/rodauth/features/login.rb
115 def login_return_to_requested_location_path
116   request.fullpath
117 end
login_session(auth_type)
[show source]
    # File lib/rodauth/features/base.rb
515 def login_session(auth_type)
516   update_session
517   set_session_value(authenticated_by_session_key, [auth_type])
518 end
login_too_long_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
141 def login_too_long_message
142   "maximum #{login_maximum_length} characters"
143 end
login_too_many_bytes_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
145 def login_too_many_bytes_message
146   "maximum #{login_maximum_bytes} bytes"
147 end
login_too_short_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
149 def login_too_short_message
150   "minimum #{login_minimum_length} characters"
151 end
login_uses_email?()
[show source]
    # File lib/rodauth/features/base.rb
359 def login_uses_email?
360   login_column == :email
361 end
login_valid_email?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
192 def login_valid_email?(login)
193   login =~ login_email_regexp
194 end
logout()
[show source]
   # File lib/rodauth/features/logout.rb
34 def logout
35   clear_session
36 end
logout_additional_form_tags()
[show source]
    # File lib/rodauth/features/active_sessions.rb
120 def logout_additional_form_tags
121   super.to_s + render('global-logout-field')
122 end
modifications_require_password?()
[show source]
    # File lib/rodauth/features/base.rb
580 def modifications_require_password?
581   has_password?
582 end
new_account(login)
[show source]
   # File lib/rodauth/features/create_account.rb
96 def new_account(login)
97   @account_retrieval_type = nil
98   set_account(_new_account(login), :new)
99 end
new_password_matches_current_password?(password)
[show source]
    # File lib/rodauth/features/base.rb
873 def new_password_matches_current_password?(password)
874   password_match?(password)
875 end
new_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
245 def new_recovery_code
246   random_key
247 end
new_webauthn_credential()
[show source]
    # File lib/rodauth/features/webauthn.rb
302 def new_webauthn_credential
303   WebAuthn::Credential.options_for_create(
304     :timeout => webauthn_setup_timeout,
305     :user => {:id=>account_webauthn_user_id, :name=>webauthn_user_name},
306     :authenticator_selection => webauthn_authenticator_selection,
307     :attestation => webauthn_attestation,
308     :extensions => webauthn_extensions,
309     :exclude => account_webauthn_ids,
310     **webauthn_create_relying_party_opts
311   )
312 end
no_longer_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
62 def no_longer_active_session
63   clear_session
64   set_redirect_error_status inactive_session_error_status
65   set_error_reason :inactive_session
66   set_redirect_error_flash active_sessions_error_flash
67   redirect active_sessions_redirect
68 end
normalize_login(login)
[show source]
    # File lib/rodauth/features/base.rb
557 def normalize_login(login)
558   login
559 end
normalize_session_or_flash_key(key)
[show source]
    # File lib/rodauth/features/base.rb
763 def normalize_session_or_flash_key(key)
764   scope.opts[:sessions_convert_symbols] ? key.to_s : key
765 end
null_byte_parameter_value(key, value)

Return nil by default for values with null bytes

[show source]
    # File lib/rodauth/features/base.rb
562 def null_byte_parameter_value(key, value)
563   nil
564 end
only_json?()
[show source]
    # File lib/rodauth/features/base.rb
474 def only_json?
475   scope.class.opts[:rodauth_json] == :only
476 end
open_account?()
[show source]
    # File lib/rodauth/features/base.rb
321 def open_account?
322   skip_status_checks? || account[account_status_column] == account_open_status_value 
323 end
otp_add_key()
[show source]
    # File lib/rodauth/features/otp.rb
294 def otp_add_key
295   _otp_add_key(otp_key)
296   super if defined?(super)
297 end
otp_available?()
[show source]
    # File lib/rodauth/features/otp.rb
250 def otp_available?
251   otp_exists? && !otp_locked_out?
252 end
otp_exists?()
[show source]
    # File lib/rodauth/features/otp.rb
254 def otp_exists?
255   !!otp_key
256 end
otp_hmac_old_secret(key)
[show source]
    # File lib/rodauth/features/otp.rb
394 def otp_hmac_old_secret(key)
395   base32_encode(compute_raw_hmac_with_secret(ROTP::Base32.decode(key), hmac_old_secret), key.bytesize)
396 end
otp_hmac_secret(key)
[show source]
    # File lib/rodauth/features/otp.rb
390 def otp_hmac_secret(key)
391   base32_encode(compute_raw_hmac(ROTP::Base32.decode(key)), key.bytesize)
392 end
otp_issuer()
[show source]
    # File lib/rodauth/features/otp.rb
325 def otp_issuer
326   domain
327 end
otp_key_ds()
[show source]
    # File lib/rodauth/features/otp.rb
461 def otp_key_ds
462   db[otp_keys_table].where(otp_keys_id_column=>session_value)
463 end
otp_keys_use_hmac?()
[show source]
    # File lib/rodauth/features/otp.rb
346 def otp_keys_use_hmac?
347   !!hmac_secret
348 end
otp_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
305 def otp_last_use
306   convert_timestamp(otp_key_ds.get(otp_keys_last_use_column))
307 end
otp_locked_out?()
[show source]
    # File lib/rodauth/features/otp.rb
317 def otp_locked_out?
318   otp_key_ds.get(otp_keys_failures_column) >= otp_auth_failures_limit
319 end
otp_lockout_redirect()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
212 def otp_lockout_redirect
213   otp_unlock_path
214 end
otp_new_secret()
[show source]
    # File lib/rodauth/features/otp.rb
412 def otp_new_secret
413   ROTP::Base32.random_base32.downcase
414 end
otp_provisioning_name()
[show source]
    # File lib/rodauth/features/otp.rb
329 def otp_provisioning_name
330   account[login_column]
331 end
otp_provisioning_uri()
[show source]
    # File lib/rodauth/features/otp.rb
321 def otp_provisioning_uri
322   otp.provisioning_uri(otp_provisioning_name)
323 end
otp_qr_code()
[show source]
    # File lib/rodauth/features/otp.rb
333 def otp_qr_code
334   svg = RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true, :use_path=>true, :fill=>"fff")
335   svg.sub(/\A<\?xml version="1\.0" standalone="yes"\?>/, '')
336 end
otp_record_authentication_failure()
[show source]
    # File lib/rodauth/features/otp.rb
309 def otp_record_authentication_failure
310   otp_key_ds.update(otp_keys_failures_column=>Sequel.identifier(otp_keys_failures_column) + 1)
311 end
otp_remove()
[show source]
    # File lib/rodauth/features/otp.rb
289 def otp_remove
290   otp_key_ds.delete
291   @otp_key = false
292 end
otp_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
313 def otp_remove_auth_failures
314   otp_key_ds.update(otp_keys_failures_column=>0)
315 end
otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
385 def otp_tmp_key(secret)
386   _otp_tmp_key(secret)
387   clear_cached_otp
388 end
otp_unlock_auth_failure()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
147 def otp_unlock_auth_failure
148   h = {
149     otp_unlock_num_successes_column=>0,
150     otp_unlock_next_auth_attempt_after_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, :seconds=>otp_unlock_auth_failure_cooldown_seconds)
151   }
152 
153   if otp_unlock_ds.update(h) == 0
154     h[otp_unlock_id_column] = session_value
155 
156     # If row already exists when inserting, no need to do anything
157     raises_uniqueness_violation?{otp_unlock_ds.insert(h)}
158   end
159 end
otp_unlock_auth_success()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
161 def otp_unlock_auth_success
162   deadline = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, :seconds=>otp_unlock_success_cooldown_seconds)
163 
164   # Add WHERE to avoid possible race condition when multiple unlock auth requests
165   # are sent at the same time (only the first should increment num successes).
166   if otp_unlock_ds.
167       where(Sequel[otp_unlock_next_auth_attempt_after_column] < Sequel::CURRENT_TIMESTAMP).
168       update(
169         otp_unlock_num_successes_column=>Sequel[otp_unlock_num_successes_column]+1,
170         otp_unlock_next_auth_attempt_after_column=>deadline
171       ) == 0
172 
173     # Ignore uniqueness errors when inserting after a failed update,
174     # which could be caused due to the race condition mentioned above.
175     raises_uniqueness_violation? do
176       otp_unlock_ds.insert(
177         otp_unlock_id_column=>session_value,
178         otp_unlock_next_auth_attempt_after_column=>deadline
179       )
180     end
181   end
182 
183   @otp_unlock_data = nil
184   # :nocov:
185   if otp_unlock_data
186   # :nocov:
187     if otp_unlock_num_successes >= otp_unlock_auths_required
188       # At least the requisite number of consecutive successful unlock
189       # authentications. Unlock OTP authentication.
190       otp_key_ds.update(otp_keys_failures_column => 0)
191 
192       # Remove OTP unlock metadata when unlocking OTP authentication
193       otp_unlock_reset
194     # else
195     #  # Still need additional consecutive successful unlock attempts.
196     end
197   # else
198   #  # if row isn't available, probably the process was reset during this,
199   #  # and it's safe to do nothing in that case.
200   end
201 end
otp_unlock_available?()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
117 def otp_unlock_available?
118   if otp_unlock_data
119     next_auth_attempt_after = otp_unlock_next_auth_attempt_after
120     current_timestamp = Time.now
121 
122     if (next_auth_attempt_after < current_timestamp - otp_unlock_deadline_seconds)
123       # Unlock process not fully completed within deadline, reset process
124       otp_unlock_reset
125       true
126     else
127       if next_auth_attempt_after > current_timestamp
128         # If next auth attempt after timestamp is in the future, that means the next
129         # unlock attempt cannot happen until then.
130         false 
131       else
132         if otp_unlock_num_successes == 0
133           # 0 value indicates previous attempt was a failure. Since failure cooldown
134           # period has passed, reset process so user gets full deadline period
135           otp_unlock_reset
136         end
137         true
138       end
139     end
140   else
141     # No row means no unlock attempts yet (or previous attempt was more than the
142     # deadline account, so unlocking is available
143     true
144   end
145 end
otp_unlock_data()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
242 def otp_unlock_data
243   @otp_unlock_data ||= otp_unlock_ds.first
244 end
otp_unlock_deadline()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
224 def otp_unlock_deadline
225   otp_unlock_next_auth_attempt_after + otp_unlock_deadline_seconds
226 end
otp_unlock_deadline_passed?()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
203 def otp_unlock_deadline_passed?
204   otp_unlock_data ? (otp_unlock_next_auth_attempt_after < Time.now - otp_unlock_deadline_seconds) : false
205 end
otp_unlock_ds()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
255 def otp_unlock_ds
256   db[otp_unlock_table].where(otp_unlock_id_column=>session_value)
257 end
otp_unlock_next_auth_attempt_after()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
216 def otp_unlock_next_auth_attempt_after
217   if otp_unlock_data
218     convert_timestamp(otp_unlock_data[otp_unlock_next_auth_attempt_after_column])
219   else
220     Time.now
221   end
222 end
otp_unlock_not_available_set_refresh_header()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
232 def otp_unlock_not_available_set_refresh_header
233   response.headers["refresh"] = ((otp_unlock_next_auth_attempt_after - Time.now).to_i + 1).to_s
234 end
otp_unlock_num_successes()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
228 def otp_unlock_num_successes
229   otp_unlock_data ? otp_unlock_data[otp_unlock_num_successes_column] : 0
230 end
otp_unlock_refresh_tag()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
207 def otp_unlock_refresh_tag
208   # RODAUTH3: Remove
209   "<meta http-equiv=\"refresh\" content=\"#{(otp_unlock_next_auth_attempt_after - Time.now).to_i + 1}\">"
210 end
otp_unlock_reset()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
250 def otp_unlock_reset
251   otp_unlock_ds.delete
252   @otp_unlock_data = nil
253 end
otp_unlock_success_cooldown_seconds()
[show source]
    # File lib/rodauth/features/otp_unlock.rb
246 def otp_unlock_success_cooldown_seconds
247   (_otp_interval+(otp_drift||0))*2
248 end
otp_update_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
299 def otp_update_last_use
300   otp_key_ds.
301     where(Sequel.date_add(otp_keys_last_use_column, :seconds=>_otp_interval) < Sequel::CURRENT_TIMESTAMP).
302     update(otp_keys_last_use_column=>Sequel::CURRENT_TIMESTAMP) == 1
303 end
otp_user_key()
[show source]
    # File lib/rodauth/features/otp.rb
338 def otp_user_key
339   @otp_user_key ||= if otp_keys_use_hmac?
340     otp_hmac_secret(otp_key)
341   else
342     otp_key
343   end
344 end
otp_valid_code?(ot_pass)
[show source]
    # File lib/rodauth/features/otp.rb
258 def otp_valid_code?(ot_pass)
259   if _otp_valid_code?(ot_pass, otp)
260     true
261   elsif hmac_secret_rotation? && _otp_valid_code?(ot_pass, _otp_for_key(otp_hmac_old_secret(otp_key)))
262     _otp_valid_code_for_old_secret
263     true
264   else
265     false
266   end
267 end
otp_valid_key?(secret)
[show source]
    # File lib/rodauth/features/otp.rb
398 def otp_valid_key?(secret)
399   return false unless secret =~ /\A([a-z2-7]{16}|[a-z2-7]{32})\z/
400   if otp_keys_use_hmac?
401     # Purposely do not allow creating new OTPs with old secrets,
402     # since OTP rotation is difficult.  The user will get shown
403     # the same page with an updated secret, which they can submit
404     # to setup OTP.
405     timing_safe_eql?(otp_hmac_secret(param(otp_setup_raw_param)), secret)
406   else
407     true
408   end
409 end
over_max_bytesize_param_value(key, value)

Return nil by default for values over maximum bytesize.

[show source]
    # File lib/rodauth/features/base.rb
548 def over_max_bytesize_param_value(key, value)
549   nil
550 end
param(key)

Return a string for the parameter name. This will be an empty string if the parameter doesn’t exist.

[show source]
    # File lib/rodauth/features/base.rb
531 def param(key)
532   param_or_nil(key).to_s
533 end
param_or_nil(key)

Return a string for the parameter name, or nil if there is no parameter with that name.

[show source]
    # File lib/rodauth/features/base.rb
537 def param_or_nil(key)
538   value = raw_param(key)
539   unless value.nil?
540     value = value.to_s
541     value = over_max_bytesize_param_value(key, value) if max_param_bytesize && value.bytesize > max_param_bytesize
542     value = null_byte_parameter_value(key, value) if value && value.include?("\0")
543   end
544   value
545 end
password_bytesize(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
211 def password_bytesize(password)
212   password.bytesize
213 end
password_confirm_label()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
53 def password_confirm_label
54   "Confirm #{password_label}"
55 end
password_does_not_contain_null_byte?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
215 def password_does_not_contain_null_byte?(password)
216   return true unless password.include?("\0")
217   set_password_requirement_error_message(:password_contains_null_byte, contains_null_byte_message)
218   false
219 end
password_does_not_meet_requirements_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
116 def password_does_not_meet_requirements_message
117   "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
118 end
password_doesnt_match_previous_password?(password)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
52 def password_doesnt_match_previous_password?(password)
53   match = if use_database_authentication_functions?
54     salts = previous_password_ds.
55       select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
56     return true if salts.empty?
57 
58     salts.any? do |hash_id, salt|
59       database_function_password_match?(:rodauth_previous_password_hash_match, hash_id, password, salt)
60     end
61   else
62     # :nocov:
63     previous_password_ds.select_map(previous_password_hash_column).any? do |hash|
64       password_hash_match?(hash, password)
65     end
66     # :nocov:
67   end
68 
69   return true unless match
70   set_password_requirement_error_message(:password_same_as_previous_password, password_same_as_previous_password_message)
71   false
72 end
password_expiration_ds()
[show source]
    # File lib/rodauth/features/password_expiration.rb
106 def password_expiration_ds
107   db[password_expiration_table].where(password_expiration_id_column=>account_id)
108 end
password_expired?()
[show source]
   # File lib/rodauth/features/password_expiration.rb
68 def password_expired?
69   if password_changed_at = session[password_changed_at_session_key]
70     return password_changed_at + require_password_change_after < Time.now.to_i
71   end
72 
73   if password_changed_at = get_password_changed_at
74     set_session_value(password_changed_at_session_key, password_changed_at.to_i)
75     password_changed_at + require_password_change_after < Time.now
76   else
77     set_session_value(password_changed_at_session_key, password_expiration_default ? 0 : 2147483647)
78     password_expiration_default
79   end
80 end
password_field_autocomplete_value()
[show source]
    # File lib/rodauth/features/base.rb
333 def password_field_autocomplete_value
334   @password_field_autocomplete_value || 'current-password'
335 end
password_has_enough_character_groups?(password)
[show source]
   # File lib/rodauth/features/password_complexity.rb
54 def password_has_enough_character_groups?(password)
55   return true if password.length > password_max_length_for_groups_check
56   return true if password_character_groups.select{|re| password =~ re}.length >= password_min_groups
57   set_password_requirement_error_message(:not_enough_character_groups_in_password, password_not_enough_character_groups_message)
58   false
59 end
password_has_no_invalid_pattern?(password)
[show source]
   # File lib/rodauth/features/password_complexity.rb
61 def password_has_no_invalid_pattern?(password)
62   return true unless password_invalid_pattern
63   return true if password !~ password_invalid_pattern
64   set_password_requirement_error_message(:invalid_password_pattern, password_invalid_pattern_message)
65   false
66 end
password_hash(password)
[show source]
   # File lib/rodauth/features/argon2.rb
21 def password_hash(password)
22   return super unless use_argon2?
23 
24   if secret = argon2_secret
25     argon2_params = Hash[password_hash_cost]
26     argon2_params[:secret] = secret
27   else
28     argon2_params = password_hash_cost
29   end
30   ::Argon2::Password.new(argon2_params).create(password)
31 end
password_hash_cost()
[show source]
   # File lib/rodauth/features/argon2.rb
47 def password_hash_cost
48   return super unless use_argon2?
49   argon2_hash_cost
50 end
password_hash_ds()
[show source]
    # File lib/rodauth/features/base.rb
940 def password_hash_ds
941   db[password_hash_table].where(password_hash_id_column=>account_id_or_session_value)
942 end
password_hash_match?(hash, password)
[show source]
   # File lib/rodauth/features/argon2.rb
52 def password_hash_match?(hash, password)
53   return super unless argon2_hash_algorithm?(hash)
54   argon2_password_hash_match?(hash, password)
55 end
password_hash_using_salt(password, salt)
[show source]
   # File lib/rodauth/features/argon2.rb
57 def password_hash_using_salt(password, salt)
58   return super unless argon2_hash_algorithm?(salt)
59   argon2_password_hash_using_salt_and_secret(password, salt, argon2_secret)
60 end
password_match?(password)
[show source]
    # File lib/rodauth/features/base.rb
496 def password_match?(password)
497   if @existing_password_hash_or_salt = hash = get_password_hash
498     if account_password_hash_column || !use_database_authentication_functions?
499       password_hash_match?(hash, password)
500     else
501       database_function_password_match?(:rodauth_valid_password_hash, account_id, password, hash)
502     end 
503   end
504 end
password_meets_length_requirements?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
196 def password_meets_length_requirements?(password)
197   if password_minimum_length > password.length
198     set_password_requirement_error_message(:password_too_short, password_too_short_message)
199     false
200   elsif password_maximum_length && password_maximum_length < password.length
201     set_password_requirement_error_message(:password_too_long, password_too_long_message)
202     false
203   elsif password_maximum_bytes && password_maximum_bytes < password_bytesize(password)
204     set_password_requirement_error_message(:password_too_many_bytes, password_too_many_bytes_message)
205     false
206   else
207     true
208   end
209 end
password_meets_requirements?(password)
[show source]
   # File lib/rodauth/features/disallow_common_passwords.rb
13 def password_meets_requirements?(password)
14   super && password_not_one_of_the_most_common?(password)
15 end
password_not_in_dictionary?(password)
[show source]
   # File lib/rodauth/features/password_complexity.rb
75 def password_not_in_dictionary?(password)
76   return true unless dict = password_dictionary
77   return true unless password =~ /\A(?:\d*)([A-Za-z!@$+|][A-Za-z!@$+|0134578]+[A-Za-z!@$+|])(?:\d*)\z/
78   word = $1.downcase.tr('!@$+|0134578', 'iastloleastb')
79   return true if !dict.include?(word)
80   set_password_requirement_error_message(:password_in_dictionary, password_in_dictionary_message)
81   false
82 end
password_not_one_of_the_most_common?(password)
[show source]
   # File lib/rodauth/features/disallow_common_passwords.rb
33 def password_not_one_of_the_most_common?(password)
34   return true unless password_one_of_most_common?(password)
35   set_password_requirement_error_message(:password_is_one_of_the_most_common, password_is_one_of_the_most_common_message)
36   false
37 end
password_not_too_many_repeating_characters?(password)
[show source]
   # File lib/rodauth/features/password_complexity.rb
68 def password_not_too_many_repeating_characters?(password)
69   return true if password_max_repeating_characters < 2
70   return true if password !~ /(.)(\1){#{password_max_repeating_characters-1}}/ 
71   set_password_requirement_error_message(:too_many_repeating_characters_in_password, password_too_many_repeating_characters_message)
72   false
73 end
password_one_of_most_common?(password)
[show source]
   # File lib/rodauth/features/disallow_common_passwords.rb
27 def password_one_of_most_common?(password)
28   most_common_passwords.include?(password)
29 end
password_recently_entered?()
[show source]
   # File lib/rodauth/features/password_grace_period.rb
24 def password_recently_entered?
25   return false unless last_password_entry = session[last_password_entry_session_key]
26   last_password_entry + password_grace_period > Time.now.to_i
27 end
password_reset_ds(id=account_id)
[show source]
    # File lib/rodauth/features/reset_password.rb
256 def password_reset_ds(id=account_id)
257   db[reset_password_table].where(reset_password_id_column=>id)
258 end
password_too_long_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
120 def password_too_long_message
121   "maximum #{password_maximum_length} characters"
122 end
password_too_many_bytes_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
124 def password_too_many_bytes_message
125   "maximum #{password_maximum_bytes} bytes"
126 end
password_too_short_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
128 def password_too_short_message
129   "minimum #{password_minimum_length} characters"
130 end
possible_authentication_methods()
[show source]
    # File lib/rodauth/features/base.rb
584 def possible_authentication_methods
585   has_password? ? ['password'] : []
586 end
post_configure()
[show source]
    # File lib/rodauth/features/base.rb
478 def post_configure
479   require 'bcrypt' if require_bcrypt?
480   db.extension :date_arithmetic if use_date_arithmetic?
481 
482   if method(:convert_token_id_to_integer?).owner == Rodauth::Base && (db rescue false) && db.table_exists?(accounts_table) && db.schema(accounts_table).find{|col, v| break v[:type] == :integer if col == account_id_column}
483     self.class.send(:define_method, :convert_token_id_to_integer?){true}
484   end
485 
486   route_hash= {}
487   self.class.routes.each do |meth|
488     route_meth = "#{meth.to_s.sub(/\Ahandle_/, '')}_route"
489     if route = send(route_meth)
490       route_hash["/#{route}"] = meth
491     end
492   end
493   self.class.route_hash = route_hash.freeze
494 end
previous_password_ds()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
96 def previous_password_ds
97   db[previous_password_hash_table].where(previous_password_account_id_column=>account_id)
98 end
raises_uniqueness_violation?(&block)

In cases where retrying on uniqueness violations cannot work, this will detect whether a uniqueness violation is raised by the block and return the exception if so. This method should be used if you don’t care about the exception itself.

[show source]
    # File lib/rodauth/features/base.rb
969 def raises_uniqueness_violation?(&block)
970   transaction(:savepoint=>:only, &block)
971   false
972 rescue unique_constraint_violation_class => e
973   e
974 end
random_key()
[show source]
    # File lib/rodauth/features/base.rb
754 def random_key
755   SecureRandom.urlsafe_base64(32)
756 end
raw_param(key)
[show source]
    # File lib/rodauth/features/base.rb
566 def raw_param(key)
567   request.params[key]
568 end
recovery_code_match?(code)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
162 def recovery_code_match?(code)
163   recovery_codes.each do |s|
164     if timing_safe_eql?(code, s)
165       unless recovery_codes_ds.where(recovery_codes_column=>code).delete == 1
166         return false
167       end
168 
169       if recovery_codes_primary?
170         add_recovery_code
171       end
172       return true
173     end
174   end
175   false
176 end
recovery_codes_available?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
201 def recovery_codes_available?
202   !recovery_codes_ds.empty?
203 end
recovery_codes_ds()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
269 def recovery_codes_ds
270   db[recovery_codes_table].where(recovery_codes_id_column=>session_value)
271 end
recovery_codes_primary?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
249 def recovery_codes_primary?
250   (features & [:otp, :sms_codes, :webauthn]).empty?
251 end
recovery_codes_remove()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
158 def recovery_codes_remove
159   recovery_codes_ds.delete
160 end
redirect(path)
[show source]
    # File lib/rodauth/features/base.rb
730 def redirect(path)
731   request.redirect(path)
732 end
remember_key_ds(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
265 def remember_key_ds(id=account_id)
266   db[remember_table].where(remember_id_column=>id)
267 end
remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
136 def remember_login
137   get_remember_key
138   set_remember_cookie
139   set_session_value(remember_deadline_extended_session_key, Time.now.to_i) if extend_remember_deadline?
140 end
remembered_session_id()
[show source]
    # File lib/rodauth/features/remember.rb
 95 def remembered_session_id
 96   return unless cookie = _get_remember_cookie
 97   id, key = cookie.split('_', 2)
 98   return unless id && key
 99 
100   actual, deadline = active_remember_key_ds(id).get([remember_key_column, remember_deadline_column])
101   return unless actual
102 
103   if hmac_secret && !(valid = timing_safe_eql?(key, compute_hmac(actual)))
104     if hmac_secret_rotation? && (valid = timing_safe_eql?(key, compute_old_hmac(actual)))
105       _set_remember_cookie(id, actual, deadline)
106     elsif !(raw_remember_token_deadline && raw_remember_token_deadline > convert_timestamp(deadline))
107       return
108     end
109   end
110 
111   unless valid || timing_safe_eql?(key, actual)
112     return
113   end
114 
115   id
116 end
remove_active_session(session_id)
[show source]
   # File lib/rodauth/features/active_sessions.rb
94 def remove_active_session(session_id)
95   active_sessions_ds.where(active_sessions_session_id_column=>session_id).delete
96 end
remove_all_active_sessions()
[show source]
    # File lib/rodauth/features/active_sessions.rb
 98 def remove_all_active_sessions
 99   active_sessions_ds.delete
100 end
remove_all_active_sessions_except_current()
[show source]
    # File lib/rodauth/features/active_sessions.rb
106 def remove_all_active_sessions_except_current 
107   if session_id = session[session_id_session_key]
108     remove_all_active_sessions_except_for(session_id)
109   else
110     remove_all_active_sessions
111   end
112 end
remove_all_active_sessions_except_for(session_id)
[show source]
    # File lib/rodauth/features/active_sessions.rb
102 def remove_all_active_sessions_except_for(session_id)
103   active_sessions_ds.exclude(active_sessions_session_id_column=>compute_hmacs(session_id)).delete
104 end
remove_all_webauthn_keys_and_user_ids()
[show source]
    # File lib/rodauth/features/webauthn.rb
381 def remove_all_webauthn_keys_and_user_ids
382   webauthn_user_ids_ds.delete
383   webauthn_keys_ds.delete
384 end
remove_current_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
88 def remove_current_session
89   if session_id = session[session_id_session_key]
90     remove_active_session(compute_hmacs(session_id))
91   end
92 end
remove_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
138 def remove_email_auth_key
139   email_auth_ds.delete
140 end
remove_inactive_sessions()
[show source]
    # File lib/rodauth/features/active_sessions.rb
114 def remove_inactive_sessions
115   if cond = inactive_session_cond
116     active_sessions_ds.where(cond).delete
117   end
118 end
remove_jwt_refresh_token_key(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
195 def remove_jwt_refresh_token_key(token)
196   account_id, token_id, _ = _account_refresh_token_split(token)
197   jwt_refresh_token_account_token_ds(account_id, token_id).delete
198 end
remove_lockout_metadata()
[show source]
    # File lib/rodauth/features/lockout.rb
292 def remove_lockout_metadata
293   account_login_failures_ds.delete
294   account_lockouts_ds.delete
295 end
remove_remember_key(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
174 def remove_remember_key(id=account_id)
175   remember_key_ds(id).delete
176 end
remove_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
179 def remove_reset_password_key
180   password_reset_ds.delete
181 end
remove_session_value(key)
[show source]
     # File lib/rodauth/features/base.rb
1047 def remove_session_value(key)
1048   session.delete(key)
1049 end
remove_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
169 def remove_verify_account_key
170   verify_account_ds.delete
171 end
remove_verify_login_change_key()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
112 def remove_verify_login_change_key
113   verify_login_change_ds.delete
114 end
remove_webauthn_key(webauthn_id)
[show source]
    # File lib/rodauth/features/webauthn.rb
377 def remove_webauthn_key(webauthn_id)
378   webauthn_keys_ds.where(webauthn_keys_webauthn_id_column=>webauthn_id).delete == 1
379 end
render(page)
[show source]
    # File lib/rodauth/features/base.rb
470 def render(page)
471   _view(:render, page)
472 end
render_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/login.rb
148 def render_multi_phase_login_forms
149   multi_phase_login_forms.sort.map{|_, form, _| form}.join("\n")
150 end
request()
[show source]
    # File lib/rodauth/features/base.rb
189 def request
190   scope.request
191 end
require_account()
[show source]
    # File lib/rodauth/features/base.rb
415 def require_account
416   require_authentication
417   require_account_session
418 end
require_account_session()
[show source]
    # File lib/rodauth/features/base.rb
772 def require_account_session
773   unless account_from_session
774     clear_session
775     login_required
776   end
777 end
require_authentication()
[show source]
    # File lib/rodauth/features/base.rb
411 def require_authentication
412   require_login
413 end
require_current_password()
[show source]
   # File lib/rodauth/features/password_expiration.rb
61 def require_current_password
62   if authenticated? && password_expired? && password_change_needed_redirect != request.path_info
63     set_redirect_error_flash password_expiration_error_flash
64     redirect password_change_needed_redirect
65   end
66 end
require_http_basic_auth()
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
29 def require_http_basic_auth
30   unless http_basic_auth
31     set_http_basic_auth_error_response
32     return_response
33   end
34 end
require_login()
[show source]
    # File lib/rodauth/features/base.rb
403 def require_login
404   login_required unless logged_in?
405 end
require_login_confirmation?()
[show source]
    # File lib/rodauth/features/verify_account.rb
161 def require_login_confirmation?
162   false
163 end
require_login_redirect()
[show source]
    # File lib/rodauth/features/login.rb
152 def require_login_redirect
153   login_path
154 end
require_otp_setup()
[show source]
    # File lib/rodauth/features/otp.rb
241 def require_otp_setup
242   unless otp_exists?
243     set_redirect_error_status(two_factor_not_setup_error_status)
244     set_error_reason :two_factor_not_setup
245     set_redirect_error_flash two_factor_not_setup_error_flash
246     redirect two_factor_need_setup_redirect
247   end
248 end
require_password_authentication()
[show source]
   # File lib/rodauth/features/confirm_password.rb
51 def require_password_authentication
52   require_login
53 
54   if require_password_authentication? && has_password?
55     set_redirect_error_status(password_authentication_required_error_status)
56     set_error_reason :password_authentication_required
57     set_redirect_error_flash password_authentication_required_error_flash
58     set_session_return_to_path(confirm_password_redirect_session_key)
59     redirect password_authentication_required_redirect
60   end
61 end
require_password_authentication?()
[show source]
   # File lib/rodauth/features/confirm_password.rb
87 def require_password_authentication?
88   return true if defined?(super) && super
89   !authenticated_by.include?('password')
90 end
require_response(meth)
[show source]
     # File lib/rodauth/features/base.rb
1038 def require_response(meth)
1039   send(meth)
1040   raise ConfigurationError, "#{meth.to_s.sub(/\A_/, '')} overridden without returning a response (should use redirect or request.halt)."
1041 end
require_sms_available()
[show source]
    # File lib/rodauth/features/sms_codes.rb
341 def require_sms_available
342   require_sms_setup
343 
344   if sms_locked_out?
345     set_redirect_error_status(lockout_error_status)
346     set_error_reason :sms_locked_out
347     set_redirect_error_flash sms_lockout_error_flash
348     redirect sms_lockout_redirect
349   end
350 end
require_sms_not_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
332 def require_sms_not_setup
333   if sms_setup?
334     set_redirect_error_status(sms_already_setup_error_status)
335     set_error_reason :sms_already_setup
336     set_redirect_error_flash sms_already_setup_error_flash
337     redirect sms_already_setup_redirect
338   end
339 end
require_sms_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
323 def require_sms_setup
324   unless sms_setup?
325     set_redirect_error_status(two_factor_not_setup_error_status)
326     set_error_reason :sms_not_setup
327     set_redirect_error_flash sms_not_setup_error_flash
328     redirect sms_needs_setup_redirect
329   end
330 end
require_two_factor_authenticated()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
158 def require_two_factor_authenticated
159   unless two_factor_authenticated?
160     if two_factor_auth_return_to_requested_location?
161       set_session_return_to_path(two_factor_auth_redirect_session_key)
162     end
163     set_redirect_error_status(two_factor_need_authentication_error_status)
164     set_error_reason :two_factor_need_authentication
165     set_redirect_error_flash two_factor_need_authentication_error_flash
166     redirect two_factor_auth_required_redirect
167   end
168 end
require_two_factor_not_authenticated(auth_type = nil)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
149 def require_two_factor_not_authenticated(auth_type = nil)
150   if two_factor_authenticated? || (auth_type && two_factor_login_type_match?(auth_type))
151     set_redirect_error_status(two_factor_already_authenticated_error_status)
152     set_error_reason :two_factor_already_authenticated
153     set_redirect_error_flash two_factor_already_authenticated_error_flash
154     redirect two_factor_already_authenticated_redirect
155   end
156 end
require_two_factor_setup()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
137 def require_two_factor_setup
138   # Avoid database query if already authenticated via 2nd factor
139   return if two_factor_authenticated?
140 
141   return if uses_two_factor_authentication?
142 
143   set_redirect_error_status(two_factor_not_setup_error_status)
144   set_error_reason :two_factor_not_setup
145   set_redirect_error_flash two_factor_not_setup_error_flash
146   redirect two_factor_need_setup_redirect
147 end
require_webauthn_setup()
[show source]
    # File lib/rodauth/features/webauthn.rb
390 def require_webauthn_setup
391   unless webauthn_setup?
392     set_redirect_error_status(webauthn_not_setup_error_status)
393     set_error_reason :webauthn_not_setup
394     set_redirect_error_flash webauthn_not_setup_error_flash
395     redirect two_factor_need_setup_redirect
396   end
397 end
rescue_jwt_payload(_)
[show source]
    # File lib/rodauth/features/jwt.rb
131 def rescue_jwt_payload(_)
132   @jwt_payload = false
133 end
reset_password_account_status_value()
[show source]
    # File lib/rodauth/features/reset_password.rb
264 def reset_password_account_status_value
265   account_open_status_value
266 end
reset_password_email_recently_sent?()
[show source]
    # File lib/rodauth/features/reset_password.rb
214 def reset_password_email_recently_sent?
215   (email_last_sent = get_reset_password_email_last_sent) && (Time.now - email_last_sent < reset_password_skip_resend_email_within)
216 end
reset_password_key_insert_hash()
[show source]
    # File lib/rodauth/features/reset_password.rb
250 def reset_password_key_insert_hash
251   hash = {reset_password_id_column=>account_id, reset_password_key_column=>reset_password_key_value}
252   set_deadline_value(hash, reset_password_deadline_column, reset_password_deadline_interval)
253   hash
254 end
reset_password_request_for_unverified_account()
[show source]
    # File lib/rodauth/features/reset_password.rb
175 def reset_password_request_for_unverified_account
176   throw_error_reason(:unverified_account, unopen_account_error_status, login_param, unverified_account_message)
177 end
reset_single_session_key()
[show source]
   # File lib/rodauth/features/single_session.rb
24 def reset_single_session_key
25   if logged_in?
26     single_session_ds.update(single_session_key_column=>random_key)
27   end
28 end
response()
[show source]
    # File lib/rodauth/features/base.rb
193 def response
194   scope.response
195 end
retry_on_uniqueness_violation(&block)

This is used to avoid race conditions when using the pattern of inserting when an update affects no rows. In such cases, if a row is inserted between the update and the insert, the insert will fail with a uniqueness error, but retrying will work. It is possible for it to fail again, but only if the row is deleted before the update and readded before the insert, which is very unlikely to happen. In such cases, raising an exception is acceptable.

[show source]
    # File lib/rodauth/features/base.rb
960 def retry_on_uniqueness_violation(&block)
961   if raises_uniqueness_violation?(&block)
962     yield
963   end
964 end
return_json_response()
[show source]
    # File lib/rodauth/features/json.rb
214 def return_json_response
215   _return_json_response
216 end
return_response(body=nil)
[show source]
    # File lib/rodauth/features/base.rb
734 def return_response(body=nil)
735   response.write(body) if body
736   request.halt
737 end
route!()
[show source]
    # File lib/rodauth/features/base.rb
205 def route!
206   if meth = self.class.route_hash[request.remaining_path]
207     send(meth)
208   end
209 
210   nil
211 end
route_path(route, opts=OPTS)
[show source]
    # File lib/rodauth/features/base.rb
739 def route_path(route, opts=OPTS)
740   path  = "#{prefix}/#{route}"
741   path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
742   path
743 end
route_url(route, opts=OPTS)
[show source]
    # File lib/rodauth/features/base.rb
745 def route_url(route, opts=OPTS)
746   "#{base_url}#{route_path(route, opts)}"
747 end
save_account()
[show source]
    # File lib/rodauth/features/create_account.rb
101 def save_account
102   id = nil
103   raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}
104 
105   if raised
106     set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
107   end
108 
109   if id
110     account[account_id_column] ||= id
111   end
112 
113   id && !raised
114 end
select_key_for_update!()
[show source]
   # File lib/rodauth/features/email_base.rb
87 def select_key_for_update!
88   @key_for_update = true
89 end
send_email(email)
[show source]
   # File lib/rodauth/features/email_base.rb
43 def send_email(email)
44   email.deliver!
45 end
send_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
128 def send_verify_login_change_email(login)
129   send_email(create_verify_login_change_email(login))
130 end
serialize_audit_log_metadata(metadata)
[show source]
   # File lib/rodauth/features/audit_logging.rb
56 def serialize_audit_log_metadata(metadata)
57   metadata.to_json unless metadata.nil?
58 end
session()
[show source]
    # File lib/rodauth/features/base.rb
197 def session
198   scope.session
199 end
session_inactivity_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
213 def session_inactivity_deadline_condition
214   if deadline = session_inactivity_deadline
215     Sequel[active_sessions_last_use_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
216   end
217 end
session_jwt()
[show source]
   # File lib/rodauth/features/jwt.rb
76 def session_jwt
77   JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
78 end
session_lifetime_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
219 def session_lifetime_deadline_condition
220   if deadline = session_lifetime_deadline
221     Sequel[active_sessions_created_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
222   end
223 end
session_param(session_key, param_name)
[show source]
   # File lib/rodauth/features/email_base.rb
68 def session_param(session_key, param_name)
69   unless value = session[session_key]
70     if allow_param_fallback_for_session_param?
71       value = param(param_name)
72     end
73   end
74 
75   value
76 end
session_value()
[show source]
    # File lib/rodauth/features/base.rb
312 def session_value
313   session[session_key]
314 end
set_account(account, retrieval_type)
[show source]
    # File lib/rodauth/features/base.rb
685 def set_account(account, retrieval_type)
686   account_reload(@account_retrieval_type, retrieval_type) if @account_retrieval_type
687   @account_retrieval_type = retrieval_type
688   @account = account
689 end
set_deadline_value(hash, column, interval)

This is needed on MySQL, which doesn’t support non constant defaults other than CURRENT_TIMESTAMP.

[show source]
     # File lib/rodauth/features/base.rb
 996 def set_deadline_value(hash, column, interval)
 997   if set_deadline_values?
 998     # :nocov:
 999     hash[column] = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, interval)
1000     # :nocov:
1001   end
1002 end
set_deadline_values?()
[show source]
    # File lib/rodauth/features/base.rb
822 def set_deadline_values?
823   db.database_type == :mysql
824 end
set_email_auth_email_last_sent()
[show source]
    # File lib/rodauth/features/email_auth.rb
126 def set_email_auth_email_last_sent
127    email_auth_ds.update(email_auth_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if email_auth_email_last_sent_column
128 end
set_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
387 def set_error_flash(message)
388   flash.now[flash_error_key] = message
389 end
set_error_reason(reason)
[show source]
    # File lib/rodauth/features/base.rb
810 def set_error_reason(reason)
811 end
set_expired()
[show source]
   # File lib/rodauth/features/account_expiration.rb
49 def set_expired
50   update_activity(account_id, account_activity_expired_column)
51   after_account_expiration
52 end
set_field_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
213 def set_field_error(field, error)
214   (@field_errors ||= {})[field] = error
215 end
set_http_basic_auth_error_response()
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
79 def set_http_basic_auth_error_response
80   response.status = 401
81   set_response_header("www-authenticate", "Basic realm=\"#{http_basic_auth_realm}\"")
82 end
set_jwt()
[show source]
    # File lib/rodauth/features/jwt.rb
158 def set_jwt
159   set_jwt_token(session_jwt)
160 end
set_jwt_refresh_token_hmac_session_key(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
211 def set_jwt_refresh_token_hmac_session_key(token)
212   if allow_refresh_with_expired_jwt_access_token?
213     key = _account_refresh_token_split(token).last
214     data = random_key
215     set_session_value(jwt_refresh_token_data_session_key, data)
216     set_session_value(jwt_refresh_token_hmac_session_key, compute_hmac(data + key))
217   end
218 end
set_jwt_token(token)
[show source]
   # File lib/rodauth/features/jwt.rb
88 def set_jwt_token(token)
89   set_response_header('authorization', token)
90 end
set_last_password_entry()
[show source]
   # File lib/rodauth/features/password_grace_period.rb
53 def set_last_password_entry
54   set_session_value(last_password_entry_session_key, Time.now.to_i)
55 end
set_login_requirement_error_message(reason, message)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
153 def set_login_requirement_error_message(reason, message)
154   set_error_reason(reason)
155   @login_requirement_message = message
156 end
set_new_account_password(password)
[show source]
   # File lib/rodauth/features/create_account.rb
92 def set_new_account_password(password)
93   account[account_password_hash_column] = password_hash(password)
94 end
set_notice_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
395 def set_notice_flash(message)
396   flash[flash_notice_key] = message
397 end
set_notice_now_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
399 def set_notice_now_flash(message)
400   flash.now[flash_notice_key] = message
401 end
set_password(password)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
21 def set_password(password)
22   hash = super
23   add_previous_password_hash(hash)
24   hash
25 end
set_password_requirement_error_message(reason, message)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
132 def set_password_requirement_error_message(reason, message)
133   set_error_reason(reason)
134   @password_requirement_message = message
135 end
set_redirect_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
391 def set_redirect_error_flash(message)
392   flash[flash_error_key] = message
393 end
set_redirect_error_status(status)

Don’t set an error status when redirecting in an error case, as a redirect status is needed.

[show source]
    # File lib/rodauth/features/base.rb
784 def set_redirect_error_status(status)
785 end
set_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
202 def set_reset_password_email_last_sent
203    password_reset_ds.update(reset_password_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if reset_password_email_last_sent_column
204 end
set_response_error_reason_status(reason, status)
[show source]
    # File lib/rodauth/features/base.rb
791 def set_response_error_reason_status(reason, status)
792   set_error_reason(reason)
793   set_response_error_status(status)
794 end
set_response_error_status(status)
[show source]
    # File lib/rodauth/features/base.rb
787 def set_response_error_status(status)
788   response.status = status
789 end
set_response_header(key, value)
[show source]
    # File lib/rodauth/features/base.rb
619 def set_response_header(key, value)
620   response.headers[key] = value
621 end
set_session_return_to_path(session_key, path=request.fullpath)
[show source]
     # File lib/rodauth/features/base.rb
1020 def set_session_return_to_path(session_key, path=request.fullpath)
1021   if request.get? && valid_return_to_path?(path)
1022     set_session_value(session_key, path)
1023   end
1024 end
set_session_value(key, value)
[show source]
     # File lib/rodauth/features/base.rb
1043 def set_session_value(key, value)
1044   session[key] = value
1045 end
set_single_session_key(data)
[show source]
    # File lib/rodauth/features/single_session.rb
103 def set_single_session_key(data)
104   data = compute_hmac(data) if hmac_secret
105   set_session_value(single_session_session_key, data)
106 end
set_title(title)
[show source]
    # File lib/rodauth/features/base.rb
381 def set_title(title)
382   if title_instance_variable
383     scope.instance_variable_set(title_instance_variable, title)
384   end
385 end
set_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
242 def set_unlock_account_email_last_sent
243   account_lockouts_ds.update(account_lockouts_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if account_lockouts_email_last_sent_column
244 end
set_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
228 def set_verify_account_email_last_sent
229   verify_account_ds.update(verify_account_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if verify_account_email_last_sent_column
230 end
setup_account_verification()
[show source]
    # File lib/rodauth/features/verify_account.rb
240 def setup_account_verification
241   generate_verify_account_key_value
242   create_verify_account_key
243   send_verify_account_email
244 end
show_lockout_page()
[show source]
    # File lib/rodauth/features/lockout.rb
297 def show_lockout_page
298   set_response_error_reason_status(:account_locked_out, lockout_error_status)
299   set_error_flash login_lockout_error_flash
300   return_response unlock_account_request_view
301 end
single_session_ds(id=session_value)
[show source]
    # File lib/rodauth/features/single_session.rb
108 def single_session_ds(id=session_value)
109   db[single_session_table].
110     where(single_session_id_column=>id)
111 end
skip_login_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
126 def skip_login_field_on_login?
127   return false unless use_multi_phase_login?
128   valid_login_entered?
129 end
skip_password_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
131 def skip_password_field_on_login?
132   return false unless use_multi_phase_login?
133   !valid_login_entered?
134 end
skip_status_checks?()
[show source]
   # File lib/rodauth/features/close_account.rb
85 def skip_status_checks?
86   false
87 end
sms()
[show source]
    # File lib/rodauth/features/sms_codes.rb
528 def sms
529   case @sms
530   when nil
531     (@sms = sms_ds.first || false) || nil
532   when false
533     nil
534   else
535     @sms
536   end
537 end
sms_auth_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
403 def sms_auth_message(code)
404   "SMS authentication code for #{domain} is #{code}"
405 end
sms_available?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
456 def sms_available?
457   sms_setup? && !sms_locked_out?
458 end
sms_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
435 def sms_code
436   sms[sms_code_column]
437 end
sms_code_issued_at()
[show source]
    # File lib/rodauth/features/sms_codes.rb
439 def sms_code_issued_at
440   convert_timestamp(sms[sms_issued_at_column])
441 end
sms_code_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
352 def sms_code_match?(code)
353   return false unless sms_current_auth?
354   timing_safe_eql?(code, sms_code)
355 end
sms_codes_primary?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
504 def sms_codes_primary?
505   (features & [:otp, :webauthn]).empty?
506 end
sms_confirm()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
148 def sms_confirm
149   super if defined?(super)
150   auto_add_missing_recovery_codes
151 end
sms_confirm_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
366 def sms_confirm_failure
367   sms_ds.delete
368 end
sms_confirm_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
407 def sms_confirm_message(code)
408   "SMS confirmation code for #{domain} is #{code}"
409 end
sms_confirmation_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
357 def sms_confirmation_match?(code)
358   sms_needs_confirmation? && sms_code_match?(code)
359 end
sms_current_auth?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
464 def sms_current_auth?
465   sms_code && sms_code_issued_at + sms_code_allowed_seconds > Time.now
466 end
sms_disable()
[show source]
    # File lib/rodauth/features/sms_codes.rb
361 def sms_disable
362   sms_ds.delete
363   @sms = false
364 end
sms_ds()
[show source]
    # File lib/rodauth/features/sms_codes.rb
539 def sms_ds
540   db[sms_codes_table].where(sms_id_column=>session_value)
541 end
sms_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
443 def sms_failures
444   sms[sms_failures_column]
445 end
sms_locked_out?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
460 def sms_locked_out?
461   sms_failures >= sms_failure_limit
462 end
sms_needs_confirmation?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
452 def sms_needs_confirmation?
453   sms && sms_failures.nil?
454 end
sms_needs_confirmation_notice_flash()
[show source]
    # File lib/rodauth/features/sms_codes.rb
411 def sms_needs_confirmation_notice_flash
412   sms_needs_confirmation_error_flash
413 end
sms_new_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
512 def sms_new_auth_code
513   SecureRandom.random_number(10**sms_auth_code_length).to_s.rjust(sms_auth_code_length, "0")
514 end
sms_new_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
516 def sms_new_confirm_code
517   SecureRandom.random_number(10**sms_confirm_code_length).to_s.rjust(sms_confirm_code_length, "0")
518 end
sms_normalize_phone(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
508 def sms_normalize_phone(phone)
509   phone.to_s.gsub(/\D+/, '')
510 end
sms_phone()
[show source]
    # File lib/rodauth/features/sms_codes.rb
431 def sms_phone
432   sms[sms_phone_column]
433 end
sms_record_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
426 def sms_record_failure
427   update_sms(sms_failures_column=>Sequel.expr(sms_failures_column)+1)
428   sms[sms_failures_column] = sms_ds.get(sms_failures_column)
429 end
sms_remove_expired_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
419 def sms_remove_expired_confirm_code
420   db[sms_codes_table].
421     where(sms_id_column=>session_value, sms_failures_column => nil).
422     where(Sequel[sms_issued_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: sms_confirm_deadline)).
423     delete
424 end
sms_remove_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
377 def sms_remove_failures
378   return if sms_needs_confirmation?
379   update_hash_ds(sms, sms_ds.exclude(sms_failures_column => nil), sms_failures_column => 0, sms_code_column => nil)
380 end
sms_send(phone, message)
[show source]
    # File lib/rodauth/features/sms_codes.rb
520 def sms_send(phone, message)
521   raise ConfigurationError, "sms_send needs to be defined in the Rodauth configuration for SMS sending to work"
522 end
sms_send_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
387 def sms_send_auth_code
388   code = sms_new_auth_code
389   sms_set_code(code)
390   sms_send(sms_phone, sms_auth_message(code))
391 end
sms_send_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
393 def sms_send_confirm_code
394   code = sms_new_confirm_code
395   sms_set_code(code)
396   sms_send(sms_phone, sms_confirm_message(code))
397 end
sms_set_code(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
415 def sms_set_code(code)
416  update_sms(sms_code_column=>code, sms_issued_at_column=>Sequel::CURRENT_TIMESTAMP)
417 end
sms_setup(phone_number)
[show source]
    # File lib/rodauth/features/sms_codes.rb
370 def sms_setup(phone_number)
371   # Cannot handle uniqueness violation here, as the phone number given may not match the
372   # one in the table.
373   sms_ds.insert(sms_id_column=>session_value, sms_phone_column=>phone_number, sms_failures_column => nil)
374   @sms = nil
375 end
sms_setup?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
447 def sms_setup?
448   return false unless sms
449   !sms_needs_confirmation?
450 end
sms_valid_phone?(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
399 def sms_valid_phone?(phone)
400   phone.length >= sms_phone_min_length
401 end
split_token(token)
[show source]
    # File lib/rodauth/features/base.rb
707 def split_token(token)
708   token.split(token_separator, 2)
709 end
template_path(page)
[show source]
    # File lib/rodauth/features/base.rb
925 def template_path(page)
926   File.join(File.dirname(__FILE__), '../../../templates', "#{page}.str")
927 end
throw_basic_auth_error(*args)
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
84 def throw_basic_auth_error(*args)
85   set_http_basic_auth_error_response
86   throw_error(*args) 
87 end
throw_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
800 def throw_error(field, error)
801   set_field_error(field, error)
802   throw_rodauth_error
803 end
throw_error_reason(reason, status, field, message)
[show source]
    # File lib/rodauth/features/base.rb
813 def throw_error_reason(reason, status, field, message)
814   set_error_reason(reason)
815   throw_error_status(status, field, message)
816 end
throw_error_status(status, field, error)
[show source]
    # File lib/rodauth/features/base.rb
805 def throw_error_status(status, field, error)
806   set_response_error_status(status)
807   throw_error(field, error)
808 end
throw_rodauth_error()
[show source]
    # File lib/rodauth/features/base.rb
796 def throw_rodauth_error
797   throw :rodauth_error
798 end
timing_safe_eql?(provided, actual)
[show source]
    # File lib/rodauth/features/base.rb
767 def timing_safe_eql?(provided, actual)
768   provided = provided.to_s
769   Rack::Utils.secure_compare(provided.ljust(actual.length), actual) && provided.length == actual.length
770 end
token_param_value(key)
[show source]
   # File lib/rodauth/features/email_base.rb
64 def token_param_value(key)
65   "#{account_id}#{token_separator}#{convert_email_token_key(key)}"
66 end
transaction(opts=OPTS, &block)
[show source]
    # File lib/rodauth/features/base.rb
749 def transaction(opts=OPTS, &block)
750   opts = opts.empty? ? transaction_opts : transaction_opts.merge(opts)
751   db.transaction(opts, &block)
752 end
translate(_key, default)
[show source]
    # File lib/rodauth/features/base.rb
280 def translate(_key, default)
281   # do not attempt to translate by default
282   default
283 end
two_factor_authenticate(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
243 def two_factor_authenticate(type)
244   two_factor_update_session(type)
245   two_factor_remove_auth_failures
246   after_two_factor_authentication
247   require_response(:_two_factor_auth_response)
248 end
two_factor_authenticated?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
186 def two_factor_authenticated?
187   authenticated_by && authenticated_by.length >= 2
188 end
two_factor_authentication_setup?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
190 def two_factor_authentication_setup?
191   possible_authentication_methods.length >= 2
192 end
two_factor_login_type_match?(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
200 def two_factor_login_type_match?(type)
201   authenticated_by && authenticated_by.include?(type)
202 end
two_factor_modifications_require_password?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
124 def two_factor_modifications_require_password?
125   modifications_require_password?
126 end
two_factor_partially_authenticated?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
182 def two_factor_partially_authenticated?
183   logged_in? && !two_factor_authenticated? && uses_two_factor_authentication?
184 end
two_factor_password_match?(password)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
174 def two_factor_password_match?(password)
175   if two_factor_modifications_require_password?
176     password_match?(password)
177   else
178     true
179   end
180 end
two_factor_remove()
[show source]
    # File lib/rodauth/features/otp.rb
231 def two_factor_remove
232   super
233   otp_remove
234 end
two_factor_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
236 def two_factor_remove_auth_failures
237   super
238   otp_remove_auth_failures
239 end
two_factor_remove_session(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
256 def two_factor_remove_session(type)
257   authenticated_by.delete(type)
258   remove_session_value(two_factor_setup_session_key)
259   if authenticated_by.empty?
260     clear_session
261   end
262 end
two_factor_update_session(auth_type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
264 def two_factor_update_session(auth_type)
265   raise Error, "attempt to have two factor authentication using same factor" if authenticated_by.include?(auth_type)
266   authenticated_by << auth_type
267   set_session_value(two_factor_setup_session_key, true)
268 end
unique_constraint_violation_class()

Work around jdbc/sqlite issue where it only raises ConstraintViolation and not UniqueConstraintViolation.

[show source]
    # File lib/rodauth/features/base.rb
978 def unique_constraint_violation_class
979   if db.adapter_scheme == :jdbc && db.database_type == :sqlite
980     # :nocov:
981     Sequel::ConstraintViolation
982     # :nocov:
983   else
984     Sequel::UniqueConstraintViolation
985   end
986 end
unlock_account()
[show source]
    # File lib/rodauth/features/lockout.rb
165 def unlock_account
166   transaction do
167     remove_lockout_metadata
168   end
169 end
unlock_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/lockout.rb
246 def unlock_account_email_recently_sent?
247   (email_last_sent = get_unlock_account_email_last_sent) && (Time.now - email_last_sent < unlock_account_skip_resend_email_within)
248 end
unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
257 def unlock_account_key
258   @unlock_account_key_value
259 end
unlock_account_key_value()
[show source]
    # File lib/rodauth/features/lockout.rb
261 def unlock_account_key_value
262   # RODAUTH3: call unlock_account_key directly
263   unlock_account_key
264 end
unverified_grace_period_expired?()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
92 def unverified_grace_period_expired?
93   return false unless expires_at = session[unverified_account_session_key]
94   expires_at.is_a?(Integer) && Time.now.to_i > expires_at
95 end
update_account(values, ds=account_ds)
[show source]
     # File lib/rodauth/features/base.rb
1061 def update_account(values, ds=account_ds)
1062   update_hash_ds(account, ds, values)
1063 end
update_activity(account_id, *columns)
[show source]
    # File lib/rodauth/features/account_expiration.rb
113 def update_activity(account_id, *columns)
114   ds = account_activity_ds(account_id)
115   hash = {}
116   columns.each do |c|
117     hash[c] = Sequel::CURRENT_TIMESTAMP
118   end
119   if ds.update(hash) == 0
120     hash[account_activity_id_column] = account_id
121     hash[account_activity_last_activity_column] ||= Sequel::CURRENT_TIMESTAMP
122     hash[account_activity_last_login_column] ||= Sequel::CURRENT_TIMESTAMP
123     # It is safe to ignore uniqueness violations here, as a concurrent insert would also use current timestamps.
124     ignore_uniqueness_violation{ds.insert(hash)}
125   end
126 end
update_current_session?()
[show source]
    # File lib/rodauth/features/active_sessions.rb
232 def update_current_session?
233   !!session_inactivity_deadline
234 end
update_hash_ds(hash, ds, values)
[show source]
     # File lib/rodauth/features/base.rb
1051 def update_hash_ds(hash, ds, values)
1052   num = ds.update(values)
1053   if num == 1
1054     values.each do |k, v|
1055       hash[k] = Sequel::CURRENT_TIMESTAMP == v ? Time.now : v
1056     end
1057   end
1058   num
1059 end
update_last_activity()
[show source]
   # File lib/rodauth/features/account_expiration.rb
43 def update_last_activity
44   if session_value
45     update_activity(session_value, account_activity_last_activity_column)
46   end
47 end
update_last_login()
[show source]
   # File lib/rodauth/features/account_expiration.rb
39 def update_last_login
40   update_activity(account_id, account_activity_last_login_column, account_activity_last_activity_column)
41 end
update_login(login)
[show source]
   # File lib/rodauth/features/change_login.rb
79 def update_login(login)
80   _update_login(login)
81 end
update_password_changed_at()
[show source]
   # File lib/rodauth/features/password_expiration.rb
52 def update_password_changed_at
53   ds = password_expiration_ds
54   if ds.update(password_expiration_changed_at_column=>Sequel::CURRENT_TIMESTAMP) == 0
55     # Ignoring the violation is safe here, since a concurrent insert would also set it to the
56     # current timestamp.
57     ignore_uniqueness_violation{ds.insert(password_expiration_id_column=>account_id)}
58   end
59 end
update_password_hash?()
[show source]
   # File lib/rodauth/features/update_password_hash.rb
24 def update_password_hash?
25   password_hash_cost != @current_password_hash_cost || @update_password_hash
26 end
update_session()
[show source]
   # File lib/rodauth/features/account_expiration.rb
72 def update_session
73   check_account_expiration
74   super
75 end
update_single_session_key()
[show source]
   # File lib/rodauth/features/single_session.rb
70 def update_single_session_key
71   key = random_key
72   set_single_session_key(key)
73   if single_session_ds.update(single_session_key_column=>key) == 0
74     # Don't handle uniqueness violations here.  While we could get the stored key from the
75     # database, it could lead to two sessions sharing the same key, which this feature is
76     # designed to prevent.
77     single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key)
78   end
79 end
update_sms(values)
[show source]
    # File lib/rodauth/features/sms_codes.rb
524 def update_sms(values)
525   update_hash_ds(sms, sms_ds, values)
526 end
use_database_authentication_functions?()
[show source]
    # File lib/rodauth/features/base.rb
826 def use_database_authentication_functions?
827   case db.database_type
828   when :postgres, :mysql, :mssql
829     true
830   else
831     # :nocov:
832     false
833     # :nocov:
834   end
835 end
use_date_arithmetic?()
[show source]
    # File lib/rodauth/features/active_sessions.rb
241 def use_date_arithmetic?
242   true
243 end
use_json?()
[show source]
   # File lib/rodauth/features/json.rb
64 def use_json?
65   json_request? || only_json?
66 end
use_jwt?()
[show source]
   # File lib/rodauth/features/jwt.rb
92 def use_jwt?
93   use_json?
94 end
use_multi_phase_login?()
[show source]
    # File lib/rodauth/features/email_auth.rb
167 def use_multi_phase_login?
168   true
169 end
use_request_specific_csrf_tokens?()
[show source]
    # File lib/rodauth/features/base.rb
837 def use_request_specific_csrf_tokens?
838   scope.opts[:rodauth_route_csrf] && scope.use_request_specific_csrf_tokens?
839 end
use_scope_clear_session?()
[show source]
     # File lib/rodauth/features/base.rb
1034 def use_scope_clear_session?
1035   scope.respond_to?(:clear_session)
1036 end
uses_instance_variables(*ivs)
[show source]
    # File lib/rodauth/features/base.rb
159 def uses_instance_variables(*ivs)
160   auth.define_singleton_method(:instance_variables_used) do
161     super() + ivs
162   end
163 end
uses_two_factor_authentication?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
194 def uses_two_factor_authentication?
195   return false unless logged_in?
196   set_session_value(two_factor_setup_session_key, two_factor_authentication_setup?) unless session.has_key?(two_factor_setup_session_key)
197   session[two_factor_setup_session_key]
198 end
valid_jwt?()
[show source]
    # File lib/rodauth/features/jwt.rb
100 def valid_jwt?
101   !!(jwt_token && jwt_payload)
102 end
valid_login_entered?()
[show source]
    # File lib/rodauth/features/login.rb
136 def valid_login_entered?
137   @valid_login_entered
138 end
valid_new_webauthn_credential?(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
314 def valid_new_webauthn_credential?(webauthn_credential)
315   _override_webauthn_credential_response_verify(webauthn_credential)
316   (challenge = param_or_nil(webauthn_setup_challenge_param)) &&
317     (hmac = param_or_nil(webauthn_setup_challenge_hmac_param)) &&
318     (timing_safe_eql?(compute_hmac(challenge), hmac) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(challenge), hmac))) &&
319     webauthn_credential.verify(challenge)
320 end
valid_return_to_path?(path)
[show source]
     # File lib/rodauth/features/base.rb
1014 def valid_return_to_path?(path)
1015   path[0] == "/" &&
1016     path[1] != "/" &&
1017     path.bytesize <= return_to_path_max_size
1018 end
valid_webauthn_credential_auth?(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
362 def valid_webauthn_credential_auth?(webauthn_credential)
363   ds = webauthn_keys_ds.where(webauthn_keys_webauthn_id_column => webauthn_credential.id)
364   pub_key, sign_count = ds.get([webauthn_keys_public_key_column, webauthn_keys_sign_count_column])
365 
366   _override_webauthn_credential_response_verify(webauthn_credential)
367   (challenge = param_or_nil(webauthn_auth_challenge_param)) &&
368     (hmac = param_or_nil(webauthn_auth_challenge_hmac_param)) &&
369     (timing_safe_eql?(compute_hmac(challenge), hmac) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(challenge), hmac))) &&
370     webauthn_credential.verify(challenge, public_key: pub_key, sign_count: sign_count) &&
371     ds.update(
372       webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count),
373       webauthn_keys_last_use_column => Sequel::CURRENT_TIMESTAMP
374     ) == 1
375 end
verified_account?()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
17 def verified_account?
18   logged_in? && !session[unverified_account_session_key]
19 end
verify_account()
[show source]
    # File lib/rodauth/features/verify_account.rb
173 def verify_account
174   ds = account_ds.where(account_status_column=>account_unverified_status_value)
175   update_account({account_status_column=>account_open_status_value}, ds) == 1
176 end
verify_account_check_already_logged_in()
[show source]
    # File lib/rodauth/features/verify_account.rb
290 def verify_account_check_already_logged_in
291   check_already_logged_in
292 end
verify_account_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_account.rb
315 def verify_account_ds(id=account_id)
316   db[verify_account_table].where(verify_account_id_column=>id)
317 end
verify_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/verify_account.rb
246 def verify_account_email_recently_sent?
247   account && (email_last_sent = get_verify_account_email_last_sent) && (Time.now - email_last_sent < verify_account_skip_resend_email_within)
248 end
verify_account_email_resend()
[show source]
    # File lib/rodauth/features/verify_account.rb
178 def verify_account_email_resend
179   if @verify_account_key_value = get_verify_account_key(account_id)
180     set_verify_account_email_last_sent
181     send_verify_account_email
182     true
183   end
184 end
verify_account_key_insert_hash()
[show source]
    # File lib/rodauth/features/verify_account.rb
311 def verify_account_key_insert_hash
312   {verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
313 end
verify_account_set_password?()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
29 def verify_account_set_password?
30   false
31 end
verify_account_view()
[show source]
   # File lib/rodauth/features/webauthn_verify_account.rb
 9 def verify_account_view
10   webauthn_setup_view
11 end
verify_login_change()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
116 def verify_login_change
117   unless res = _update_login(verify_login_change_new_login)
118     remove_verify_login_change_key
119   end
120 
121   res
122 end
verify_login_change_account_status_value()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
223 def verify_login_change_account_status_value
224   account_open_status_value
225 end
verify_login_change_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
212 def verify_login_change_ds(id=account_id)
213   db[verify_login_change_table].where(verify_login_change_id_column=>id)
214 end
verify_login_change_email_body()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
208 def verify_login_change_email_body
209   render('verify-login-change-email')
210 end
verify_login_change_key_insert_hash(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
198 def verify_login_change_key_insert_hash(login)
199   hash = {verify_login_change_id_column=>account_id, verify_login_change_key_column=>verify_login_change_key_value, verify_login_change_login_column=>login}
200   set_deadline_value(hash, verify_login_change_deadline_column, verify_login_change_deadline_interval)
201   hash
202 end
verify_login_change_old_login()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
146 def verify_login_change_old_login
147   account_ds.get(login_column)
148 end
view(page, title)
[show source]
    # File lib/rodauth/features/base.rb
465 def view(page, title)
466   set_title(title)
467   _view(:view, page)
468 end
webauthn_account_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
508 def webauthn_account_id
509   account_id_or_session_value
510 end
webauthn_allow()
[show source]
    # File lib/rodauth/features/webauthn.rb
340 def webauthn_allow
341   account_webauthn_ids
342 end
webauthn_auth_additional_form_tags()
[show source]
   # File lib/rodauth/features/webauthn_login.rb
45 def webauthn_auth_additional_form_tags
46   if @webauthn_login
47     super.to_s + login_hidden_field
48   else
49     super
50   end
51 end
webauthn_auth_credential_from_form_submission()
[show source]
    # File lib/rodauth/features/webauthn.rb
520 def webauthn_auth_credential_from_form_submission
521   begin
522     webauthn_credential = webauthn_form_submission_call(:from_get, webauthn_auth_data)
523 
524     unless valid_webauthn_credential_auth?(webauthn_credential)
525       throw_error_reason(:invalid_webauthn_auth_param, invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
526     end
527   rescue WebAuthn::SignCountVerificationError
528     handle_webauthn_sign_count_verification_error
529   rescue WebAuthn::Error, RuntimeError, NoMethodError
530     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
531   end
532 
533   webauthn_credential
534 end
webauthn_auth_data()
[show source]
    # File lib/rodauth/features/webauthn.rb
536 def webauthn_auth_data
537   case auth_data = raw_param(webauthn_auth_param)
538   when String
539     begin
540       JSON.parse(auth_data)
541     rescue
542       throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
543     end
544   when Hash
545     auth_data
546   else
547     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
548   end
549 end
webauthn_auth_form_path()
[show source]
    # File lib/rodauth/features/webauthn.rb
247 def webauthn_auth_form_path
248   webauthn_auth_path
249 end
webauthn_authenticator_selection()
[show source]
    # File lib/rodauth/features/webauthn.rb
263 def webauthn_authenticator_selection
264   {'requireResidentKey' => false, 'userVerification' => webauthn_user_verification}
265 end
webauthn_create_relying_party_opts()
[show source]
    # File lib/rodauth/features/webauthn.rb
434 def webauthn_create_relying_party_opts
435   { :relying_party => webauthn_relying_party }
436 end
webauthn_credential_options_for_get()
[show source]
    # File lib/rodauth/features/webauthn.rb
322 def webauthn_credential_options_for_get
323   WebAuthn::Credential.options_for_get(
324     :allow => webauthn_allow,
325     :timeout => webauthn_auth_timeout,
326     :user_verification => webauthn_user_verification,
327     :extensions => webauthn_extensions,
328     **webauthn_get_relying_party_opts
329   )
330 end
webauthn_extensions()
[show source]
    # File lib/rodauth/features/webauthn.rb
267 def webauthn_extensions
268   {}
269 end
webauthn_form_submission_call(meth, arg)
[show source]
    # File lib/rodauth/features/webauthn.rb
439 def webauthn_form_submission_call(meth, arg)
440   WebAuthn::Credential.public_send(meth, arg, :relying_party => webauthn_relying_party)
441 end
webauthn_key_insert_hash(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
499 def webauthn_key_insert_hash(webauthn_credential)
500   {
501     webauthn_keys_account_id_column => webauthn_account_id,
502     webauthn_keys_webauthn_id_column => webauthn_credential.id,
503     webauthn_keys_public_key_column => webauthn_credential.public_key,
504     webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count)
505   }
506 end
webauthn_keys_ds()
[show source]
    # File lib/rodauth/features/webauthn.rb
516 def webauthn_keys_ds
517   db[webauthn_keys_table].where(webauthn_keys_account_id_column => webauthn_account_id)
518 end
webauthn_login_options?()
[show source]
   # File lib/rodauth/features/webauthn_autofill.rb
60 def webauthn_login_options?
61   return true unless param_or_nil(login_param)
62   super
63 end
webauthn_login_verification_factor?(webauthn_credential)
[show source]
   # File lib/rodauth/features/webauthn_login.rb
72 def webauthn_login_verification_factor?(webauthn_credential)
73   webauthn_login_user_verification_additional_factor? &&
74     webauthn_credential.response.authenticator_data.user_verified? &&
75     uses_two_factor_authentication?
76 end
webauthn_modification_authenticated?()
[show source]
    # File lib/rodauth/features/webauthn.rb
472 def webauthn_modification_authenticated?
473   two_factor_login_type_match?('webauthn') &&
474     (!uses_two_factor_authentication? || two_factor_modifications_require_password?)
475 end
webauthn_origin()
[show source]
    # File lib/rodauth/features/webauthn.rb
336 def webauthn_origin
337   base_url
338 end
webauthn_relying_party()
[show source]
    # File lib/rodauth/features/webauthn.rb
414 def webauthn_relying_party
415   # No need to memoize, only called once per request
416   WebAuthn::RelyingParty.new(
417     allowed_origins: [webauthn_origin],
418     id: webauthn_rp_id,
419     name: webauthn_rp_name,
420   )
421 end
webauthn_remove_authenticated_session()
[show source]
    # File lib/rodauth/features/webauthn.rb
255 def webauthn_remove_authenticated_session
256   remove_session_value(authenticated_webauthn_id_session_key)
257 end
webauthn_rp_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
344 def webauthn_rp_id
345   webauthn_origin.sub(/\Ahttps?:\/\//, '').sub(/:\d+\z/, '')
346 end
webauthn_rp_name()
[show source]
    # File lib/rodauth/features/webauthn.rb
348 def webauthn_rp_name
349   webauthn_rp_id
350 end
webauthn_setup?()
[show source]
    # File lib/rodauth/features/webauthn.rb
386 def webauthn_setup?
387   !webauthn_keys_ds.empty?
388 end
webauthn_setup_credential_from_form_submission()
[show source]
    # File lib/rodauth/features/webauthn.rb
551 def webauthn_setup_credential_from_form_submission
552   unless two_factor_password_match?(param(password_param))
553     throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
554   end
555 
556   begin
557     webauthn_credential = webauthn_form_submission_call(:from_create, webauthn_setup_data)
558 
559     unless valid_new_webauthn_credential?(webauthn_credential)
560       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
561     end
562   rescue WebAuthn::Error, RuntimeError, NoMethodError
563     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
564   end
565 
566   webauthn_credential
567 end
webauthn_setup_data()
[show source]
    # File lib/rodauth/features/webauthn.rb
569 def webauthn_setup_data
570   case setup_data = raw_param(webauthn_setup_param)
571   when String
572     begin
573       JSON.parse(setup_data)
574     rescue
575       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
576     end
577   when Hash
578     setup_data
579   else
580     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
581   end
582 end
webauthn_update_session(webauthn_id)
[show source]
    # File lib/rodauth/features/webauthn.rb
259 def webauthn_update_session(webauthn_id)
260   set_session_value(authenticated_webauthn_id_session_key, webauthn_id)
261 end
webauthn_user_ids_ds()
[show source]
    # File lib/rodauth/features/webauthn.rb
512 def webauthn_user_ids_ds
513   db[webauthn_user_ids_table].where(webauthn_user_ids_account_id_column => webauthn_account_id)
514 end
webauthn_user_name()
[show source]
    # File lib/rodauth/features/webauthn.rb
332 def webauthn_user_name
333   account![login_column]
334 end
webauthn_user_verification()
[show source]
   # File lib/rodauth/features/webauthn_autofill.rb
25 def webauthn_user_verification
26   'preferred'
27 end