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/confirm_password.rb
  12. lib/rodauth/features/create_account.rb
  13. lib/rodauth/features/disallow_common_passwords.rb
  14. lib/rodauth/features/disallow_password_reuse.rb
  15. lib/rodauth/features/email_auth.rb
  16. lib/rodauth/features/email_base.rb
  17. lib/rodauth/features/http_basic_auth.rb
  18. lib/rodauth/features/internal_request.rb
  19. lib/rodauth/features/json.rb
  20. lib/rodauth/features/jwt.rb
  21. lib/rodauth/features/jwt_cors.rb
  22. lib/rodauth/features/jwt_refresh.rb
  23. lib/rodauth/features/lockout.rb
  24. lib/rodauth/features/login.rb
  25. lib/rodauth/features/login_password_requirements_base.rb
  26. lib/rodauth/features/logout.rb
  27. lib/rodauth/features/otp.rb
  28. lib/rodauth/features/password_complexity.rb
  29. lib/rodauth/features/password_expiration.rb
  30. lib/rodauth/features/password_grace_period.rb
  31. lib/rodauth/features/password_pepper.rb
  32. lib/rodauth/features/path_class_methods.rb
  33. lib/rodauth/features/recovery_codes.rb
  34. lib/rodauth/features/remember.rb
  35. lib/rodauth/features/reset_password.rb
  36. lib/rodauth/features/session_expiration.rb
  37. lib/rodauth/features/single_session.rb
  38. lib/rodauth/features/sms_codes.rb
  39. lib/rodauth/features/two_factor_base.rb
  40. lib/rodauth/features/update_password_hash.rb
  41. lib/rodauth/features/verify_account.rb
  42. lib/rodauth/features/verify_account_grace_period.rb
  43. lib/rodauth/features/verify_login_change.rb
  44. lib/rodauth/features/webauthn.rb
  45. lib/rodauth/features/webauthn_login.rb
  46. lib/rodauth/features/webauthn_verify_account.rb
  47. lib/rodauth/migrations.rb
  48. lib/rodauth/version.rb
  49. show all

: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_login
  3. _account_from_refresh_token
  4. _account_from_reset_password_key
  5. _account_from_session
  6. _account_from_unlock_key
  7. _account_from_verify_account_key
  8. _account_from_verify_login_change_key
  9. _account_refresh_token_split
  10. _around_rodauth
  11. _email_auth_request
  12. _email_auth_request_and_redirect
  13. _field_attributes
  14. _field_error_attributes
  15. _formatted_field_error
  16. _get_remember_cookie
  17. _json_response_body
  18. _jwt_decode_opts
  19. _login
  20. _login_form_footer
  21. _login_form_footer_links
  22. _multi_phase_login_forms
  23. _new_account
  24. _otp
  25. _otp_add_key
  26. _otp_key
  27. _otp_tmp_key
  28. _recovery_codes
  29. _return_json_response
  30. _setup_account_lockouts_hash
  31. _sms
  32. _two_factor_auth_links
  33. _two_factor_remove_all_from_session
  34. _two_factor_remove_links
  35. _two_factor_setup_links
  36. _update_login
  37. _view
  38. _view_opts
  39. account_activity_ds
  40. account_ds
  41. account_expired?
  42. account_expired_at
  43. account_from_email_auth_key
  44. account_from_key
  45. account_from_login
  46. account_from_refresh_token
  47. account_from_reset_password_key
  48. account_from_session
  49. account_from_unlock_key
  50. account_from_verify_account_key
  51. account_from_verify_login_change_key
  52. account_id
  53. account_in_unverified_grace_period?
  54. account_initial_status_value
  55. account_lockouts_ds
  56. account_login_failures_ds
  57. account_password_hash_column
  58. account_session_status_filter
  59. account_webauthn_ids
  60. account_webauthn_usage
  61. account_webauthn_user_id
  62. active_remember_key_ds
  63. active_sessions_ds
  64. active_sessions_insert_hash
  65. active_sessions_update_hash
  66. add_active_session
  67. add_audit_log
  68. add_field_error_class
  69. add_previous_password_hash
  70. add_recovery_code
  71. add_recovery_codes
  72. add_remember_key
  73. add_webauthn_credential
  74. after_change_password
  75. after_close_account
  76. after_create_account
  77. after_login
  78. after_login_entered_during_multi_phase_login
  79. after_login_failure
  80. after_logout
  81. after_otp_disable
  82. after_refresh_token
  83. after_reset_password
  84. after_sms_disable
  85. after_webauthn_remove
  86. allow_email_auth?
  87. allow_resending_verify_account_email?
  88. already_logged_in
  89. argon2_hash_algorithm?
  90. argon2_hash_cost
  91. argon2_password_hash_match?
  92. audit_log_ds
  93. audit_log_insert_hash
  94. audit_log_message
  95. audit_log_message_default
  96. audit_log_metadata
  97. auth_class_eval
  98. authenticated?
  99. authenticated_by
  100. authenticated_webauthn_id
  101. auto_add_missing_recovery_codes
  102. auto_remove_recovery_codes
  103. autocomplete_for_field?
  104. autologin_session
  105. autologin_type
  106. base32_encode
  107. base_url
  108. before_change_login_route
  109. before_change_password_route
  110. before_create_account_route
  111. before_login_attempt
  112. before_logout
  113. before_otp_setup_route
  114. before_reset_password
  115. before_reset_password_request
  116. before_rodauth
  117. before_unlock_account
  118. before_unlock_account_request
  119. before_verify_account
  120. before_verify_account_route
  121. before_view_recovery_codes
  122. before_webauthn_auth_route
  123. before_webauthn_login_route
  124. before_webauthn_remove_route
  125. before_webauthn_setup_route
  126. button
  127. button_opts
  128. can_add_recovery_codes?
  129. catch_error
  130. change_login
  131. change_login_notice_flash
  132. change_login_requires_password?
  133. change_password_requires_password?
  134. check_account_expiration
  135. check_active_session
  136. check_already_logged_in
  137. check_csrf
  138. check_csrf?
  139. check_password_change_allowed
  140. check_session_expiration
  141. check_single_session
  142. clear_cached_otp
  143. clear_invalid_login_attempts
  144. clear_session
  145. close_account
  146. close_account_requires_password?
  147. compute_hmac
  148. compute_raw_hmac
  149. confirm_password
  150. confirm_password_redirect
  151. convert_email_token_key
  152. convert_session_key
  153. convert_timestamp
  154. convert_token_key
  155. create_account_autologin?
  156. create_account_notice_flash
  157. create_account_set_password?
  158. create_email
  159. create_email_auth_email
  160. create_email_auth_key
  161. create_email_to
  162. create_password_changed_email
  163. create_reset_password_email
  164. create_reset_password_key
  165. create_unlock_account_email
  166. create_verify_account_email
  167. create_verify_account_key
  168. create_verify_login_change_email
  169. create_verify_login_change_key
  170. csrf_tag
  171. currently_active_session?
  172. database_function_password_match?
  173. db
  174. delete_account
  175. delete_account_on_close?
  176. disable_remember_login
  177. domain
  178. email_auth_ds
  179. email_auth_email_body
  180. email_auth_email_link
  181. email_auth_email_recently_sent?
  182. email_auth_key_insert_hash
  183. email_auth_request_form
  184. email_from
  185. email_to
  186. expire_session
  187. extract_password_hash_cost
  188. features
  189. field_attributes
  190. field_error
  191. field_error_attributes
  192. flash
  193. forget_login
  194. formatted_field_error
  195. function_name
  196. generate_active_sessions_key
  197. generate_email_auth_key_value
  198. generate_refresh_token
  199. generate_remember_key_value
  200. generate_reset_password_key_value
  201. generate_unlock_account_key
  202. generate_verify_account_key_value
  203. generate_verify_login_change_key_value
  204. get_active_refresh_token
  205. get_activity_timestamp
  206. get_email_auth_email_last_sent
  207. get_email_auth_key
  208. get_password_changed_at
  209. get_password_hash
  210. get_password_reset_key
  211. get_remember_key
  212. get_reset_password_email_last_sent
  213. get_unlock_account_email_last_sent
  214. get_unlock_account_key
  215. get_verify_account_email_last_sent
  216. get_verify_account_key
  217. get_verify_login_change_login_and_key
  218. handle_duplicate_active_session_id
  219. handle_webauthn_sign_count_verification_error
  220. has_password?
  221. hook_action
  222. http_basic_auth
  223. inactive_session_cond
  224. include_success_messages?
  225. input_field_string
  226. inputmode_for_field?
  227. internal_request?
  228. internal_request_configuration
  229. invalid_login_attempted
  230. invalid_previous_password_message
  231. json_request?
  232. json_response
  233. jwt_cors_allow?
  234. jwt_payload
  235. jwt_refresh_token_account_ds
  236. jwt_refresh_token_account_token_ds
  237. jwt_refresh_token_ds
  238. jwt_refresh_token_insert_hash
  239. jwt_refresh_token_match?
  240. jwt_secret
  241. jwt_session_hash
  242. jwt_token
  243. last_account_activity_at
  244. last_account_login_at
  245. load_memory
  246. loaded_templates
  247. locked_out?
  248. logged_in_via_remember_key?
  249. login
  250. login_confirm_label
  251. login_does_not_meet_requirements_message
  252. login_failed_reset_password_request_form
  253. login_hidden_field
  254. login_input_type
  255. login_meets_email_requirements?
  256. login_meets_length_requirements?
  257. login_meets_requirements?
  258. login_required
  259. login_return_to_requested_location_path
  260. login_session
  261. login_too_long_message
  262. login_too_short_message
  263. login_uses_email?
  264. login_valid_email?
  265. logout
  266. logout_additional_form_tags
  267. modifications_require_password?
  268. new_account
  269. new_recovery_code
  270. new_webauthn_credential
  271. no_longer_active_session
  272. only_json?
  273. open_account?
  274. otp_add_key
  275. otp_exists?
  276. otp_hmac_secret
  277. otp_issuer
  278. otp_key_ds
  279. otp_keys_use_hmac?
  280. otp_last_use
  281. otp_locked_out?
  282. otp_new_secret
  283. otp_provisioning_name
  284. otp_provisioning_uri
  285. otp_qr_code
  286. otp_record_authentication_failure
  287. otp_remove
  288. otp_remove_auth_failures
  289. otp_tmp_key
  290. otp_update_last_use
  291. otp_user_key
  292. otp_valid_code?
  293. otp_valid_key?
  294. param
  295. param_or_nil
  296. password_changed_email_body
  297. password_confirm_label
  298. password_does_not_contain_null_byte?
  299. password_does_not_meet_requirements_message
  300. password_doesnt_match_previous_password?
  301. password_expiration_ds
  302. password_expired?
  303. password_field_autocomplete_value
  304. password_has_enough_character_groups?
  305. password_has_no_invalid_pattern?
  306. password_hash
  307. password_hash_cost
  308. password_hash_ds
  309. password_hash_match?
  310. password_hash_using_salt
  311. password_match?
  312. password_meets_length_requirements?
  313. password_meets_requirements?
  314. password_not_in_dictionary?
  315. password_not_one_of_the_most_common?
  316. password_not_too_many_repeating_characters?
  317. password_one_of_most_common?
  318. password_recently_entered?
  319. password_reset_ds
  320. password_too_short_message
  321. possible_authentication_methods
  322. post_configure
  323. previous_password_ds
  324. raises_uniqueness_violation?
  325. random_key
  326. raw_param
  327. recovery_code_match?
  328. recovery_codes_ds
  329. recovery_codes_primary?
  330. recovery_codes_remove
  331. redirect
  332. redirect_two_factor_authenticated
  333. remember_key_ds
  334. remember_login
  335. remembered_session_id
  336. remove_all_active_sessions
  337. remove_all_webauthn_keys_and_user_ids
  338. remove_current_session
  339. remove_email_auth_key
  340. remove_inactive_sessions
  341. remove_jwt_refresh_token_key
  342. remove_lockout_metadata
  343. remove_remember_key
  344. remove_reset_password_key
  345. remove_session_value
  346. remove_verify_account_key
  347. remove_verify_login_change_key
  348. remove_webauthn_key
  349. render
  350. render_multi_phase_login_forms
  351. request
  352. require_account
  353. require_account_session
  354. require_authentication
  355. require_current_password
  356. require_http_basic_auth
  357. require_login
  358. require_login_confirmation?
  359. require_otp_setup
  360. require_password_authentication
  361. require_password_authentication?
  362. require_sms_available
  363. require_sms_not_setup
  364. require_sms_setup
  365. require_two_factor_authenticated
  366. require_two_factor_not_authenticated
  367. require_two_factor_setup
  368. require_webauthn_setup
  369. rescue_jwt_payload
  370. reset_password_email_body
  371. reset_password_email_link
  372. reset_password_email_recently_sent?
  373. reset_password_key_insert_hash
  374. reset_single_session_key
  375. response
  376. retry_on_uniqueness_violation
  377. return_json_response
  378. route!
  379. route_path
  380. route_url
  381. save_account
  382. send_email
  383. send_email_auth_email
  384. send_password_changed_email
  385. send_reset_password_email
  386. send_unlock_account_email
  387. send_verify_account_email
  388. send_verify_login_change_email
  389. serialize_audit_log_metadata
  390. session
  391. session_inactivity_deadline_condition
  392. session_jwt
  393. session_lifetime_deadline_condition
  394. session_value
  395. set_deadline_value
  396. set_deadline_values?
  397. set_email_auth_email_last_sent
  398. set_error_flash
  399. set_error_reason
  400. set_expired
  401. set_field_error
  402. set_http_basic_auth_error_response
  403. set_jwt
  404. set_jwt_refresh_token_hmac_session_key
  405. set_jwt_token
  406. set_last_password_entry
  407. set_login_requirement_error_message
  408. set_new_account_password
  409. set_notice_flash
  410. set_notice_now_flash
  411. set_password
  412. set_password_requirement_error_message
  413. set_redirect_error_flash
  414. set_redirect_error_status
  415. set_reset_password_email_last_sent
  416. set_response_error_reason_status
  417. set_response_error_status
  418. set_session_value
  419. set_single_session_key
  420. set_title
  421. set_unlock_account_email_last_sent
  422. set_verify_account_email_last_sent
  423. setup_account_verification
  424. show_lockout_page
  425. single_session_ds
  426. skip_login_field_on_login?
  427. skip_password_field_on_login?
  428. skip_status_checks?
  429. sms_auth_message
  430. sms_available?
  431. sms_code
  432. sms_code_issued_at
  433. sms_code_match?
  434. sms_codes_primary?
  435. sms_confirm
  436. sms_confirm_failure
  437. sms_confirm_message
  438. sms_confirmation_match?
  439. sms_current_auth?
  440. sms_disable
  441. sms_ds
  442. sms_failures
  443. sms_locked_out?
  444. sms_needs_confirmation?
  445. sms_new_auth_code
  446. sms_new_confirm_code
  447. sms_normalize_phone
  448. sms_phone
  449. sms_record_failure
  450. sms_remove_failures
  451. sms_send
  452. sms_send_auth_code
  453. sms_send_confirm_code
  454. sms_set_code
  455. sms_setup
  456. sms_setup?
  457. sms_valid_phone?
  458. split_token
  459. template_path
  460. throw_basic_auth_error
  461. throw_error
  462. throw_error_reason
  463. throw_error_status
  464. timing_safe_eql?
  465. token_link
  466. token_param_value
  467. transaction
  468. translate
  469. two_factor_authenticate
  470. two_factor_authenticated?
  471. two_factor_authentication_setup?
  472. two_factor_login_type_match?
  473. two_factor_modifications_require_password?
  474. two_factor_password_match?
  475. two_factor_remove
  476. two_factor_remove_auth_failures
  477. two_factor_remove_session
  478. two_factor_update_session
  479. unique_constraint_violation_class
  480. unlock_account
  481. unlock_account_email_body
  482. unlock_account_email_link
  483. unlock_account_email_recently_sent?
  484. update_account
  485. update_activity
  486. update_current_session?
  487. update_hash_ds
  488. update_last_activity
  489. update_last_login
  490. update_login
  491. update_password_changed_at
  492. update_password_hash?
  493. update_session
  494. update_single_session_key
  495. update_sms
  496. use_database_authentication_functions?
  497. use_date_arithmetic?
  498. use_json?
  499. use_jwt?
  500. use_multi_phase_login?
  501. use_request_specific_csrf_tokens?
  502. uses_two_factor_authentication?
  503. valid_jwt?
  504. valid_login_entered?
  505. valid_new_webauthn_credential?
  506. valid_webauthn_credential_auth?
  507. verified_account?
  508. verify_account
  509. verify_account_check_already_logged_in
  510. verify_account_ds
  511. verify_account_email_body
  512. verify_account_email_link
  513. verify_account_email_recently_sent?
  514. verify_account_email_resend
  515. verify_account_key_insert_hash
  516. verify_account_set_password?
  517. verify_account_view
  518. verify_login_change
  519. verify_login_change_ds
  520. verify_login_change_email_body
  521. verify_login_change_email_link
  522. verify_login_change_key_insert_hash
  523. verify_login_change_old_login
  524. view
  525. webauth_credential_options_for_get
  526. webauthn_account_id
  527. webauthn_auth_additional_form_tags
  528. webauthn_auth_credential_from_form_submission
  529. webauthn_auth_form_path
  530. webauthn_authenticator_selection
  531. webauthn_extensions
  532. webauthn_keys_ds
  533. webauthn_origin
  534. webauthn_remove_authenticated_session
  535. webauthn_rp_id
  536. webauthn_rp_name
  537. webauthn_setup?
  538. webauthn_setup_credential_from_form_submission
  539. webauthn_update_session
  540. webauthn_user_ids_ds
  541. webauthn_user_name

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 = 16  

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

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.

Public Class methods

configure(app, opts={}, &block)
[show source]
   # File lib/rodauth.rb
44 def self.configure(app, opts={}, &block)
45   json_opt = app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
46   csrf = app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_csrf])
47   app.opts[:rodauth_route_csrf] = case csrf
48   when false, :rack_csrf
49     false
50   else
51     json_opt != :only
52   end
53   auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= opts[:auth_class] || Class.new(Auth){@configuration_name = opts[:name]}
54   if !auth_class.roda_class
55     auth_class.roda_class = app
56   elsif auth_class.roda_class != app
57     auth_class = app.opts[:rodauths][opts[:name]] = Class.new(auth_class){@configuration_name = opts[:name]}
58     auth_class.roda_class = app
59   end
60   auth_class.configure(&block) if block
61 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={}, &block)
[show source]
   # File lib/rodauth.rb
 6 def self.lib(opts={}, &block) 
 7   require 'roda'
 8   c = Class.new(Roda)
 9   c.plugin(:rodauth, opts) do
10     enable :internal_request
11     instance_exec(&block)
12   end
13   c.freeze
14   c.rodauth
15 end
load_dependencies(app, opts={})
[show source]
   # File lib/rodauth.rb
17 def self.load_dependencies(app, opts={})
18   json_opt = opts.fetch(:json, app.opts[:rodauth_json])
19   if json_opt
20     app.plugin :json
21     app.plugin :json_parser
22   end
23 
24   unless json_opt == :only
25     require 'tilt/string'
26     app.plugin :render
27 
28     case opts.fetch(:csrf, app.opts[:rodauth_csrf])
29     when false
30       # nothing
31     when :rack_csrf
32       # :nocov:
33       app.plugin :csrf
34       # :nocov:
35     else
36       app.plugin :route_csrf
37     end
38 
39     app.plugin :flash unless opts[:flash] == false
40     app.plugin :h
41   end
42 end
new(scope)
[show source]
    # File lib/rodauth/features/base.rb
131 def initialize(scope)
132   @scope = scope
133 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
258 def _account_from_email_auth_key(token)
259   account_from_key(token, account_open_status_value){|id| get_email_auth_key(id)}
260 end
_account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
635 def _account_from_login(login)
636   ds = db[accounts_table].where(login_column=>login)
637   ds = ds.select(*account_select) if account_select
638   ds = ds.where(account_status_column=>[account_unverified_status_value, account_open_status_value]) unless skip_status_checks?
639   ds.first
640 end
_account_from_refresh_token(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
111 def _account_from_refresh_token(token)
112   id, token_id, key = _account_refresh_token_split(token)
113 
114   unless key &&
115          (id == session_value.to_s) &&
116          (actual = get_active_refresh_token(id, token_id)) &&
117          timing_safe_eql?(key, convert_token_key(actual)) &&
118          jwt_refresh_token_match?(key)
119     return
120   end
121 
122   ds = account_ds(id)
123   ds = ds.where(account_status_column=>account_open_status_value) unless skip_status_checks?
124   ds.first
125 end
_account_from_reset_password_key(token)
[show source]
    # File lib/rodauth/features/reset_password.rb
270 def _account_from_reset_password_key(token)
271   account_from_key(token, account_open_status_value){|id| get_password_reset_key(id)}
272 end
_account_from_session()
[show source]
    # File lib/rodauth/features/base.rb
642 def _account_from_session
643   ds = account_ds(session_value)
644   ds = ds.where(account_session_status_filter) unless skip_status_checks?
645   ds.first
646 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| 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
328 def _account_from_verify_account_key(token)
329   account_from_key(token, account_unverified_status_value){|id| get_verify_account_key(id)}
330 end
_account_from_verify_login_change_key(token)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
212 def _account_from_verify_login_change_key(token)
213   account_from_key(token) do |id|
214     @verify_login_change_new_login, key = get_verify_login_change_login_and_key(id)
215     key
216   end
217 end
_account_refresh_token_split(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
127 def _account_refresh_token_split(token)
128   id, token = split_token(token)
129   return unless id && token
130 
131   token_id, key = split_token(token)
132   return unless token_id && key
133 
134   [id, token_id, key]
135 end
_around_rodauth()
[show source]
    # File lib/rodauth/features/base.rb
471 def _around_rodauth
472   yield
473 end
_email_auth_request()
[show source]
    # File lib/rodauth/features/email_auth.rb
192 def _email_auth_request
193   if email_auth_email_recently_sent?
194     set_redirect_error_flash email_auth_email_recently_sent_error_flash
195     redirect email_auth_email_recently_sent_redirect
196   end
197 
198   generate_email_auth_key_value
199   transaction do
200     before_email_auth_request
201     create_email_auth_key
202     send_email_auth_email
203     after_email_auth_request
204   end
205 
206   set_notice_flash email_auth_email_sent_notice_flash
207 end
_email_auth_request_and_redirect()
[show source]
    # File lib/rodauth/features/email_auth.rb
187 def _email_auth_request_and_redirect
188   _email_auth_request
189   redirect email_auth_email_sent_redirect
190 end
_field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
652 def _field_attributes(field)
653   nil
654 end
_field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
656 def _field_error_attributes(field)
657   " aria-invalid=\"true\" aria-describedby=\"#{field}_error_message\" "
658 end
_formatted_field_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
660 def _formatted_field_error(field, error)
661   "<span class=\"#{input_field_error_message_class}\" id=\"#{field}_error_message\">#{error}</span>"
662 end
_json_response_body(hash)
[show source]
    # File lib/rodauth/features/json.rb
167 def _json_response_body(hash)
168   request.send(:convert_to_json, hash)
169 end
_jwt_decode_opts()
[show source]
    # File lib/rodauth/features/jwt.rb
110 def _jwt_decode_opts
111   jwt_decode_opts
112 end
_login(auth_type)
[show source]
    # File lib/rodauth/features/login.rb
149 def _login(auth_type)
150   warn("Deprecated #_login method called, use #login instead.")
151   login(auth_type)
152 end
_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/email_auth.rb
177 def _multi_phase_login_forms
178   forms = super
179   forms << [30, email_auth_request_form, :_email_auth_request_and_redirect] if valid_login_entered? && allow_email_auth?
180   forms
181 end
_new_account(login)
[show source]
    # File lib/rodauth/features/create_account.rb
121 def _new_account(login)
122   acc = {login_column=>login}
123   unless skip_status_checks?
124     acc[account_status_column] = account_initial_status_value
125   end
126   acc
127 end
_otp()
[show source]
    # File lib/rodauth/features/otp.rb
408 def _otp
409   otp_class.new(otp_user_key, :issuer=>otp_issuer, :digits=>otp_digits, :interval=>otp_interval)
410 end
_otp_add_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
397 def _otp_add_key(secret)
398   # Uniqueness errors can't be handled here, as we can't be sure the secret provided
399   # is the same as the current secret.
400   otp_key_ds.insert(otp_keys_id_column=>session_value, otp_keys_column=>secret)
401 end
_otp_key()
[show source]
    # File lib/rodauth/features/otp.rb
403 def _otp_key
404   @otp_user_key = nil
405   otp_key_ds.get(otp_keys_column)
406 end
_otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
391 def _otp_tmp_key(secret)
392   @otp_tmp_key = true
393   @otp_user_key = nil
394   @otp_key = secret
395 end
_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
255 def _recovery_codes
256   recovery_codes_ds.select_map(recovery_codes_column)
257 end
_return_json_response()
[show source]
    # File lib/rodauth/features/json.rb
156 def _return_json_response
157   response.status ||= json_response_error_status if json_response[json_response_error_key]
158   response['Content-Type'] ||= json_response_content_type
159   response.write(_json_response_body(json_response))
160   request.halt
161 end
_setup_account_lockouts_hash(account_id, key)
[show source]
    # File lib/rodauth/features/lockout.rb
174 def _setup_account_lockouts_hash(account_id, key)
175   hash = {account_lockouts_id_column=>account_id, account_lockouts_key_column=>key}
176   set_deadline_value(hash, account_lockouts_deadline_column, account_lockouts_deadline_interval)
177   hash
178 end
_sms()
[show source]
    # File lib/rodauth/features/sms_codes.rb
499 def _sms
500   sms_ds.first
501 end
_two_factor_remove_all_from_session()
[show source]
    # File lib/rodauth/features/otp.rb
347 def _two_factor_remove_all_from_session
348   two_factor_remove_session('totp')
349   super
350 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   updated && !raised
90 end
_view(meth, page)
[show source]
    # File lib/rodauth/features/base.rb
784 def _view(meth, page)
785   scope.send(meth, _view_opts(page))
786 end
_view_opts(page)
[show source]
    # File lib/rodauth/features/base.rb
769 def _view_opts(page)
770   opts = template_opts.dup
771   opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
772   opts[:locals][:rodauth] = self
773   opts[:cache] = cache_templates
774   opts[:cache_key] = :"rodauth_#{page}"
775 
776   opts = scope.send(:find_template, scope.send(:parse_template_opts, page, opts))
777   unless File.file?(scope.send(:template_path, opts))
778     opts[:path] = template_path(page)
779   end
780 
781   opts
782 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
672 def account_ds(id=account_id)
673   raise ArgumentError, "invalid account id passed to account_ds" unless id
674   ds = db[accounts_table].where(account_id_column=>id)
675   ds = ds.select(*account_select) if account_select
676   ds
677 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
136 def account_from_email_auth_key(key)
137   @account = _account_from_email_auth_key(key)
138 end
account_from_key(token, status_id=nil)
[show source]
   # File lib/rodauth/features/email_base.rb
65 def account_from_key(token, status_id=nil)
66   id, key = split_token(token)
67   return unless id && key
68 
69   return unless actual = yield(id)
70 
71   unless timing_safe_eql?(key, convert_email_token_key(actual))
72     if hmac_secret && allow_raw_email_token?
73       return unless timing_safe_eql?(key, actual)
74     else
75       return
76     end
77   end
78   ds = account_ds(id)
79   ds = ds.where(account_status_column=>status_id) if status_id && !skip_status_checks?
80   ds.first
81 end
account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
252 def account_from_login(login)
253   @account = _account_from_login(login)
254 end
account_from_refresh_token(token)
[show source]
   # File lib/rodauth/features/jwt_refresh.rb
88 def account_from_refresh_token(token)
89   @account = _account_from_refresh_token(token)
90 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
345 def account_from_session
346   @account = _account_from_session
347 end
account_from_unlock_key(key)
[show source]
    # File lib/rodauth/features/lockout.rb
225 def account_from_unlock_key(key)
226   @account = _account_from_unlock_key(key)
227 end
account_from_verify_account_key(key)
[show source]
    # File lib/rodauth/features/verify_account.rb
208 def account_from_verify_account_key(key)
209   @account = _account_from_verify_account_key(key)
210 end
account_from_verify_login_change_key(key)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
122 def account_from_verify_login_change_key(key)
123   @account = _account_from_verify_login_change_key(key)
124 end
account_id()
[show source]
    # File lib/rodauth/features/base.rb
242 def account_id
243   account[account_id_column]
244 end
account_in_unverified_grace_period?()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
74 def account_in_unverified_grace_period?
75   return false unless account || (session_value && account_from_session)
76   account[account_status_column] == account_unverified_status_value &&
77     verify_account_grace_period &&
78     !verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
79 end
account_initial_status_value()
[show source]
    # File lib/rodauth/features/base.rb
341 def account_initial_status_value
342   account_open_status_value
343 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
272 def account_password_hash_column
273   nil
274 end
account_session_status_filter()
[show source]
    # File lib/rodauth/features/base.rb
664 def account_session_status_filter
665   {account_status_column=>account_open_status_value}
666 end
account_webauthn_ids()
[show source]
    # File lib/rodauth/features/webauthn.rb
262 def account_webauthn_ids
263   webauthn_keys_ds.select_map(webauthn_keys_webauthn_id_column)
264 end
account_webauthn_usage()
[show source]
    # File lib/rodauth/features/webauthn.rb
266 def account_webauthn_usage
267   webauthn_keys_ds.select_hash(webauthn_keys_webauthn_id_column, webauthn_keys_last_use_column)
268 end
account_webauthn_user_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
270 def account_webauthn_user_id
271   unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
272     webauthn_id = WebAuthn.generate_user_id
273     if e = raised_uniqueness_violation do
274           webauthn_user_ids_ds.insert(
275             webauthn_user_ids_account_id_column => webauthn_account_id,
276             webauthn_user_ids_webauthn_id_column => webauthn_id
277           )
278         end
279       # If two requests to create a webauthn user id are sent at the same time and an insert
280       # is attempted for both, one will fail with a unique constraint violation.  In that case
281       # it is safe for the second one to use the webauthn user id inserted by the other request.
282       # If there is still no webauthn user id at this point, then we'll just reraise the
283       # exception.
284       # :nocov:
285       raise e unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
286       # :nocov:
287     end
288   end
289 
290   webauthn_id
291 end
active_remember_key_ds(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
222 def active_remember_key_ds(id=account_id)
223   remember_key_ds(id).where(Sequel.expr(remember_deadline_column) > Sequel::CURRENT_TIMESTAMP)
224 end
active_sessions_ds()
[show source]
    # File lib/rodauth/features/active_sessions.rb
170 def active_sessions_ds
171   db[active_sessions_table].
172     where(active_sessions_account_id_column=>session_value)
173 end
active_sessions_insert_hash()
[show source]
    # File lib/rodauth/features/active_sessions.rb
139 def active_sessions_insert_hash
140   {active_sessions_account_id_column => session_value, active_sessions_session_id_column => compute_hmac(active_sessions_key)}
141 end
active_sessions_update_hash()
[show source]
    # File lib/rodauth/features/active_sessions.rb
143 def active_sessions_update_hash
144   {active_sessions_last_use_column => Sequel::CURRENT_TIMESTAMP}
145 end
add_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
65 def add_active_session
66   key = generate_active_sessions_key
67   set_session_value(session_id_session_key, key)
68   if e = raises_uniqueness_violation?{active_sessions_ds.insert(active_sessions_insert_hash)}
69     handle_duplicate_active_session_id(e)
70   end
71   nil
72 end
add_audit_log(account_id, action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
39 def add_audit_log(account_id, action)
40   if hash = audit_log_insert_hash(account_id, action)
41     audit_log_ds.insert(hash)
42   end
43 end
add_field_error_class(field)
[show source]
    # File lib/rodauth/features/base.rb
172 def add_field_error_class(field)
173   if field_error(field)
174     " #{input_field_error_class}"
175   end
176 end
add_previous_password_hash(hash)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
25 def add_previous_password_hash(hash) 
26   ds = previous_password_ds
27 
28   unless @dont_check_previous_password
29     keep_before = ds.reverse(previous_password_id_column).
30       limit(nil, previous_passwords_to_check).
31       get(previous_password_id_column)
32 
33     if keep_before
34       ds.where(Sequel.expr(previous_password_id_column) <= keep_before).
35         delete
36     end
37   end
38 
39   # This should never raise uniqueness violations, as it uses a serial primary key
40   ds.insert(previous_password_account_id_column=>account_id, previous_password_hash_column=>hash)
41 end
add_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
186 def add_recovery_code
187   # This should never raise uniqueness violations unless the recovery code is the same, and the odds of that
188   # are 1/256**32 assuming a good random number generator.  Still, attempt to handle that case by retrying
189   # on such a uniqueness violation.
190   retry_on_uniqueness_violation do
191     recovery_codes_ds.insert(recovery_codes_id_column=>session_value, recovery_codes_column=>new_recovery_code)
192   end
193 end
add_recovery_codes(number)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
176 def add_recovery_codes(number)
177   return if number <= 0
178   transaction do
179     number.times do
180       add_recovery_code
181     end
182   end
183   remove_instance_variable(:@recovery_codes)
184 end
add_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
173 def add_remember_key
174   hash = {remember_id_column=>account_id, remember_key_column=>remember_key_value}
175   set_deadline_value(hash, remember_deadline_column, remember_deadline_interval)
176 
177   if e = raised_uniqueness_violation{remember_key_ds.insert(hash)}
178     # If inserting into the remember key table causes a violation, we can pull the
179     # existing row from the table.  If there is no invalid row, we can then reraise.
180     raise e unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
181   end
182 end
add_webauthn_credential(_)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
150 def add_webauthn_credential(_)
151   super if defined?(super)
152   auto_add_missing_recovery_codes
153 end
after_change_password()
[show source]
   # File lib/rodauth/features/change_password_notify.rb
31 def after_change_password
32   super
33   send_password_changed_email
34 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
87 def after_create_account
88   if account_password_hash_column && !(respond_to?(:verify_account_set_password?) && verify_account_set_password?)
89     add_previous_password_hash(password_hash(param(password_param)))
90   end
91   super if defined?(super)
92 end
after_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
215 def after_login
216   # Remove the email auth key after any login, even if
217   # it is a password login.  This is done to invalidate
218   # the email login when a user has a password and requests
219   # email authentication, but then remembers their password
220   # and doesn't need the link.  At that point, the link
221   # that allows login access to the account becomes a
222   # security liability, and it is best to remove it.
223   remove_email_auth_key
224   super
225 end
after_login_entered_during_multi_phase_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
158 def after_login_entered_during_multi_phase_login
159   # If forcing email auth, just send the email link.
160   _email_auth_request_and_redirect if force_email_auth?
161 
162   super
163 end
after_login_failure()
[show source]
    # File lib/rodauth/features/lockout.rb
265 def after_login_failure
266   invalid_login_attempted
267   super
268 end
after_logout()
[show source]
    # File lib/rodauth/features/remember.rb
198 def after_logout
199   forget_login
200   super if defined?(super)
201 end
after_otp_disable()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
220 def after_otp_disable
221   super if defined?(super)
222   auto_remove_recovery_codes
223 end
after_refresh_token()
[show source]
    # File lib/rodauth/features/active_sessions.rb
108 def after_refresh_token
109   super if defined?(super)
110   if prev_key = session[session_id_session_key]
111     key = generate_active_sessions_key
112     set_session_value(session_id_session_key, key)
113     active_sessions_ds.
114       where(active_sessions_session_id_column => compute_hmac(prev_key)).
115       update(active_sessions_session_id_column => compute_hmac(key))
116   end
117 end
after_reset_password()
[show source]
   # File lib/rodauth/features/password_grace_period.rb
39 def after_reset_password
40   super if defined?(super)
41   @last_password_entry = Time.now.to_i
42 end
after_sms_disable()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
225 def after_sms_disable
226   super if defined?(super)
227   auto_remove_recovery_codes
228 end
after_webauthn_remove()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
230 def after_webauthn_remove
231   super if defined?(super)
232   auto_remove_recovery_codes
233 end
allow_email_auth?()
[show source]
    # File lib/rodauth/features/email_auth.rb
211 def allow_email_auth?
212   defined?(super) ? super : true
213 end
allow_resending_verify_account_email?()
[show source]
    # File lib/rodauth/features/verify_account.rb
173 def allow_resending_verify_account_email?
174   account[account_status_column] == account_unverified_status_value
175 end
already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
280 def already_logged_in
281   nil
282 end
argon2_hash_algorithm?(hash)

:nocov:

[show source]
   # File lib/rodauth/features/argon2.rb
61 def argon2_hash_algorithm?(hash)
62   hash.start_with?('$argon2id$')
63 end
argon2_hash_cost()
[show source]
   # File lib/rodauth/features/argon2.rb
50 def argon2_hash_cost
51   {t_cost: 1, m_cost: 3}
52 end
argon2_password_hash_match?(hash, password)
[show source]
   # File lib/rodauth/features/argon2.rb
65 def argon2_password_hash_match?(hash, password)
66   ::Argon2::Password.verify_password(password, hash)
67 end
audit_log_ds()
[show source]
   # File lib/rodauth/features/audit_logging.rb
83 def audit_log_ds
84   ds = db[audit_logging_table]
85   # :nocov:
86   if db.database_type == :postgres
87   # :nocov:
88     # For PostgreSQL, use RETURNING NULL. This allows the feature
89     # to be used with INSERT but not SELECT permissions on the
90     # table, useful for audit logging where the database user
91     # the application is running as should not need to read the
92     # logs.
93     ds = ds.returning(nil)
94   end
95   ds
96 end
audit_log_insert_hash(account_id, action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
45 def audit_log_insert_hash(account_id, action)
46   if message = audit_log_message(action)
47     {
48       audit_logging_account_id_column => account_id,
49       audit_logging_message_column => message,
50       audit_logging_metadata_column => serialize_audit_log_metadata(audit_log_metadata(action))
51     }
52   end
53 end
audit_log_message(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
63 def audit_log_message(action)
64   meth = :"audit_log_message_for_#{action}"
65   if respond_to?(meth, true)
66     send(meth)
67   else
68     audit_log_message_default(action)
69   end
70 end
audit_log_message_default(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
59 def audit_log_message_default(action)
60   action.to_s
61 end
audit_log_metadata(action)
[show source]
   # File lib/rodauth/features/audit_logging.rb
72 def audit_log_metadata(action)
73   meth = :"audit_log_metadata_for_#{action}"
74   if respond_to?(meth, true)
75     send(meth)
76   else
77     audit_log_metadata_default
78   end
79 end
auth_class_eval(&block)
[show source]
    # File lib/rodauth/features/base.rb
123 def auth_class_eval(&block)
124   auth.class_eval(&block)
125 end
authenticated?()
[show source]
    # File lib/rodauth/features/base.rb
333 def authenticated?
334   logged_in?
335 end
authenticated_by()
[show source]
    # File lib/rodauth/features/base.rb
416 def authenticated_by
417   session[authenticated_by_session_key]
418 end
authenticated_webauthn_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
242 def authenticated_webauthn_id
243   session[authenticated_webauthn_id_session_key]
244 end
auto_add_missing_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
243 def auto_add_missing_recovery_codes
244   if auto_add_recovery_codes?
245     add_recovery_codes(recovery_codes_limit - recovery_codes.length)
246   end
247 end
auto_remove_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
249 def auto_remove_recovery_codes
250   if auto_remove_recovery_codes? && (%w'totp webauthn sms_code' & possible_authentication_methods).empty?
251     recovery_codes_remove
252   end
253 end
autocomplete_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
202 def autocomplete_for_field?(_param)
203   mark_input_fields_with_autocomplete?
204 end
autologin_session(autologin_type)
[show source]
    # File lib/rodauth/features/base.rb
429 def autologin_session(autologin_type)
430   login_session('autologin')
431   set_session_value(autologin_type_session_key, autologin_type)
432 end
autologin_type()
[show source]
    # File lib/rodauth/features/base.rb
425 def autologin_type
426   session[autologin_type_session_key]
427 end
base32_encode(data, length)
[show source]
    # File lib/rodauth/features/otp.rb
386 def base32_encode(data, length)
387   chars = 'abcdefghijklmnopqrstuvwxyz234567'
388   length.times.map{|i|chars[data[i].ord % 32]}.join
389 end
base_url()
[show source]
    # File lib/rodauth/features/base.rb
451 def base_url
452   url = String.new("#{request.scheme}://#{domain}")
453   url << ":#{request.port}" if request.port != Rack::Request::DEFAULT_PORTS[request.scheme]
454   url
455 end
before_change_login_route()
[show source]
   # File lib/rodauth/features/verify_account_grace_period.rb
47 def before_change_login_route
48   unless verified_account?
49     set_redirect_error_flash unverified_change_login_error_flash
50     redirect unverified_change_login_redirect
51   end
52   super if defined?(super)
53 end
before_change_password_route()
[show source]
   # File lib/rodauth/features/password_expiration.rb
90 def before_change_password_route
91   check_password_change_allowed
92   super
93 end
before_create_account_route()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
77 def before_create_account_route
78   super if defined?(super)
79   @dont_check_previous_password = true
80 end
before_login_attempt()
[show source]
    # File lib/rodauth/features/lockout.rb
253 def before_login_attempt
254   if locked_out?
255     show_lockout_page
256   end
257   super
258 end
before_logout()
[show source]
    # File lib/rodauth/features/active_sessions.rb
124 def before_logout
125   if param_or_nil(global_logout_param)
126     remove_all_active_sessions
127   else
128     remove_current_session
129   end
130   super
131 end
before_otp_setup_route()
[show source]
    # File lib/rodauth/features/json.rb
115 def before_otp_setup_route
116   super if defined?(super)
117   if use_json? && otp_keys_use_hmac? && !param_or_nil(otp_setup_raw_param)
118     _otp_tmp_key(otp_new_secret)
119     json_response[otp_setup_param] = otp_user_key
120     json_response[otp_setup_raw_param] = otp_key
121   end
122 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
124 def before_rodauth
125   if json_request?
126     if json_check_accept? && (accept = request.env['HTTP_ACCEPT']) && accept !~ json_accept_regexp
127       response.status = 406
128       json_response[json_response_error_key] = json_not_accepted_error_message
129       _return_json_response
130     end
131 
132     unless request.post?
133       response.status = 405
134       response.headers['Allow'] = 'POST'
135       json_response[json_response_error_key] = json_non_post_error_message
136       return_json_response
137     end
138   elsif only_json?
139     response.status = json_response_error_status
140     response.write non_json_request_error_message
141     request.halt
142   end
143 
144   super
145 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
30 def before_verify_account
31   super
32   if features.include?(:json) && use_json? && !param_or_nil(webauthn_setup_param)
33     cred = new_webauthn_credential
34     json_response[webauthn_setup_param] = cred.as_json
35     json_response[webauthn_setup_challenge_param] = cred.challenge
36     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
37   end
38   @webauthn_credential = webauthn_setup_credential_from_form_submission
39   add_webauthn_credential(@webauthn_credential)
40 end
before_verify_account_route()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
82 def before_verify_account_route
83   super if defined?(super)
84   @dont_check_previous_password = true
85 end
before_view_recovery_codes()
[show source]
   # File lib/rodauth/features/json.rb
70 def before_view_recovery_codes
71   super if defined?(super)
72   if use_json?
73     json_response[:codes] = recovery_codes
74     json_response[json_response_success_key] ||= "" if include_success_messages?
75   end
76 end
before_webauthn_auth_route()
[show source]
   # File lib/rodauth/features/json.rb
88 def before_webauthn_auth_route
89   super if defined?(super)
90   if use_json? && !param_or_nil(webauthn_auth_param)
91     cred = webauth_credential_options_for_get
92     json_response[webauthn_auth_param] = cred.as_json
93     json_response[webauthn_auth_challenge_param] = cred.challenge
94     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
95   end
96 end
before_webauthn_login_route()
[show source]
    # File lib/rodauth/features/json.rb
 98 def before_webauthn_login_route
 99   super if defined?(super)
100   if use_json? && !param_or_nil(webauthn_auth_param) && account_from_login(param(login_param))
101     cred = webauth_credential_options_for_get
102     json_response[webauthn_auth_param] = cred.as_json
103     json_response[webauthn_auth_challenge_param] = cred.challenge
104     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
105   end
106 end
before_webauthn_remove_route()
[show source]
    # File lib/rodauth/features/json.rb
108 def before_webauthn_remove_route
109   super if defined?(super)
110   if use_json? && !param_or_nil(webauthn_remove_param)
111     json_response[webauthn_remove_param] = account_webauthn_usage
112   end
113 end
before_webauthn_setup_route()
[show source]
   # File lib/rodauth/features/json.rb
78 def before_webauthn_setup_route
79   super if defined?(super)
80   if use_json? && !param_or_nil(webauthn_setup_param)
81     cred = new_webauthn_credential
82     json_response[webauthn_setup_param] = cred.as_json
83     json_response[webauthn_setup_challenge_param] = cred.challenge
84     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
85   end
86 end
button(value, opts={})
[show source]
    # File lib/rodauth/features/base.rb
374 def button(value, opts={})
375   scope.render(button_opts(value, opts))
376 end
button_opts(value, opts)
[show source]
    # File lib/rodauth/features/base.rb
365 def button_opts(value, opts)
366   opts = Hash[template_opts].merge!(opts)
367   opts[:locals] = {:value=>value, :opts=>opts}
368   opts[:path] = template_path('button')
369   opts[:cache] = cache_templates
370   opts[:cache_key] = :rodauth_button
371   opts
372 end
can_add_recovery_codes?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
172 def can_add_recovery_codes?
173   recovery_codes.length < recovery_codes_limit
174 end
catch_error(&block)
[show source]
    # File lib/rodauth/features/base.rb
539 def catch_error(&block)
540   catch(:rodauth_error, &block)
541 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
138 def change_login_notice_flash
139   change_login_needs_verification_notice_flash
140 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
68 def change_password_requires_password?
69   modifications_require_password?
70 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
51 def check_active_session
52   if logged_in? && !currently_active_session?
53     no_longer_active_session
54   end
55 end
check_already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
276 def check_already_logged_in
277   already_logged_in if logged_in?
278 end
check_csrf()
[show source]
    # File lib/rodauth/features/base.rb
349 def check_csrf
350   scope.check_csrf!(check_csrf_opts, &check_csrf_block)
351 end
check_csrf?()
[show source]
    # File lib/rodauth/features/base.rb
597 def check_csrf?
598   scope.opts[:rodauth_route_csrf]
599 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
51 def check_single_session
52   if logged_in? && !currently_active_session?
53     no_longer_active_session
54   end
55 end
clear_cached_otp()
[show source]
    # File lib/rodauth/features/otp.rb
352 def clear_cached_otp
353   remove_instance_variable(:@otp) if defined?(@otp)
354 end
clear_invalid_login_attempts()
[show source]
    # File lib/rodauth/features/lockout.rb
170 def clear_invalid_login_attempts
171   unlock_account
172 end
clear_session()
[show source]
    # File lib/rodauth/features/base.rb
292 def clear_session
293   if scope.respond_to?(:clear_session)
294     scope.clear_session
295   else
296     session.clear
297   end
298 end
close_account()
[show source]
   # File lib/rodauth/features/close_account.rb
66 def close_account
67   unless skip_status_checks?
68     update_account(account_status_column=>account_closed_status_value)
69   end
70 
71   unless account_password_hash_column
72     password_hash_ds.delete
73   end
74 end
close_account_requires_password?()
[show source]
   # File lib/rodauth/features/close_account.rb
62 def close_account_requires_password?
63   modifications_require_password?
64 end
compute_hmac(data)

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

[show source]
    # File lib/rodauth/features/base.rb
236 def compute_hmac(data)
237   s = [compute_raw_hmac(data)].pack('m').chomp!("=\n")
238   s.tr!('+/', '-_')
239   s
240 end
compute_raw_hmac(data)
[show source]
    # File lib/rodauth/features/base.rb
648 def compute_raw_hmac(data)
649   OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, hmac_secret, data)
650 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
61 def convert_email_token_key(key)
62   convert_token_key(key)
63 end
convert_session_key(key)
[show source]
    # File lib/rodauth/features/base.rb
517 def convert_session_key(key)
518   key = "#{session_key_prefix}#{key}".to_sym if session_key_prefix
519   scope.opts[:sessions_convert_symbols] ? key.to_s : key
520 end
convert_timestamp(timestamp)

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

[show source]
    # File lib/rodauth/features/base.rb
684 def convert_timestamp(timestamp)
685   timestamp = db.to_application_timestamp(timestamp) if timestamp.is_a?(String)
686   timestamp
687 end
convert_token_key(key)
[show source]
    # File lib/rodauth/features/base.rb
483 def convert_token_key(key)
484   if key && hmac_secret
485     compute_hmac(key)
486   else
487     key
488   end
489 end
create_account_autologin?()
[show source]
    # File lib/rodauth/features/verify_account.rb
232 def create_account_autologin?
233   false
234 end
create_account_notice_flash()
[show source]
    # File lib/rodauth/features/verify_account.rb
193 def create_account_notice_flash
194   verify_account_email_sent_notice_flash
195 end
create_account_set_password?()
[show source]
    # File lib/rodauth/features/verify_account.rb
236 def create_account_set_password?
237   return false if verify_account_set_password?
238   super
239 end
create_email(subject, body)
[show source]
   # File lib/rodauth/features/email_base.rb
32 def create_email(subject, body)
33   create_email_to(email_to, subject, body)
34 end
create_email_auth_email()
[show source]
    # File lib/rodauth/features/email_auth.rb
236 def create_email_auth_email
237   create_email(email_auth_email_subject, email_auth_email_body)
238 end
create_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
107 def create_email_auth_key
108   transaction do
109     if email_auth_key_value = get_email_auth_key(account_id)
110       set_email_auth_email_last_sent
111       @email_auth_key_value = email_auth_key_value
112     elsif e = raised_uniqueness_violation{email_auth_ds.insert(email_auth_key_insert_hash)}
113       # If inserting into the email auth table causes a violation, we can pull the
114       # existing email auth key from the table, or reraise.
115       raise e unless @email_auth_key_value = get_email_auth_key(account_id)
116     end
117   end
118 end
create_email_to(to, subject, body)
[show source]
   # File lib/rodauth/features/email_base.rb
36 def create_email_to(to, subject, body)
37   m = Mail.new
38   m.from = email_from
39   m.to = to
40   m.subject = "#{email_subject_prefix}#{subject}"
41   m.body = body
42   m
43 end
create_password_changed_email()
[show source]
   # File lib/rodauth/features/change_password_notify.rb
23 def create_password_changed_email
24   create_email(password_changed_email_subject, password_changed_email_body)
25 end
create_reset_password_email()
[show source]
    # File lib/rodauth/features/reset_password.rb
244 def create_reset_password_email
245   create_email(reset_password_email_subject, reset_password_email_body)
246 end
create_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
169 def create_reset_password_key
170   transaction do
171     if reset_password_key_value = get_password_reset_key(account_id)
172       set_reset_password_email_last_sent
173       @reset_password_key_value = reset_password_key_value
174     elsif e = raised_uniqueness_violation{password_reset_ds.insert(reset_password_key_insert_hash)}
175       # If inserting into the reset password table causes a violation, we can pull the
176       # existing reset password key from the table, or reraise.
177       raise e unless @reset_password_key_value = get_password_reset_key(account_id)
178     end
179   end
180 end
create_unlock_account_email()
[show source]
    # File lib/rodauth/features/lockout.rb
291 def create_unlock_account_email
292   create_email(unlock_account_email_subject, unlock_account_email_body)
293 end
create_verify_account_email()
[show source]
    # File lib/rodauth/features/verify_account.rb
316 def create_verify_account_email
317   create_email(verify_account_email_subject, verify_account_email_body)
318 end
create_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
299 def create_verify_account_key
300   ds = verify_account_ds
301   transaction do
302     if ds.empty?
303       if e = raised_uniqueness_violation{ds.insert(verify_account_key_insert_hash)}
304         # If inserting into the verify account table causes a violation, we can pull the
305         # key from the verify account table, or reraise.
306         raise e unless @verify_account_key_value = get_verify_account_key(account_id)
307       end
308     end
309   end
310 end
create_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
200 def create_verify_login_change_email(login)
201   create_email_to(login, verify_login_change_email_subject, verify_login_change_email_body)
202 end
create_verify_login_change_key(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
178 def create_verify_login_change_key(login)
179   ds = verify_login_change_ds
180   transaction do
181     ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
182     if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
183       old_login, key = get_verify_login_change_login_and_key(account_id)
184       # If inserting into the verify login change table causes a violation, we can pull the
185       # key from the verify login change table if the logins match, or reraise.
186       @verify_login_change_key_value = if old_login.downcase == login.downcase
187         key
188       end
189       raise e unless @verify_login_change_key_value
190     end
191   end
192 end
csrf_tag(path=request.path)
[show source]
    # File lib/rodauth/features/base.rb
353 def csrf_tag(path=request.path)
354   return unless scope.respond_to?(:csrf_tag)
355 
356   if use_request_specific_csrf_tokens?
357     scope.csrf_tag(path)
358   else
359     # :nocov:
360     scope.csrf_tag
361     # :nocov:
362   end
363 end
currently_active_session?()
[show source]
   # File lib/rodauth/features/active_sessions.rb
37 def currently_active_session?
38   return false unless session_id = session[session_id_session_key]
39 
40   remove_inactive_sessions
41   ds = active_sessions_ds.
42     where(active_sessions_session_id_column => compute_hmac(session_id))
43 
44   if update_current_session?
45     ds.update(active_sessions_update_hash) == 1
46   else
47     ds.count == 1
48   end
49 end
database_function_password_match?(name, hash_id, password, salt)
[show source]
    # File lib/rodauth/features/base.rb
475 def database_function_password_match?(name, hash_id, password, salt)
476   db.get(Sequel.function(function_name(name), hash_id, password_hash_using_salt(password, salt)))
477 end
db()
[show source]
    # File lib/rodauth/features/base.rb
260 def db
261   Sequel::DATABASES.first
262 end
delete_account()
[show source]
   # File lib/rodauth/features/close_account.rb
76 def delete_account
77   account_ds.delete
78 end
delete_account_on_close?()
[show source]
   # File lib/rodauth/features/close_account.rb
80 def delete_account_on_close?
81   skip_status_checks?
82 end
disable_remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
169 def disable_remember_login
170   remove_remember_key
171 end
domain()
[show source]
    # File lib/rodauth/features/base.rb
457 def domain
458   request.host
459 end
email_auth_ds(id=account_id)
[show source]
    # File lib/rodauth/features/email_auth.rb
254 def email_auth_ds(id=account_id)
255   db[email_auth_table].where(email_auth_id_column=>id)
256 end
email_auth_email_body()
[show source]
    # File lib/rodauth/features/email_auth.rb
240 def email_auth_email_body
241   render('email-auth-email')
242 end
email_auth_email_recently_sent?()
[show source]
    # File lib/rodauth/features/email_auth.rb
183 def email_auth_email_recently_sent?
184   (email_last_sent = get_email_auth_email_last_sent) && (Time.now - email_last_sent < email_auth_skip_resend_email_within)
185 end
email_auth_key_insert_hash()
[show source]
    # File lib/rodauth/features/email_auth.rb
248 def email_auth_key_insert_hash
249   hash = {email_auth_id_column=>account_id, email_auth_key_column=>email_auth_key_value}
250   set_deadline_value(hash, email_auth_deadline_column, email_auth_deadline_interval)
251   hash
252 end
email_auth_request_form()
[show source]
    # File lib/rodauth/features/email_auth.rb
154 def email_auth_request_form
155   render('email-auth-request-form')
156 end
email_from()
[show source]
   # File lib/rodauth/features/email_base.rb
45 def email_from
46   "webmaster@#{domain}"
47 end
email_to()
[show source]
   # File lib/rodauth/features/email_base.rb
49 def email_to
50   account[login_column]
51 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
extract_password_hash_cost(hash)
[show source]
   # File lib/rodauth/features/argon2.rb
42 def extract_password_hash_cost(hash)
43   return super unless argon2_hash_algorithm?(hash )
44 
45   /\A\$argon2id\$v=\d+\$m=(\d+),t=(\d+)/ =~ hash
46   { t_cost: $2.to_i, m_cost: Math.log2($1.to_i).to_i }
47 end
features()
[show source]
    # File lib/rodauth/features/base.rb
135 def features
136   self.class.features
137 end
field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
210 def field_attributes(field)
211   _field_attributes(field) || default_field_attributes
212 end
field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
167 def field_error(field)
168   return nil unless @field_errors
169   @field_errors[field]
170 end
field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
214 def field_error_attributes(field)
215   if field_error(field)
216     _field_error_attributes(field)
217   end
218 end
flash()
[show source]
    # File lib/rodauth/features/base.rb
151 def flash
152   scope.flash
153 end
forget_login()
[show source]
    # File lib/rodauth/features/remember.rb
152 def forget_login
153   opts = Hash[remember_cookie_options]
154   opts[:path] = "/" unless opts.key?(:path)
155   ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, opts)
156 end
formatted_field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
220 def formatted_field_error(field)
221   if error = field_error(field)
222     _formatted_field_error(field, error)
223   end
224 end
function_name(name)
[show source]
    # File lib/rodauth/features/base.rb
601 def function_name(name)
602   if db.database_type == :mssql
603     # :nocov:
604     "dbo.#{name}"
605     # :nocov:
606   else
607     name
608   end
609 end
generate_active_sessions_key()
[show source]
    # File lib/rodauth/features/active_sessions.rb
135 def generate_active_sessions_key
136   @active_sessions_key = random_key
137 end
generate_email_auth_key_value()
[show source]
    # File lib/rodauth/features/email_auth.rb
232 def generate_email_auth_key_value
233   @email_auth_key_value = random_key
234 end
generate_refresh_token()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
181 def generate_refresh_token
182   hash = jwt_refresh_token_insert_hash
183   [account_id, jwt_refresh_token_ds.insert(hash), convert_token_key(hash[jwt_refresh_token_key_column])].join(token_separator)
184 end
generate_remember_key_value()
[show source]
    # File lib/rodauth/features/remember.rb
210 def generate_remember_key_value
211   @remember_key_value = random_key
212 end
generate_reset_password_key_value()
[show source]
    # File lib/rodauth/features/reset_password.rb
240 def generate_reset_password_key_value
241   @reset_password_key_value = random_key
242 end
generate_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
275 def generate_unlock_account_key
276   random_key
277 end
generate_verify_account_key_value()
[show source]
    # File lib/rodauth/features/verify_account.rb
295 def generate_verify_account_key_value
296   @verify_account_key_value = random_key
297 end
generate_verify_login_change_key_value()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
174 def generate_verify_login_change_key_value
175   @verify_login_change_key_value = random_key
176 end
get_active_refresh_token(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
154 def get_active_refresh_token(account_id, token_id)
155   jwt_refresh_token_account_ds(account_id).
156     where(Sequel::CURRENT_TIMESTAMP > jwt_refresh_token_deadline_column).
157     delete
158 
159   jwt_refresh_token_account_token_ds(account_id, token_id).
160     get(jwt_refresh_token_key_column)
161 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
124 def get_email_auth_email_last_sent
125   if column = email_auth_email_last_sent_column
126     if ts = email_auth_ds.get(column)
127       convert_timestamp(ts)
128     end
129   end
130 end
get_email_auth_key(id)
[show source]
    # File lib/rodauth/features/email_auth.rb
148 def get_email_auth_key(id)
149   ds = email_auth_ds(id)
150   ds.where(Sequel::CURRENT_TIMESTAMP > email_auth_deadline_column).delete
151   ds.get(email_auth_key_column)
152 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
623 def get_password_hash
624   if account_password_hash_column
625     (account || account_from_session)[account_password_hash_column]
626   elsif use_database_authentication_functions?
627     db.get(Sequel.function(function_name(:rodauth_get_salt), account ? account_id : session_value))
628   else
629     # :nocov:
630     password_hash_ds.get(password_hash_column)
631     # :nocov:
632   end
633 end
get_password_reset_key(id)
[show source]
    # File lib/rodauth/features/reset_password.rb
198 def get_password_reset_key(id)
199   ds = password_reset_ds(id)
200   ds.where(Sequel::CURRENT_TIMESTAMP > reset_password_deadline_column).delete
201   ds.get(reset_password_key_column)
202 end
get_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
158 def get_remember_key
159   unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
160    generate_remember_key_value
161    transaction do
162      remove_remember_key
163      add_remember_key
164    end
165   end
166   nil
167 end
get_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
208 def get_reset_password_email_last_sent
209   if column = reset_password_email_last_sent_column
210     if ts = password_reset_ds.get(column)
211       convert_timestamp(ts)
212     end
213   end
214 end
get_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
237 def get_unlock_account_email_last_sent
238   if column = account_lockouts_email_last_sent_column
239     if ts = account_lockouts_ds.get(column)
240       convert_timestamp(ts)
241     end
242   end
243 end
get_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
221 def get_unlock_account_key
222   account_lockouts_ds.get(account_lockouts_key_column)
223 end
get_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
245 def get_verify_account_email_last_sent
246   if column = verify_account_email_last_sent_column
247     if ts = verify_account_ds.get(column)
248       convert_timestamp(ts)
249     end
250   end
251 end
get_verify_account_key(id)
[show source]
    # File lib/rodauth/features/verify_account.rb
224 def get_verify_account_key(id)
225   verify_account_ds(id).get(verify_account_key_column)
226 end
get_verify_login_change_login_and_key(id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
134 def get_verify_login_change_login_and_key(id)
135   verify_login_change_ds(id).get([verify_login_change_login_column, verify_login_change_key_column])
136 end
handle_duplicate_active_session_id(_e)
[show source]
   # File lib/rodauth/features/active_sessions.rb
74 def handle_duplicate_active_session_id(_e)
75   # Do nothing by default as session is already tracked.  This will result in
76   # the current session and the existing session with the same id
77   # being tracked together, so that a logout of one will logout
78   # the other, and updating the last use on one will update the other,
79   # but this should be acceptable.  However, this can be overridden if different
80   # behavior is desired.
81 end
handle_webauthn_sign_count_verification_error()
[show source]
    # File lib/rodauth/features/webauthn.rb
344 def handle_webauthn_sign_count_verification_error
345   throw_error_reason(:invalid_webauthn_sign_count, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message) 
346 end
has_password?()
[show source]
    # File lib/rodauth/features/base.rb
611 def has_password?
612   return @has_password if defined?(@has_password)
613   return false unless account || session_value
614   @has_password = !!get_password_hash
615 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   # In after_logout, session is already cleared, so use before_logout in that case
34   if (hook_type == :after || action == :logout) && (id = account ? account_id : session_value)
35     add_audit_log(id, action)
36   end
37 end
http_basic_auth()
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
34 def http_basic_auth
35   return @checked_http_basic_auth if defined?(@checked_http_basic_auth)
36 
37   @checked_http_basic_auth = nil
38   return unless token = ((v = request.env['HTTP_AUTHORIZATION']) && v[/\A *Basic (.*)\Z/, 1])
39 
40   username, password = token.unpack("m*").first.split(/:/, 2)
41   return unless username && password
42 
43   catch_error do
44     unless account_from_login(username)
45       throw_basic_auth_error(login_param, no_matching_login_message)
46     end
47 
48     before_login_attempt
49 
50     unless open_account?
51       throw_basic_auth_error(login_param, no_matching_login_message)
52     end
53 
54     unless password_match?(password)
55       after_login_failure
56       throw_basic_auth_error(password_param, invalid_password_message)
57     end
58 
59     transaction do
60       before_login
61       login_session('password')
62       after_login
63     end
64 
65     @checked_http_basic_auth = true
66     return true
67   end
68 
69   nil
70 end
inactive_session_cond()
[show source]
    # File lib/rodauth/features/active_sessions.rb
159 def inactive_session_cond
160   cond = session_inactivity_deadline_condition
161   cond2 = session_lifetime_deadline_condition
162   return false unless cond || cond2
163   Sequel.|(*[cond, cond2].compact)
164 end
include_success_messages?()
[show source]
    # File lib/rodauth/features/json.rb
163 def include_success_messages?
164   !json_response_success_key.nil?
165 end
input_field_string(param, id, opts={})
[show source]
    # File lib/rodauth/features/base.rb
178 def input_field_string(param, id, opts={})
179   type = opts.fetch(:type, "text")
180 
181   unless type == "password"
182     value = opts.fetch(:value){scope.h param(param)}
183   end
184 
185   field_class = opts.fetch(:class, "form-control")
186 
187   if autocomplete_for_field?(param) && opts[:autocomplete]
188     autocomplete = "autocomplete=\"#{opts[:autocomplete]}\""
189   end
190 
191   if inputmode_for_field?(param) && opts[:inputmode]
192     inputmode = "inputmode=\"#{opts[:inputmode]}\""
193   end
194 
195   if mark_input_fields_as_required? && opts[:required] != false
196     required = "required=\"required\""
197   end
198 
199   "<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]}"
200 end
inputmode_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
206 def inputmode_for_field?(_param)
207   mark_input_fields_with_inputmode?
208 end
internal_request?()
[show source]
    # File lib/rodauth/features/base.rb
743 def internal_request?
744   false
745 end
internal_request_configuration(&block)
[show source]
    # File lib/rodauth/features/internal_request.rb
329 def internal_request_configuration(&block)
330   @auth.instance_exec do
331     (@internal_request_configuration_blocks ||= []) << block
332   end
333 end
invalid_login_attempted()
[show source]
    # File lib/rodauth/features/lockout.rb
180 def invalid_login_attempted
181   ds = account_login_failures_ds.
182       where(account_login_failures_id_column=>account_id)
183 
184   number = if db.database_type == :postgres
185     ds.returning(account_login_failures_number_column).
186       with_sql(:update_sql, account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1).
187       single_value
188   else
189     # :nocov:
190     if ds.update(account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1) > 0
191       ds.get(account_login_failures_number_column)
192     end
193     # :nocov:
194   end
195 
196   unless number
197     # Ignoring the violation is safe here.  It may allow slightly more than max_invalid_logins invalid logins before
198     # lockout, but allowing a few extra is OK if the race is lost.
199     ignore_uniqueness_violation{account_login_failures_ds.insert(account_login_failures_id_column=>account_id)}
200     number = 1
201   end
202 
203   if number >= max_invalid_logins
204     @unlock_account_key_value = generate_unlock_account_key
205     hash = _setup_account_lockouts_hash(account_id, unlock_account_key_value)
206 
207     if e = raised_uniqueness_violation{account_lockouts_ds.insert(hash)}
208       # If inserting into the lockout table raises a violation, we should just be able to pull the already inserted
209       # key out of it.  If that doesn't return a valid key, we should reraise the error.
210       raise e unless @unlock_account_key_value = account_lockouts_ds.get(account_lockouts_key_column)
211 
212       after_account_lockout
213       show_lockout_page
214     else
215       after_account_lockout
216       e
217     end
218   end
219 end
invalid_previous_password_message()
[show source]
   # File lib/rodauth/features/change_password.rb
72 def invalid_previous_password_message
73   invalid_password_message
74 end
json_request?()
[show source]
   # File lib/rodauth/features/json.rb
54 def json_request?
55   return @json_request if defined?(@json_request)
56   @json_request = request.content_type =~ json_request_content_type_regexp
57 end
json_response()
[show source]
    # File lib/rodauth/features/json.rb
171 def json_response
172   @json_response ||= {}
173 end
jwt_cors_allow?()
[show source]
   # File lib/rodauth/features/jwt_cors.rb
15 def jwt_cors_allow?
16   return false unless origin = request.env['HTTP_ORIGIN']
17 
18   case allowed = jwt_cors_allow_origin
19   when String
20     timing_safe_eql?(origin, allowed)
21   when Array
22     allowed.any?{|s| timing_safe_eql?(origin, s)}
23   when Regexp
24     allowed =~ origin
25   when true
26     true
27   else
28     false
29   end
30 end
jwt_payload()
[show source]
    # File lib/rodauth/features/jwt.rb
114 def jwt_payload
115   return @jwt_payload if defined?(@jwt_payload)
116   @jwt_payload = JWT.decode(jwt_token, jwt_secret, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
117 rescue JWT::DecodeError => e
118   rescue_jwt_payload(e)
119 end
jwt_refresh_token_account_ds(account_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
163 def jwt_refresh_token_account_ds(account_id)
164   jwt_refresh_token_ds.where(jwt_refresh_token_account_id_column => account_id)
165 end
jwt_refresh_token_account_token_ds(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
167 def jwt_refresh_token_account_token_ds(account_id, token_id)
168   jwt_refresh_token_account_ds(account_id).
169     where(jwt_refresh_token_id_column=>token_id)
170 end
jwt_refresh_token_ds()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
172 def jwt_refresh_token_ds
173   db[jwt_refresh_token_table]
174 end
jwt_refresh_token_insert_hash()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
186 def jwt_refresh_token_insert_hash
187   hash = {jwt_refresh_token_account_id_column => account_id, jwt_refresh_token_key_column => random_key}
188   set_deadline_value(hash, jwt_refresh_token_deadline_column, jwt_refresh_token_deadline_interval)
189   hash
190 end
jwt_refresh_token_match?(key)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
145 def jwt_refresh_token_match?(key)
146   # We don't need to match tokens if we are requiring a valid current access token
147   return true unless allow_refresh_with_expired_jwt_access_token?
148 
149   # If allowing with expired jwt access token, check the expired session contains
150   # hmac matching submitted and active refresh token.
151   timing_safe_eql?(compute_hmac(session[jwt_refresh_token_data_session_key].to_s + key), session[jwt_refresh_token_hmac_session_key].to_s)
152 end
jwt_secret()
[show source]
   # File lib/rodauth/features/jwt.rb
67 def jwt_secret
68   raise ArgumentError, "jwt_secret not set"
69 end
jwt_session_hash()
[show source]
   # File lib/rodauth/features/jwt.rb
71 def jwt_session_hash
72   jwt_session_key ? {jwt_session_key=>session} : session
73 end
jwt_token()
[show source]
   # File lib/rodauth/features/jwt.rb
79 def jwt_token
80   return @jwt_token if defined?(@jwt_token)
81 
82   if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
83     @jwt_token = v.sub(jwt_authorization_remove, '')
84   end
85 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
112 def load_memory
113   return if session[session_key]
114 
115   unless id = remembered_session_id
116     # Only set expired cookie if there is already a cookie set.
117     forget_login if _get_remember_cookie
118     return
119   end
120 
121   set_session_value(session_key, id)
122   account = account_from_session
123   remove_session_value(session_key)
124 
125   unless account
126     remove_remember_key(id)
127     forget_login
128     return 
129   end
130 
131   before_load_memory
132   login_session('remember')
133 
134   if extend_remember_deadline?
135     active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
136     remember_login
137   end
138   after_load_memory
139 end
loaded_templates()
[show source]
    # File lib/rodauth/features/base.rb
689 def loaded_templates
690   []
691 end
locked_out?()
[show source]
    # File lib/rodauth/features/lockout.rb
151 def locked_out?
152   if t = convert_timestamp(account_lockouts_ds.get(account_lockouts_deadline_column))
153     if Time.now < t
154       true
155     else
156       unlock_account
157       false
158     end
159   else
160     false
161   end
162 end
logged_in_via_remember_key?()
[show source]
    # File lib/rodauth/features/remember.rb
188 def logged_in_via_remember_key?
189   authenticated_by.include?('remember')
190 end
login(auth_type)
[show source]
   # File lib/rodauth/features/login.rb
80 def login(auth_type)
81   saved_login_redirect = remove_session_value(login_redirect_session_key)
82   transaction do
83     before_login
84     login_session(auth_type)
85     yield if block_given?
86     after_login
87   end
88   set_notice_flash login_notice_flash
89   redirect(saved_login_redirect || login_redirect)
90 end
login_confirm_label()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
40 def login_confirm_label
41   "Confirm #{login_label}"
42 end
login_does_not_meet_requirements_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
90 def login_does_not_meet_requirements_message
91   "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
92 end
login_failed_reset_password_request_form()
[show source]
    # File lib/rodauth/features/reset_password.rb
248 def login_failed_reset_password_request_form
249   render("reset-password-request")
250 end
login_hidden_field()
[show source]
    # File lib/rodauth/features/login.rb
124 def login_hidden_field
125   "<input type='hidden' name=\"#{login_param}\" value=\"#{scope.h param(login_param)}\" />"
126 end
login_input_type()
[show source]
    # File lib/rodauth/features/base.rb
284 def login_input_type
285   login_uses_email? ? 'email' : 'text'
286 end
login_meets_email_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
119 def login_meets_email_requirements?(login)
120   return true unless require_email_address_logins?
121   return true if login_valid_email?(login)
122   set_login_requirement_error_message(:login_not_valid_email, login_not_valid_email_message)
123   return false
124 end
login_meets_length_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
107 def login_meets_length_requirements?(login)
108   if login_minimum_length > login.length
109     set_login_requirement_error_message(:login_too_short, login_too_short_message)
110     false
111   elsif login_maximum_length < login.length
112     set_login_requirement_error_message(:login_too_long, login_too_long_message)
113     false
114   else
115     true
116   end
117 end
login_meets_requirements?(login)
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
48 def login_meets_requirements?(login)
49   login_meets_length_requirements?(login) && \
50     login_meets_email_requirements?(login)
51 end
login_required()
[show source]
    # File lib/rodauth/features/base.rb
300 def login_required
301   set_redirect_error_status(login_required_error_status)
302   set_error_reason :login_required
303   set_redirect_error_flash require_login_error_flash
304   redirect require_login_redirect
305 end
login_return_to_requested_location_path()
[show source]
    # File lib/rodauth/features/login.rb
 99 def login_return_to_requested_location_path
100   request.fullpath if request.get?
101 end
login_session(auth_type)
[show source]
    # File lib/rodauth/features/base.rb
420 def login_session(auth_type)
421   update_session
422   set_session_value(authenticated_by_session_key, [auth_type])
423 end
login_too_long_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
94 def login_too_long_message
95   "maximum #{login_maximum_length} characters"
96 end
login_too_short_message()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
 98 def login_too_short_message
 99   "minimum #{login_minimum_length} characters"
100 end
login_uses_email?()
[show source]
    # File lib/rodauth/features/base.rb
288 def login_uses_email?
289   login_column == :email
290 end
login_valid_email?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
126 def login_valid_email?(login)
127   login =~ login_email_regexp
128 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
97 def logout_additional_form_tags
98   super.to_s + render('global-logout-field')
99 end
modifications_require_password?()
[show source]
    # File lib/rodauth/features/base.rb
461 def modifications_require_password?
462   has_password?
463 end
new_account(login)
[show source]
   # File lib/rodauth/features/create_account.rb
96 def new_account(login)
97   @account = _new_account(login)
98 end
new_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
235 def new_recovery_code
236   random_key
237 end
new_webauthn_credential()
[show source]
    # File lib/rodauth/features/webauthn.rb
293 def new_webauthn_credential
294   WebAuthn::Credential.options_for_create(
295     :timeout => webauthn_setup_timeout,
296     :rp => {:name=>webauthn_rp_name, :id=>webauthn_rp_id},
297     :user => {:id=>account_webauthn_user_id, :name=>webauthn_user_name},
298     :authenticator_selection => webauthn_authenticator_selection,
299     :attestation => webauthn_attestation,
300     :extensions => webauthn_extensions,
301     :exclude => account_webauthn_ids,
302   )
303 end
no_longer_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
57 def no_longer_active_session
58   clear_session
59   set_redirect_error_status inactive_session_error_status
60   set_error_reason :inactive_session
61   set_redirect_error_flash active_sessions_error_flash
62   redirect active_sessions_redirect
63 end
only_json?()
[show source]
    # File lib/rodauth/features/base.rb
387 def only_json?
388   scope.class.opts[:rodauth_json] == :only
389 end
open_account?()
[show source]
    # File lib/rodauth/features/base.rb
256 def open_account?
257   skip_status_checks? || account[account_status_column] == account_open_status_value 
258 end
otp_add_key()
[show source]
    # File lib/rodauth/features/otp.rb
266 def otp_add_key
267   _otp_add_key(otp_key)
268   super if defined?(super)
269 end
otp_exists?()
[show source]
    # File lib/rodauth/features/otp.rb
241 def otp_exists?
242   !otp_key.nil?
243 end
otp_hmac_secret(key)
[show source]
    # File lib/rodauth/features/otp.rb
361 def otp_hmac_secret(key)
362   base32_encode(compute_raw_hmac(ROTP::Base32.decode(key)), key.bytesize)
363 end
otp_issuer()
[show source]
    # File lib/rodauth/features/otp.rb
297 def otp_issuer
298   domain
299 end
otp_key_ds()
[show source]
    # File lib/rodauth/features/otp.rb
412 def otp_key_ds
413   db[otp_keys_table].where(otp_keys_id_column=>session_value)
414 end
otp_keys_use_hmac?()
[show source]
    # File lib/rodauth/features/otp.rb
317 def otp_keys_use_hmac?
318   !!hmac_secret
319 end
otp_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
277 def otp_last_use
278   convert_timestamp(otp_key_ds.get(otp_keys_last_use_column))
279 end
otp_locked_out?()
[show source]
    # File lib/rodauth/features/otp.rb
289 def otp_locked_out?
290   otp_key_ds.get(otp_keys_failures_column) >= otp_auth_failures_limit
291 end
otp_new_secret()
[show source]
    # File lib/rodauth/features/otp.rb
375 def otp_new_secret
376   ROTP::Base32.random_base32.downcase
377 end
otp_provisioning_name()
[show source]
    # File lib/rodauth/features/otp.rb
301 def otp_provisioning_name
302   account[login_column]
303 end
otp_provisioning_uri()
[show source]
    # File lib/rodauth/features/otp.rb
293 def otp_provisioning_uri
294   otp.provisioning_uri(otp_provisioning_name)
295 end
otp_qr_code()
[show source]
    # File lib/rodauth/features/otp.rb
305 def otp_qr_code
306   RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8)
307 end
otp_record_authentication_failure()
[show source]
    # File lib/rodauth/features/otp.rb
281 def otp_record_authentication_failure
282   otp_key_ds.update(otp_keys_failures_column=>Sequel.identifier(otp_keys_failures_column) + 1)
283 end
otp_remove()
[show source]
    # File lib/rodauth/features/otp.rb
261 def otp_remove
262   otp_key_ds.delete
263   @otp_key = nil
264 end
otp_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
285 def otp_remove_auth_failures
286   otp_key_ds.update(otp_keys_failures_column=>0)
287 end
otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
356 def otp_tmp_key(secret)
357   _otp_tmp_key(secret)
358   clear_cached_otp
359 end
otp_update_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
271 def otp_update_last_use
272   otp_key_ds.
273     where(Sequel.date_add(otp_keys_last_use_column, :seconds=>(otp_interval||30)) < Sequel::CURRENT_TIMESTAMP).
274     update(otp_keys_last_use_column=>Sequel::CURRENT_TIMESTAMP) == 1
275 end
otp_user_key()
[show source]
    # File lib/rodauth/features/otp.rb
309 def otp_user_key
310   @otp_user_key ||= if otp_keys_use_hmac?
311     otp_hmac_secret(otp_key)
312   else
313     otp_key
314   end
315 end
otp_valid_code?(ot_pass)
[show source]
    # File lib/rodauth/features/otp.rb
245 def otp_valid_code?(ot_pass)
246   return false unless otp_exists?
247   ot_pass = ot_pass.gsub(/\s+/, '')
248   if drift = otp_drift
249     if otp.respond_to?(:verify_with_drift)
250       # :nocov:
251       otp.verify_with_drift(ot_pass, drift)
252       # :nocov:
253     else
254       otp.verify(ot_pass, :drift_behind=>drift, :drift_ahead=>drift)
255     end
256   else
257     otp.verify(ot_pass)
258   end
259 end
otp_valid_key?(secret)
[show source]
    # File lib/rodauth/features/otp.rb
365 def otp_valid_key?(secret)
366   return false unless secret =~ /\A([a-z2-7]{16}|[a-z2-7]{32})\z/
367   if otp_keys_use_hmac?
368     timing_safe_eql?(otp_hmac_secret(param(otp_setup_raw_param)), secret)
369   else
370     true
371   end
372 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
436 def param(key)
437   param_or_nil(key).to_s
438 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
442 def param_or_nil(key)
443   value = raw_param(key)
444   value.to_s unless value.nil?
445 end
password_changed_email_body()
[show source]
   # File lib/rodauth/features/change_password_notify.rb
27 def password_changed_email_body
28   render('password-changed-email')
29 end
password_confirm_label()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
44 def password_confirm_label
45   "Confirm #{password_label}"
46 end
password_does_not_contain_null_byte?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
136 def password_does_not_contain_null_byte?(password)
137   return true unless password.include?("\0")
138   set_password_requirement_error_message(:password_contains_null_byte, contains_null_byte_message)
139   false
140 end
password_does_not_meet_requirements_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
77 def password_does_not_meet_requirements_message
78   "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
79 end
password_doesnt_match_previous_password?(password)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
50 def password_doesnt_match_previous_password?(password)
51   match = if use_database_authentication_functions?
52     salts = previous_password_ds.
53       select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
54     return true if salts.empty?
55 
56     salts.any? do |hash_id, salt|
57       database_function_password_match?(:rodauth_previous_password_hash_match, hash_id, password, salt)
58     end
59   else
60     # :nocov:
61     previous_password_ds.select_map(previous_password_hash_column).any? do |hash|
62       password_hash_match?(hash, password)
63     end
64     # :nocov:
65   end
66 
67   return true unless match
68   set_password_requirement_error_message(:password_same_as_previous_password, password_same_as_previous_password_message)
69   false
70 end
password_expiration_ds()
[show source]
    # File lib/rodauth/features/password_expiration.rb
107 def password_expiration_ds
108   db[password_expiration_table].where(password_expiration_id_column=>account_id)
109 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   account_from_session
74   if password_changed_at = get_password_changed_at
75     set_session_value(password_changed_at_session_key, password_changed_at.to_i)
76     password_changed_at + require_password_change_after < Time.now
77   else
78     set_session_value(password_changed_at_session_key, password_expiration_default ? 0 : 2147483647)
79     password_expiration_default
80   end
81 end
password_field_autocomplete_value()
[show source]
    # File lib/rodauth/features/base.rb
264 def password_field_autocomplete_value
265   @password_field_autocomplete_value || 'current-password'
266 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
24 def password_hash(password)
25   return super unless use_argon2?
26   ::Argon2::Password.new(password_hash_cost).create(password)
27 end
password_hash_cost()
[show source]
   # File lib/rodauth/features/argon2.rb
19 def password_hash_cost
20   return super unless use_argon2?
21   argon2_hash_cost 
22 end
password_hash_ds()
[show source]
    # File lib/rodauth/features/base.rb
679 def password_hash_ds
680   db[password_hash_table].where(password_hash_id_column=>account ? account_id : session_value)
681 end
password_hash_match?(hash, password)
[show source]
   # File lib/rodauth/features/argon2.rb
29 def password_hash_match?(hash, password)
30   return super unless argon2_hash_algorithm?(hash)
31   argon2_password_hash_match?(hash, password)
32 end
password_hash_using_salt(password, salt)
[show source]
   # File lib/rodauth/features/argon2.rb
34 def password_hash_using_salt(password, salt)
35   return super unless argon2_hash_algorithm?(salt)
36 
37   argon2_params = Hash[extract_password_hash_cost(salt)]
38   argon2_params[:salt_do_not_supply] = Base64.decode64(salt.split('$').last)
39   ::Argon2::Password.new(argon2_params).create(password)
40 end
password_match?(password)
[show source]
    # File lib/rodauth/features/base.rb
401 def password_match?(password)
402   if hash = get_password_hash
403     if account_password_hash_column || !use_database_authentication_functions?
404       password_hash_match?(hash, password)
405     else
406       database_function_password_match?(:rodauth_valid_password_hash, account_id, password, hash)
407     end 
408   end
409 end
password_meets_length_requirements?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
130 def password_meets_length_requirements?(password)
131   return true if password_minimum_length <= password.length
132   set_password_requirement_error_message(:password_too_short, password_too_short_message)
133   false
134 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
22 def password_recently_entered?
23   return false unless last_password_entry = session[last_password_entry_session_key]
24   last_password_entry + password_grace_period > Time.now.to_i
25 end
password_reset_ds(id=account_id)
[show source]
    # File lib/rodauth/features/reset_password.rb
266 def password_reset_ds(id=account_id)
267   db[reset_password_table].where(reset_password_id_column=>id)
268 end
password_too_short_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
81 def password_too_short_message
82   "minimum #{password_minimum_length} characters"
83 end
possible_authentication_methods()
[show source]
    # File lib/rodauth/features/base.rb
465 def possible_authentication_methods
466   has_password? ? ['password'] : []
467 end
post_configure()
[show source]
    # File lib/rodauth/features/base.rb
391 def post_configure
392   require 'bcrypt' if require_bcrypt?
393   db.extension :date_arithmetic if use_date_arithmetic?
394   route_hash= {}
395   self.class.routes.each do |meth|
396     route_hash["/#{send("#{meth.to_s.sub(/\Ahandle_/, '')}_route")}"] = meth
397   end
398   self.class.route_hash = route_hash.freeze
399 end
previous_password_ds()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
94 def previous_password_ds
95   db[previous_password_hash_table].where(previous_password_account_id_column=>account_id)
96 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
708 def raises_uniqueness_violation?(&block)
709   transaction(:savepoint=>:only, &block)
710   false
711 rescue unique_constraint_violation_class => e
712   e
713 end
random_key()
[show source]
    # File lib/rodauth/features/base.rb
513 def random_key
514   SecureRandom.urlsafe_base64(32)
515 end
raw_param(key)
[show source]
    # File lib/rodauth/features/base.rb
447 def raw_param(key)
448   request.params[key]
449 end
recovery_code_match?(code)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
159 def recovery_code_match?(code)
160   recovery_codes.each do |s|
161     if timing_safe_eql?(code, s)
162       recovery_codes_ds.where(recovery_codes_column=>code).delete
163       if recovery_codes_primary?
164         add_recovery_code
165       end
166       return true
167     end
168   end
169   false
170 end
recovery_codes_ds()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
259 def recovery_codes_ds
260   db[recovery_codes_table].where(recovery_codes_id_column=>session_value)
261 end
recovery_codes_primary?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
239 def recovery_codes_primary?
240   (features & [:otp, :sms_codes, :webauthn]).empty?
241 end
recovery_codes_remove()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
155 def recovery_codes_remove
156   recovery_codes_ds.delete
157 end
redirect(path)
[show source]
    # File lib/rodauth/features/base.rb
495 def redirect(path)
496   request.redirect(path)
497 end
redirect_two_factor_authenticated()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
240 def redirect_two_factor_authenticated
241   saved_two_factor_auth_redirect = remove_session_value(two_factor_auth_redirect_session_key)
242   redirect saved_two_factor_auth_redirect || two_factor_auth_redirect
243 end
remember_key_ds(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
218 def remember_key_ds(id=account_id)
219   db[remember_table].where(remember_id_column=>id)
220 end
remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
141 def remember_login
142   get_remember_key
143   opts = Hash[remember_cookie_options]
144   opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
145   opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
146   opts[:path] = "/" unless opts.key?(:path)
147   opts[:httponly] = true unless opts.key?(:httponly)
148   opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
149   ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
150 end
remembered_session_id()
[show source]
    # File lib/rodauth/features/remember.rb
 89 def remembered_session_id
 90   return unless cookie = _get_remember_cookie
 91   id, key = cookie.split('_', 2)
 92   return unless id && key
 93 
 94   actual, deadline = active_remember_key_ds(id).get([remember_key_column, remember_deadline_column])
 95   return unless actual
 96 
 97   if hmac_secret
 98     unless valid = timing_safe_eql?(key, compute_hmac(actual))
 99       unless raw_remember_token_deadline && raw_remember_token_deadline > convert_timestamp(deadline)
100         return
101       end
102     end
103   end
104 
105   unless valid || timing_safe_eql?(key, actual)
106     return
107   end
108 
109   id
110 end
remove_all_active_sessions()
[show source]
   # File lib/rodauth/features/active_sessions.rb
87 def remove_all_active_sessions
88   active_sessions_ds.delete
89 end
remove_all_webauthn_keys_and_user_ids()
[show source]
    # File lib/rodauth/features/webauthn.rb
383 def remove_all_webauthn_keys_and_user_ids
384   webauthn_user_ids_ds.delete
385   webauthn_keys_ds.delete
386 end
remove_current_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
83 def remove_current_session
84   active_sessions_ds.where(active_sessions_session_id_column=>compute_hmac(session[session_id_session_key])).delete
85 end
remove_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
132 def remove_email_auth_key
133   email_auth_ds.delete
134 end
remove_inactive_sessions()
[show source]
   # File lib/rodauth/features/active_sessions.rb
91 def remove_inactive_sessions
92   if cond = inactive_session_cond
93     active_sessions_ds.where(cond).delete
94   end
95 end
remove_jwt_refresh_token_key(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
176 def remove_jwt_refresh_token_key(token)
177   account_id, token_id, _ = _account_refresh_token_split(token)
178   jwt_refresh_token_account_token_ds(account_id, token_id).delete
179 end
remove_lockout_metadata()
[show source]
    # File lib/rodauth/features/lockout.rb
279 def remove_lockout_metadata
280   account_login_failures_ds.delete
281   account_lockouts_ds.delete
282 end
remove_remember_key(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
184 def remove_remember_key(id=account_id)
185   remember_key_ds(id).delete
186 end
remove_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
182 def remove_reset_password_key
183   password_reset_ds.delete
184 end
remove_session_value(key)
[show source]
    # File lib/rodauth/features/base.rb
751 def remove_session_value(key)
752   session.delete(key)
753 end
remove_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
177 def remove_verify_account_key
178   verify_account_ds.delete
179 end
remove_verify_login_change_key()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
110 def remove_verify_login_change_key
111   verify_login_change_ds.delete
112 end
remove_webauthn_key(webauthn_id)
[show source]
    # File lib/rodauth/features/webauthn.rb
379 def remove_webauthn_key(webauthn_id)
380   webauthn_keys_ds.where(webauthn_keys_webauthn_id_column=>webauthn_id).delete == 1
381 end
render(page)
[show source]
    # File lib/rodauth/features/base.rb
383 def render(page)
384   _view(:render, page)
385 end
render_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/login.rb
128 def render_multi_phase_login_forms
129   multi_phase_login_forms.sort.map{|_, form, _| form}.join("\n")
130 end
request()
[show source]
    # File lib/rodauth/features/base.rb
139 def request
140   scope.request
141 end
require_account()
[show source]
    # File lib/rodauth/features/base.rb
527 def require_account
528   require_authentication
529   require_account_session
530 end
require_account_session()
[show source]
    # File lib/rodauth/features/base.rb
532 def require_account_session
533   unless account_from_session
534     clear_session
535     login_required
536   end
537 end
require_authentication()
[show source]
    # File lib/rodauth/features/base.rb
337 def require_authentication
338   require_login
339 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
27 def require_http_basic_auth
28   unless http_basic_auth
29     set_http_basic_auth_error_response
30     request.halt
31   end
32 end
require_login()
[show source]
    # File lib/rodauth/features/base.rb
329 def require_login
330   login_required unless logged_in?
331 end
require_login_confirmation?()
[show source]
    # File lib/rodauth/features/verify_account.rb
169 def require_login_confirmation?
170   false
171 end
require_otp_setup()
[show source]
    # File lib/rodauth/features/otp.rb
232 def require_otp_setup
233   unless otp_exists?
234     set_redirect_error_status(two_factor_not_setup_error_status)
235     set_error_reason :two_factor_not_setup
236     set_redirect_error_flash two_factor_not_setup_error_flash
237     redirect two_factor_need_setup_redirect
238   end
239 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_value(confirm_password_redirect_session_key, request.fullpath)
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_sms_available()
[show source]
    # File lib/rodauth/features/sms_codes.rb
329 def require_sms_available
330   require_sms_setup
331 
332   if sms_locked_out?
333     set_redirect_error_status(lockout_error_status)
334     set_error_reason :sms_locked_out
335     set_redirect_error_flash sms_lockout_error_flash
336     redirect sms_lockout_redirect
337   end
338 end
require_sms_not_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
320 def require_sms_not_setup
321   if sms_setup?
322     set_redirect_error_status(sms_already_setup_error_status)
323     set_error_reason :sms_already_setup
324     set_redirect_error_flash sms_already_setup_error_flash
325     redirect sms_already_setup_redirect
326   end
327 end
require_sms_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
311 def require_sms_setup
312   unless sms_setup?
313     set_redirect_error_status(two_factor_not_setup_error_status)
314     set_error_reason :sms_not_setup
315     set_redirect_error_flash sms_not_setup_error_flash
316     redirect sms_needs_setup_redirect
317   end
318 end
require_two_factor_authenticated()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
163 def require_two_factor_authenticated
164   unless two_factor_authenticated?
165     if two_factor_auth_return_to_requested_location?
166       set_session_value(two_factor_auth_redirect_session_key, request.fullpath)
167     end
168     set_redirect_error_status(two_factor_need_authentication_error_status)
169     set_error_reason :two_factor_need_authentication
170     set_redirect_error_flash two_factor_need_authentication_error_flash
171     redirect two_factor_auth_required_redirect
172   end
173 end
require_two_factor_not_authenticated(auth_type = nil)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
154 def require_two_factor_not_authenticated(auth_type = nil)
155   if two_factor_authenticated? || (auth_type && two_factor_login_type_match?(auth_type))
156     set_redirect_error_status(two_factor_already_authenticated_error_status)
157     set_error_reason :two_factor_already_authenticated
158     set_redirect_error_flash two_factor_already_authenticated_error_flash
159     redirect two_factor_already_authenticated_redirect
160   end
161 end
require_two_factor_setup()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
142 def require_two_factor_setup
143   # Avoid database query if already authenticated via 2nd factor
144   return if two_factor_authenticated?
145 
146   return if uses_two_factor_authentication?
147 
148   set_redirect_error_status(two_factor_not_setup_error_status)
149   set_error_reason :two_factor_not_setup
150   set_redirect_error_flash two_factor_not_setup_error_flash
151   redirect two_factor_need_setup_redirect
152 end
require_webauthn_setup()
[show source]
    # File lib/rodauth/features/webauthn.rb
392 def require_webauthn_setup
393   unless webauthn_setup?
394     set_redirect_error_status(webauthn_not_setup_error_status)
395     set_error_reason :webauthn_not_setup
396     set_redirect_error_flash webauthn_not_setup_error_flash
397     redirect two_factor_need_setup_redirect
398   end
399 end
rescue_jwt_payload(_)
[show source]
    # File lib/rodauth/features/jwt.rb
121 def rescue_jwt_payload(_)
122   @jwt_payload = false
123 end
reset_password_email_body()
[show source]
    # File lib/rodauth/features/reset_password.rb
252 def reset_password_email_body
253   render('reset-password-email')
254 end
reset_password_email_recently_sent?()
[show source]
    # File lib/rodauth/features/reset_password.rb
222 def reset_password_email_recently_sent?
223   (email_last_sent = get_reset_password_email_last_sent) && (Time.now - email_last_sent < reset_password_skip_resend_email_within)
224 end
reset_password_key_insert_hash()
[show source]
    # File lib/rodauth/features/reset_password.rb
260 def reset_password_key_insert_hash
261   hash = {reset_password_id_column=>account_id, reset_password_key_column=>reset_password_key_value}
262   set_deadline_value(hash, reset_password_deadline_column, reset_password_deadline_interval)
263   hash
264 end
reset_single_session_key()
[show source]
   # File lib/rodauth/features/single_session.rb
22 def reset_single_session_key
23   if logged_in?
24     single_session_ds.update(single_session_key_column=>random_key)
25   end
26 end
response()
[show source]
    # File lib/rodauth/features/base.rb
143 def response
144   scope.response
145 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
699 def retry_on_uniqueness_violation(&block)
700   if raises_uniqueness_violation?(&block)
701     yield
702   end
703 end
return_json_response()
[show source]
    # File lib/rodauth/features/json.rb
152 def return_json_response
153   _return_json_response
154 end
route!()
[show source]
    # File lib/rodauth/features/base.rb
155 def route!
156   if meth = self.class.route_hash[request.remaining_path]
157     send(meth)
158   end
159 
160   nil
161 end
route_path(route, opts={})
[show source]
    # File lib/rodauth/features/base.rb
499 def route_path(route, opts={})
500   path  = "#{prefix}/#{route}"
501   path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
502   path
503 end
route_url(route, opts={})
[show source]
    # File lib/rodauth/features/base.rb
505 def route_url(route, opts={})
506   "#{base_url}#{route_path(route, opts)}"
507 end
save_account()
[show source]
    # File lib/rodauth/features/create_account.rb
100 def save_account
101   id = nil
102   raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}
103 
104   if raised
105     set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
106   end
107 
108   if id
109     account[account_id_column] = id
110   end
111 
112   id && !raised
113 end
send_email(email)
[show source]
   # File lib/rodauth/features/email_base.rb
28 def send_email(email)
29   email.deliver!
30 end
send_email_auth_email()
[show source]
    # File lib/rodauth/features/email_auth.rb
140 def send_email_auth_email
141   send_email(create_email_auth_email)
142 end
send_password_changed_email()
[show source]
   # File lib/rodauth/features/change_password_notify.rb
19 def send_password_changed_email
20   send_email(create_password_changed_email)
21 end
send_reset_password_email()
[show source]
    # File lib/rodauth/features/reset_password.rb
190 def send_reset_password_email
191   send_email(create_reset_password_email)
192 end
send_unlock_account_email()
[show source]
    # File lib/rodauth/features/lockout.rb
229 def send_unlock_account_email
230   send_email(create_unlock_account_email)
231 end
send_verify_account_email()
[show source]
    # File lib/rodauth/features/verify_account.rb
216 def send_verify_account_email
217   send_email(create_verify_account_email)
218 end
send_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
126 def send_verify_login_change_email(login)
127   send_email(create_verify_login_change_email(login))
128 end
serialize_audit_log_metadata(metadata)
[show source]
   # File lib/rodauth/features/audit_logging.rb
55 def serialize_audit_log_metadata(metadata)
56   metadata.to_json unless metadata.nil?
57 end
session()
[show source]
    # File lib/rodauth/features/base.rb
147 def session
148   scope.session
149 end
session_inactivity_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
147 def session_inactivity_deadline_condition
148   if deadline = session_inactivity_deadline
149     Sequel[active_sessions_last_use_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
150   end
151 end
session_jwt()
[show source]
   # File lib/rodauth/features/jwt.rb
75 def session_jwt
76   JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
77 end
session_lifetime_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
153 def session_lifetime_deadline_condition
154   if deadline = session_lifetime_deadline
155     Sequel[active_sessions_created_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
156   end
157 end
session_value()
[show source]
    # File lib/rodauth/features/base.rb
247 def session_value
248   session[session_key]
249 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
735 def set_deadline_value(hash, column, interval)
736   if set_deadline_values?
737     # :nocov:
738     hash[column] = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, interval)
739     # :nocov:
740   end
741 end
set_deadline_values?()
[show source]
    # File lib/rodauth/features/base.rb
578 def set_deadline_values?
579   db.database_type == :mysql
580 end
set_email_auth_email_last_sent()
[show source]
    # File lib/rodauth/features/email_auth.rb
120 def set_email_auth_email_last_sent
121    email_auth_ds.update(email_auth_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if email_auth_email_last_sent_column
122 end
set_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
313 def set_error_flash(message)
314   flash.now[flash_error_key] = message
315 end
set_error_reason(reason)
[show source]
    # File lib/rodauth/features/base.rb
566 def set_error_reason(reason)
567 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
163 def set_field_error(field, error)
164   (@field_errors ||= {})[field] = error
165 end
set_http_basic_auth_error_response()
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
74 def set_http_basic_auth_error_response
75   response.status = 401
76   response.headers["WWW-Authenticate"] = "Basic realm=\"#{http_basic_auth_realm}\""
77 end
set_jwt()
[show source]
    # File lib/rodauth/features/jwt.rb
142 def set_jwt
143   set_jwt_token(session_jwt)
144 end
set_jwt_refresh_token_hmac_session_key(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
192 def set_jwt_refresh_token_hmac_session_key(token)
193   if allow_refresh_with_expired_jwt_access_token?
194     key = _account_refresh_token_split(token).last
195     data = random_key
196     set_session_value(jwt_refresh_token_data_session_key, data)
197     set_session_value(jwt_refresh_token_hmac_session_key, compute_hmac(data + key))
198   end
199 end
set_jwt_token(token)
[show source]
   # File lib/rodauth/features/jwt.rb
87 def set_jwt_token(token)
88   response.headers['Authorization'] = token
89 end
set_last_password_entry()
[show source]
   # File lib/rodauth/features/password_grace_period.rb
44 def set_last_password_entry
45   set_session_value(last_password_entry_session_key, Time.now.to_i)
46 end
set_login_requirement_error_message(reason, message)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
102 def set_login_requirement_error_message(reason, message)
103   set_error_reason(reason)
104   @login_requirement_message = message
105 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
321 def set_notice_flash(message)
322   flash[flash_notice_key] = message
323 end
set_notice_now_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
325 def set_notice_now_flash(message)
326   flash.now[flash_notice_key] = message
327 end
set_password(password)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
19 def set_password(password)
20   hash = super
21   add_previous_password_hash(hash)
22   hash
23 end
set_password_requirement_error_message(reason, message)
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
85 def set_password_requirement_error_message(reason, message)
86   set_error_reason(reason)
87   @password_requirement_message = message
88 end
set_redirect_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
317 def set_redirect_error_flash(message)
318   flash[flash_error_key] = message
319 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
544 def set_redirect_error_status(status)
545 end
set_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
204 def set_reset_password_email_last_sent
205    password_reset_ds.update(reset_password_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if reset_password_email_last_sent_column
206 end
set_response_error_reason_status(reason, status)
[show source]
    # File lib/rodauth/features/base.rb
551 def set_response_error_reason_status(reason, status)
552   set_error_reason(reason)
553   set_response_error_status(status)
554 end
set_response_error_status(status)
[show source]
    # File lib/rodauth/features/base.rb
547 def set_response_error_status(status)
548   response.status = status
549 end
set_session_value(key, value)
[show source]
    # File lib/rodauth/features/base.rb
747 def set_session_value(key, value)
748   session[key] = value
749 end
set_single_session_key(data)
[show source]
   # File lib/rodauth/features/single_session.rb
93 def set_single_session_key(data)
94   data = compute_hmac(data) if hmac_secret
95   set_session_value(single_session_session_key, data)
96 end
set_title(title)
[show source]
    # File lib/rodauth/features/base.rb
307 def set_title(title)
308   if title_instance_variable
309     scope.instance_variable_set(title_instance_variable, title)
310   end
311 end
set_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
245 def set_unlock_account_email_last_sent
246   account_lockouts_ds.update(account_lockouts_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if account_lockouts_email_last_sent_column
247 end
set_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
241 def set_verify_account_email_last_sent
242    verify_account_ds.update(verify_account_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if verify_account_email_last_sent_column
243 end
setup_account_verification()
[show source]
    # File lib/rodauth/features/verify_account.rb
253 def setup_account_verification
254   generate_verify_account_key_value
255   create_verify_account_key
256   send_verify_account_email
257 end
show_lockout_page()
[show source]
    # File lib/rodauth/features/lockout.rb
284 def show_lockout_page
285   set_response_error_reason_status(:account_locked_out, lockout_error_status)
286   set_error_flash login_lockout_error_flash
287   response.write unlock_account_request_view
288   request.halt
289 end
single_session_ds()
[show source]
    # File lib/rodauth/features/single_session.rb
 98 def single_session_ds
 99   db[single_session_table].
100     where(single_session_id_column=>session_value)
101 end
skip_login_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
110 def skip_login_field_on_login?
111   return false unless use_multi_phase_login?
112   valid_login_entered?
113 end
skip_password_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
115 def skip_password_field_on_login?
116   return false unless use_multi_phase_login?
117   !valid_login_entered?
118 end
skip_status_checks?()
[show source]
   # File lib/rodauth/features/close_account.rb
84 def skip_status_checks?
85   false
86 end
sms_auth_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
390 def sms_auth_message(code)
391   "SMS authentication code for #{domain} is #{code}"
392 end
sms_available?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
432 def sms_available?
433   sms && !sms_needs_confirmation? && !sms_locked_out?
434 end
sms_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
411 def sms_code
412   sms[sms_code_column]
413 end
sms_code_issued_at()
[show source]
    # File lib/rodauth/features/sms_codes.rb
415 def sms_code_issued_at
416   convert_timestamp(sms[sms_issued_at_column])
417 end
sms_code_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
340 def sms_code_match?(code)
341   return false unless sms_current_auth?
342   timing_safe_eql?(code, sms_code)
343 end
sms_codes_primary?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
475 def sms_codes_primary?
476   (features & [:otp, :webauthn]).empty?
477 end
sms_confirm()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
145 def sms_confirm
146   super if defined?(super)
147   auto_add_missing_recovery_codes
148 end
sms_confirm_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
354 def sms_confirm_failure
355   sms_ds.delete
356 end
sms_confirm_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
394 def sms_confirm_message(code)
395   "SMS confirmation code for #{domain} is #{code}"
396 end
sms_confirmation_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
345 def sms_confirmation_match?(code)
346   sms_needs_confirmation? && sms_code_match?(code)
347 end
sms_current_auth?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
440 def sms_current_auth?
441   sms_code && sms_code_issued_at + sms_code_allowed_seconds > Time.now
442 end
sms_disable()
[show source]
    # File lib/rodauth/features/sms_codes.rb
349 def sms_disable
350   sms_ds.delete
351   @sms = nil
352 end
sms_ds()
[show source]
    # File lib/rodauth/features/sms_codes.rb
503 def sms_ds
504   db[sms_codes_table].where(sms_id_column=>session_value)
505 end
sms_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
419 def sms_failures
420   sms[sms_failures_column]
421 end
sms_locked_out?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
436 def sms_locked_out?
437   sms_failures >= sms_failure_limit
438 end
sms_needs_confirmation?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
428 def sms_needs_confirmation?
429   sms && sms_failures.nil?
430 end
sms_new_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
483 def sms_new_auth_code
484   SecureRandom.random_number(10**sms_auth_code_length).to_s.rjust(sms_auth_code_length, "0")
485 end
sms_new_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
487 def sms_new_confirm_code
488   SecureRandom.random_number(10**sms_confirm_code_length).to_s.rjust(sms_confirm_code_length, "0")
489 end
sms_normalize_phone(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
479 def sms_normalize_phone(phone)
480   phone.to_s.gsub(/\D+/, '')
481 end
sms_phone()
[show source]
    # File lib/rodauth/features/sms_codes.rb
407 def sms_phone
408   sms[sms_phone_column]
409 end
sms_record_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
402 def sms_record_failure
403   update_sms(sms_failures_column=>Sequel.expr(sms_failures_column)+1)
404   sms[sms_failures_column] = sms_ds.get(sms_failures_column)
405 end
sms_remove_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
365 def sms_remove_failures
366   update_sms(sms_failures_column => 0, sms_code_column => nil)
367 end
sms_send(phone, message)
[show source]
    # File lib/rodauth/features/sms_codes.rb
491 def sms_send(phone, message)
492   raise NotImplementedError, "sms_send needs to be defined in the Rodauth configuration for SMS sending to work"
493 end
sms_send_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
374 def sms_send_auth_code
375   code = sms_new_auth_code
376   sms_set_code(code)
377   sms_send(sms_phone, sms_auth_message(code))
378 end
sms_send_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
380 def sms_send_confirm_code
381   code = sms_new_confirm_code
382   sms_set_code(code)
383   sms_send(sms_phone, sms_confirm_message(code))
384 end
sms_set_code(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
398 def sms_set_code(code)
399  update_sms(sms_code_column=>code, sms_issued_at_column=>Sequel::CURRENT_TIMESTAMP)
400 end
sms_setup(phone_number)
[show source]
    # File lib/rodauth/features/sms_codes.rb
358 def sms_setup(phone_number)
359   # Cannot handle uniqueness violation here, as the phone number given may not match the
360   # one in the table.
361   sms_ds.insert(sms_id_column=>session_value, sms_phone_column=>phone_number)
362   remove_instance_variable(:@sms) if instance_variable_defined?(:@sms)
363 end
sms_setup?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
423 def sms_setup?
424   return false unless sms
425   !sms_needs_confirmation?
426 end
sms_valid_phone?(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
386 def sms_valid_phone?(phone)
387   phone.length >= sms_phone_min_length
388 end
split_token(token)
[show source]
    # File lib/rodauth/features/base.rb
491 def split_token(token)
492   token.split(token_separator, 2)
493 end
template_path(page)
[show source]
    # File lib/rodauth/features/base.rb
668 def template_path(page)
669   File.join(File.dirname(__FILE__), '../../../templates', "#{page}.str")
670 end
throw_basic_auth_error(*args)
[show source]
   # File lib/rodauth/features/http_basic_auth.rb
79 def throw_basic_auth_error(*args)
80   set_http_basic_auth_error_response
81   throw_error(*args) 
82 end
throw_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
556 def throw_error(field, error)
557   set_field_error(field, error)
558   throw :rodauth_error
559 end
throw_error_reason(reason, status, field, message)
[show source]
    # File lib/rodauth/features/base.rb
569 def throw_error_reason(reason, status, field, message)
570   set_error_reason(reason)
571   throw_error_status(status, field, message)
572 end
throw_error_status(status, field, error)
[show source]
    # File lib/rodauth/features/base.rb
561 def throw_error_status(status, field, error)
562   set_response_error_status(status)
563   throw_error(field, error)
564 end
timing_safe_eql?(provided, actual)
[show source]
    # File lib/rodauth/features/base.rb
522 def timing_safe_eql?(provided, actual)
523   provided = provided.to_s
524   Rack::Utils.secure_compare(provided.ljust(actual.length), actual) && provided.length == actual.length
525 end
token_param_value(key)
[show source]
   # File lib/rodauth/features/email_base.rb
57 def token_param_value(key)
58   "#{account_id}#{token_separator}#{convert_email_token_key(key)}"
59 end
transaction(opts={}, &block)
[show source]
    # File lib/rodauth/features/base.rb
509 def transaction(opts={}, &block)
510   db.transaction(opts, &block)
511 end
translate(_key, default)
[show source]
    # File lib/rodauth/features/base.rb
230 def translate(_key, default)
231   # do not attempt to translate by default
232   default
233 end
two_factor_authenticate(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
232 def two_factor_authenticate(type)
233   two_factor_update_session(type)
234   two_factor_remove_auth_failures
235   after_two_factor_authentication
236   set_notice_flash two_factor_auth_notice_flash
237   redirect_two_factor_authenticated
238 end
two_factor_authenticated?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
187 def two_factor_authenticated?
188   authenticated_by && authenticated_by.length >= 2
189 end
two_factor_authentication_setup?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
191 def two_factor_authentication_setup?
192   possible_authentication_methods.length >= 2
193 end
two_factor_login_type_match?(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
201 def two_factor_login_type_match?(type)
202   authenticated_by && authenticated_by.include?(type)
203 end
two_factor_modifications_require_password?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
118 def two_factor_modifications_require_password?
119   modifications_require_password?
120 end
two_factor_password_match?(password)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
179 def two_factor_password_match?(password)
180   if two_factor_modifications_require_password?
181     password_match?(password)
182   else
183     true
184   end
185 end
two_factor_remove()
[show source]
    # File lib/rodauth/features/otp.rb
222 def two_factor_remove
223   super
224   otp_remove
225 end
two_factor_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
227 def two_factor_remove_auth_failures
228   super
229   otp_remove_auth_failures
230 end
two_factor_remove_session(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
245 def two_factor_remove_session(type)
246   authenticated_by.delete(type)
247   remove_session_value(two_factor_setup_session_key)
248   if authenticated_by.empty?
249     clear_session
250   end
251 end
two_factor_update_session(auth_type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
253 def two_factor_update_session(auth_type)
254   authenticated_by << auth_type
255   set_session_value(two_factor_setup_session_key, true)
256 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
717 def unique_constraint_violation_class
718   if db.adapter_scheme == :jdbc && db.database_type == :sqlite
719     # :nocov:
720     Sequel::ConstraintViolation
721     # :nocov:
722   else
723     Sequel::UniqueConstraintViolation
724   end
725 end
unlock_account()
[show source]
    # File lib/rodauth/features/lockout.rb
164 def unlock_account
165   transaction do
166     remove_lockout_metadata
167   end
168 end
unlock_account_email_body()
[show source]
    # File lib/rodauth/features/lockout.rb
295 def unlock_account_email_body
296   render('unlock-account-email')
297 end
unlock_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/lockout.rb
299 def unlock_account_email_recently_sent?
300   (email_last_sent = get_unlock_account_email_last_sent) && (Time.now - email_last_sent < unlock_account_skip_resend_email_within)
301 end
update_account(values, ds=account_ds)
[show source]
    # File lib/rodauth/features/base.rb
765 def update_account(values, ds=account_ds)
766   update_hash_ds(account, ds, values)
767 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
166 def update_current_session?
167   !!session_inactivity_deadline
168 end
update_hash_ds(hash, ds, values)
[show source]
    # File lib/rodauth/features/base.rb
755 def update_hash_ds(hash, ds, values)
756   num = ds.update(values)
757   if num == 1
758     values.each do |k, v|
759       account[k] = v == Sequel::CURRENT_TIMESTAMP ? Time.now : v
760     end
761   end
762   num
763 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
17 def update_password_hash?
18   password_hash_cost != @current_password_hash_cost
19 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
65 def update_single_session_key
66   key = random_key
67   set_single_session_key(key)
68   if single_session_ds.update(single_session_key_column=>key) == 0
69     # Don't handle uniqueness violations here.  While we could get the stored key from the
70     # database, it could lead to two sessions sharing the same key, which this feature is
71     # designed to prevent.
72     single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key)
73   end
74 end
update_sms(values)
[show source]
    # File lib/rodauth/features/sms_codes.rb
495 def update_sms(values)
496   update_hash_ds(sms, sms_ds, values)
497 end
use_database_authentication_functions?()
[show source]
    # File lib/rodauth/features/base.rb
582 def use_database_authentication_functions?
583   case db.database_type
584   when :postgres, :mysql, :mssql
585     true
586   else
587     # :nocov:
588     false
589     # :nocov:
590   end
591 end
use_date_arithmetic?()
[show source]
    # File lib/rodauth/features/active_sessions.rb
175 def use_date_arithmetic?
176   true
177 end
use_json?()
[show source]
   # File lib/rodauth/features/json.rb
59 def use_json?
60   json_request? || only_json?
61 end
use_jwt?()
[show source]
   # File lib/rodauth/features/jwt.rb
91 def use_jwt?
92   use_json?
93 end
use_multi_phase_login?()
[show source]
    # File lib/rodauth/features/email_auth.rb
165 def use_multi_phase_login?
166   true
167 end
use_request_specific_csrf_tokens?()
[show source]
    # File lib/rodauth/features/base.rb
593 def use_request_specific_csrf_tokens?
594   scope.opts[:rodauth_route_csrf] && scope.use_request_specific_csrf_tokens?
595 end
uses_two_factor_authentication?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
195 def uses_two_factor_authentication?
196   return false unless logged_in?
197   set_session_value(two_factor_setup_session_key, two_factor_authentication_setup?) unless session.has_key?(two_factor_setup_session_key)
198   session[two_factor_setup_session_key]
199 end
valid_jwt?()
[show source]
    # File lib/rodauth/features/jwt.rb
 99 def valid_jwt?
100   !!(jwt_token && jwt_payload)
101 end
valid_login_entered?()
[show source]
    # File lib/rodauth/features/login.rb
120 def valid_login_entered?
121   @valid_login_entered
122 end
valid_new_webauthn_credential?(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
305 def valid_new_webauthn_credential?(webauthn_credential)
306   # Hack around inability to override expected_origin
307   origin = webauthn_origin
308   webauthn_credential.response.define_singleton_method(:verify) do |expected_challenge, expected_origin = nil, **kw|
309     super(expected_challenge, expected_origin || origin, **kw)
310   end
311 
312   (challenge = param_or_nil(webauthn_setup_challenge_param)) &&
313     (hmac = param_or_nil(webauthn_setup_challenge_hmac_param)) &&
314     timing_safe_eql?(compute_hmac(challenge), hmac) &&
315     webauthn_credential.verify(challenge)
316 end
valid_webauthn_credential_auth?(webauthn_credential)
[show source]
    # File lib/rodauth/features/webauthn.rb
359 def valid_webauthn_credential_auth?(webauthn_credential)
360   ds = webauthn_keys_ds.where(webauthn_keys_webauthn_id_column => webauthn_credential.id)
361   pub_key, sign_count = ds.get([webauthn_keys_public_key_column, webauthn_keys_sign_count_column])
362 
363   # Hack around inability to override expected_origin
364   origin = webauthn_origin
365   webauthn_credential.response.define_singleton_method(:verify) do |expected_challenge, expected_origin = nil, **kw|
366     super(expected_challenge, expected_origin || origin, **kw)
367   end
368 
369   (challenge = param_or_nil(webauthn_auth_challenge_param)) &&
370     (hmac = param_or_nil(webauthn_auth_challenge_hmac_param)) &&
371     timing_safe_eql?(compute_hmac(challenge), hmac) &&
372     webauthn_credential.verify(challenge, public_key: pub_key, sign_count: sign_count) &&
373     ds.update(
374       webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count),
375       webauthn_keys_last_use_column => Sequel::CURRENT_TIMESTAMP
376     ) == 1
377 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
181 def verify_account
182   update_account(account_status_column=>account_open_status_value) == 1
183 end
verify_account_check_already_logged_in()
[show source]
    # File lib/rodauth/features/verify_account.rb
291 def verify_account_check_already_logged_in
292   check_already_logged_in
293 end
verify_account_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_account.rb
324 def verify_account_ds(id=account_id)
325   db[verify_account_table].where(verify_account_id_column=>id)
326 end
verify_account_email_body()
[show source]
    # File lib/rodauth/features/verify_account.rb
320 def verify_account_email_body
321   render('verify-account-email')
322 end
verify_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/verify_account.rb
269 def verify_account_email_recently_sent?
270   (email_last_sent = get_verify_account_email_last_sent) && (Time.now - email_last_sent < verify_account_skip_resend_email_within)
271 end
verify_account_email_resend()
[show source]
    # File lib/rodauth/features/verify_account.rb
185 def verify_account_email_resend
186   if @verify_account_key_value = get_verify_account_key(account_id)
187     set_verify_account_email_last_sent
188     send_verify_account_email
189     true
190   end
191 end
verify_account_key_insert_hash()
[show source]
    # File lib/rodauth/features/verify_account.rb
312 def verify_account_key_insert_hash
313   {verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
314 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
7 def verify_account_view
8   webauthn_setup_view
9 end
verify_login_change()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
114 def verify_login_change
115   unless res = _update_login(verify_login_change_new_login)
116     remove_verify_login_change_key
117   end
118 
119   res
120 end
verify_login_change_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
208 def verify_login_change_ds(id=account_id)
209   db[verify_login_change_table].where(verify_login_change_id_column=>id)
210 end
verify_login_change_email_body()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
204 def verify_login_change_email_body
205   render('verify-login-change-email')
206 end
verify_login_change_key_insert_hash(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
194 def verify_login_change_key_insert_hash(login)
195   hash = {verify_login_change_id_column=>account_id, verify_login_change_key_column=>verify_login_change_key_value, verify_login_change_login_column=>login}
196   set_deadline_value(hash, verify_login_change_deadline_column, verify_login_change_deadline_interval)
197   hash
198 end
verify_login_change_old_login()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
142 def verify_login_change_old_login
143   account_ds.get(login_column)
144 end
view(page, title)
[show source]
    # File lib/rodauth/features/base.rb
378 def view(page, title)
379   set_title(title)
380   _view(:view, page)
381 end
webauth_credential_options_for_get()
[show source]
    # File lib/rodauth/features/webauthn.rb
318 def webauth_credential_options_for_get
319   WebAuthn::Credential.options_for_get(
320     :allow => account_webauthn_ids,
321     :timeout => webauthn_auth_timeout,
322     :rp_id => webauthn_rp_id,
323     :user_verification => webauthn_user_verification,
324     :extensions => webauthn_extensions,
325   )
326 end
webauthn_account_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
436 def webauthn_account_id
437   session_value
438 end
webauthn_auth_additional_form_tags()
[show source]
   # File lib/rodauth/features/webauthn_login.rb
35 def webauthn_auth_additional_form_tags
36   if @webauthn_login
37     super.to_s + login_hidden_field
38   else
39     super
40   end
41 end
webauthn_auth_credential_from_form_submission()
[show source]
    # File lib/rodauth/features/webauthn.rb
448 def webauthn_auth_credential_from_form_submission
449   case auth_data = raw_param(webauthn_auth_param)
450   when String
451     begin
452       auth_data = JSON.parse(auth_data)
453     rescue
454       throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
455     end
456   when Hash
457     # nothing
458   else
459     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
460   end
461 
462   begin
463     webauthn_credential = WebAuthn::Credential.from_get(auth_data)
464     unless valid_webauthn_credential_auth?(webauthn_credential)
465       throw_error_reason(:invalid_webauthn_auth_param, invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
466     end
467   rescue WebAuthn::SignCountVerificationError
468     handle_webauthn_sign_count_verification_error
469   rescue WebAuthn::Error, RuntimeError, NoMethodError
470     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
471   end
472 
473   webauthn_credential
474 end
webauthn_auth_form_path()
[show source]
    # File lib/rodauth/features/webauthn.rb
238 def webauthn_auth_form_path
239   webauthn_auth_path
240 end
webauthn_authenticator_selection()
[show source]
    # File lib/rodauth/features/webauthn.rb
254 def webauthn_authenticator_selection
255   {'requireResidentKey' => false, 'userVerification' => webauthn_user_verification}
256 end
webauthn_extensions()
[show source]
    # File lib/rodauth/features/webauthn.rb
258 def webauthn_extensions
259   {}
260 end
webauthn_keys_ds()
[show source]
    # File lib/rodauth/features/webauthn.rb
444 def webauthn_keys_ds
445   db[webauthn_keys_table].where(webauthn_keys_account_id_column => webauthn_account_id)
446 end
webauthn_origin()
[show source]
    # File lib/rodauth/features/webauthn.rb
332 def webauthn_origin
333   base_url
334 end
webauthn_remove_authenticated_session()
[show source]
    # File lib/rodauth/features/webauthn.rb
246 def webauthn_remove_authenticated_session
247   remove_session_value(authenticated_webauthn_id_session_key)
248 end
webauthn_rp_id()
[show source]
    # File lib/rodauth/features/webauthn.rb
336 def webauthn_rp_id
337   webauthn_origin.sub(/\Ahttps?:\/\//, '')
338 end
webauthn_rp_name()
[show source]
    # File lib/rodauth/features/webauthn.rb
340 def webauthn_rp_name
341   webauthn_rp_id
342 end
webauthn_setup?()
[show source]
    # File lib/rodauth/features/webauthn.rb
388 def webauthn_setup?
389   !webauthn_keys_ds.empty?
390 end
webauthn_setup_credential_from_form_submission()
[show source]
    # File lib/rodauth/features/webauthn.rb
476 def webauthn_setup_credential_from_form_submission
477   case setup_data = raw_param(webauthn_setup_param)
478   when String
479     begin
480       setup_data = JSON.parse(setup_data)
481     rescue
482       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
483     end
484   when Hash
485     # nothing
486   else
487     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
488   end
489 
490   unless two_factor_password_match?(param(password_param))
491     throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
492   end
493 
494   begin
495     webauthn_credential = WebAuthn::Credential.from_create(setup_data)
496     unless valid_new_webauthn_credential?(webauthn_credential)
497       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
498     end
499   rescue WebAuthn::Error, RuntimeError, NoMethodError
500     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
501   end
502 
503   webauthn_credential
504 end
webauthn_update_session(webauthn_id)
[show source]
    # File lib/rodauth/features/webauthn.rb
250 def webauthn_update_session(webauthn_id)
251   set_session_value(authenticated_webauthn_id_session_key, webauthn_id)
252 end
webauthn_user_ids_ds()
[show source]
    # File lib/rodauth/features/webauthn.rb
440 def webauthn_user_ids_ds
441   db[webauthn_user_ids_table].where(webauthn_user_ids_account_id_column => webauthn_account_id)
442 end
webauthn_user_name()
[show source]
    # File lib/rodauth/features/webauthn.rb
328 def webauthn_user_name
329   (account || account_from_session)[login_column]
330 end