module Rodauth

  1. lib/rodauth.rb
  2. lib/rodauth/features/account_expiration.rb
  3. lib/rodauth/features/active_sessions.rb
  4. lib/rodauth/features/audit_logging.rb
  5. lib/rodauth/features/base.rb
  6. lib/rodauth/features/change_login.rb
  7. lib/rodauth/features/change_password.rb
  8. lib/rodauth/features/change_password_notify.rb
  9. lib/rodauth/features/close_account.rb
  10. lib/rodauth/features/confirm_password.rb
  11. lib/rodauth/features/create_account.rb
  12. lib/rodauth/features/disallow_common_passwords.rb
  13. lib/rodauth/features/disallow_password_reuse.rb
  14. lib/rodauth/features/email_auth.rb
  15. lib/rodauth/features/email_base.rb
  16. lib/rodauth/features/http_basic_auth.rb
  17. lib/rodauth/features/jwt.rb
  18. lib/rodauth/features/jwt_cors.rb
  19. lib/rodauth/features/jwt_refresh.rb
  20. lib/rodauth/features/lockout.rb
  21. lib/rodauth/features/login.rb
  22. lib/rodauth/features/login_password_requirements_base.rb
  23. lib/rodauth/features/logout.rb
  24. lib/rodauth/features/otp.rb
  25. lib/rodauth/features/password_complexity.rb
  26. lib/rodauth/features/password_expiration.rb
  27. lib/rodauth/features/password_grace_period.rb
  28. lib/rodauth/features/recovery_codes.rb
  29. lib/rodauth/features/remember.rb
  30. lib/rodauth/features/reset_password.rb
  31. lib/rodauth/features/session_expiration.rb
  32. lib/rodauth/features/single_session.rb
  33. lib/rodauth/features/sms_codes.rb
  34. lib/rodauth/features/two_factor_base.rb
  35. lib/rodauth/features/update_password_hash.rb
  36. lib/rodauth/features/verify_account.rb
  37. lib/rodauth/features/verify_account_grace_period.rb
  38. lib/rodauth/features/verify_login_change.rb
  39. lib/rodauth/features/webauthn.rb
  40. lib/rodauth/features/webauthn_login.rb
  41. lib/rodauth/features/webauthn_verify_account.rb
  42. lib/rodauth/migrations.rb
  43. lib/rodauth/version.rb
  44. show all

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

Constants

FEATURES = {}  
MAJOR = 2  

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

MINOR = 3  

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
33 def self.configure(app, opts={}, &block)
34   json_opt = app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
35   csrf = app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_csrf])
36   app.opts[:rodauth_route_csrf] = case csrf
37   when false, :rack_csrf
38     false
39   else
40     json_opt != :only
41   end
42   auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= Class.new(Auth)
43   if !auth_class.roda_class
44     auth_class.roda_class = app
45   elsif auth_class.roda_class != app
46     auth_class = app.opts[:rodauths][opts[:name]] = Class.new(auth_class)
47     auth_class.roda_class = app
48   end
49   auth_class.configure(&block)
50 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 
  9     case db.database_type
 10     when :postgres
 11       search_path = opts[:search_path] || 'public, pg_temp'
 12       primary_key_type =
 13         case db.schema(table_name).find { |row| row.first == :id }[1][:db_type]
 14         when 'uuid' then :uuid
 15         else :int8
 16         end
 17 
 18       db.run <<END
 19 CREATE OR REPLACE FUNCTION #{get_salt_name}(acct_id #{primary_key_type}) RETURNS text AS $$
 20 DECLARE salt text;
 21 BEGIN
 22 SELECT substr(password_hash, 0, 30) INTO salt 
 23 FROM #{table_name}
 24 WHERE acct_id = id;
 25 RETURN salt;
 26 END;
 27 $$ LANGUAGE plpgsql
 28 SECURITY DEFINER
 29 SET search_path = #{search_path};
 30 END
 31 
 32       db.run <<END
 33 CREATE OR REPLACE FUNCTION #{valid_hash_name}(acct_id #{primary_key_type}, hash text) RETURNS boolean AS $$
 34 DECLARE valid boolean;
 35 BEGIN
 36 SELECT password_hash = hash INTO valid 
 37 FROM #{table_name}
 38 WHERE acct_id = id;
 39 RETURN valid;
 40 END;
 41 $$ LANGUAGE plpgsql
 42 SECURITY DEFINER
 43 SET search_path = #{search_path};
 44 END
 45     when :mysql
 46       db.run <<END
 47 CREATE FUNCTION #{get_salt_name}(acct_id int8) RETURNS varchar(255)
 48 SQL SECURITY DEFINER
 49 READS SQL DATA
 50 BEGIN
 51 RETURN (SELECT substr(password_hash, 1, 30)
 52 FROM #{table_name}
 53 WHERE acct_id = id);
 54 END;
 55 END
 56 
 57       db.run <<END
 58 CREATE FUNCTION #{valid_hash_name}(acct_id int8, hash varchar(255)) RETURNS tinyint(1)
 59 SQL SECURITY DEFINER
 60 READS SQL DATA
 61 BEGIN
 62 DECLARE valid tinyint(1);
 63 DECLARE csr CURSOR FOR 
 64 SELECT password_hash = hash
 65 FROM #{table_name}
 66 WHERE acct_id = id;
 67 OPEN csr;
 68 FETCH csr INTO valid;
 69 CLOSE csr;
 70 RETURN valid;
 71 END;
 72 END
 73     when :mssql
 74       db.run <<END
 75 CREATE FUNCTION #{get_salt_name}(@account_id bigint) RETURNS nvarchar(255)
 76 WITH EXECUTE AS OWNER
 77 AS
 78 BEGIN
 79 DECLARE @salt nvarchar(255);
 80 SELECT @salt = substring(password_hash, 0, 30)
 81 FROM #{table_name}
 82 WHERE id = @account_id;
 83 RETURN @salt;
 84 END;
 85 END
 86 
 87       db.run <<END
 88 CREATE FUNCTION #{valid_hash_name}(@account_id bigint, @hash nvarchar(255)) RETURNS bit
 89 WITH EXECUTE AS OWNER
 90 AS
 91 BEGIN
 92 DECLARE @valid bit;
 93 DECLARE @ph nvarchar(255);
 94 SELECT @ph = password_hash
 95 FROM #{table_name}
 96 WHERE id = @account_id;
 97 IF(@hash = @ph)
 98   SET @valid = 1;
 99 ELSE
100   SET @valid = 0
101 RETURN @valid;
102 END;
103 END
104     end
105   end
create_database_previous_password_check_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
127 def self.create_database_previous_password_check_functions(db, opts={})
128   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))
129 end
drop_database_authentication_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
107 def self.drop_database_authentication_functions(db, opts={})
108   table_name = opts[:table_name] || :account_password_hashes
109   get_salt_name = opts[:get_salt_name] || :rodauth_get_salt
110   valid_hash_name = opts[:valid_hash_name] || :rodauth_valid_password_hash 
111 
112   case db.database_type
113   when :postgres
114     primary_key_type =
115       case db.schema(table_name).find { |row| row.first == :id }[1][:db_type]
116       when 'uuid' then :uuid
117       else :int8
118       end
119     db.run "DROP FUNCTION #{get_salt_name}(#{primary_key_type})"
120     db.run "DROP FUNCTION #{valid_hash_name}(#{primary_key_type}, text)"
121   when :mysql, :mssql
122     db.run "DROP FUNCTION #{get_salt_name}"
123     db.run "DROP FUNCTION #{valid_hash_name}"
124   end
125 end
drop_database_previous_password_check_functions(db, opts={})
[show source]
    # File lib/rodauth/migrations.rb
131 def self.drop_database_previous_password_check_functions(db, opts={})
132   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))
133 end
load_dependencies(app, opts={})
[show source]
   # File lib/rodauth.rb
 6 def self.load_dependencies(app, opts={})
 7   json_opt = opts.fetch(:json, app.opts[:rodauth_json])
 8   if json_opt
 9     app.plugin :json
10     app.plugin :json_parser
11   end
12 
13   unless json_opt == :only
14     require 'tilt/string'
15     app.plugin :render
16 
17     case opts.fetch(:csrf, app.opts[:rodauth_csrf])
18     when false
19       # nothing
20     when :rack_csrf
21       # :nocov:
22       app.plugin :csrf
23       # :nocov:
24     else
25       app.plugin :route_csrf
26     end
27 
28     app.plugin :flash unless opts[:flash] == false
29     app.plugin :h
30   end
31 end
new(scope)
[show source]
    # File lib/rodauth/features/base.rb
125 def initialize(scope)
126   @scope = scope
127 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
252 def _account_from_email_auth_key(token)
253   account_from_key(token, account_open_status_value){|id| get_email_auth_key(id)}
254 end
_account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
595 def _account_from_login(login)
596   ds = db[accounts_table].where(login_column=>login)
597   ds = ds.select(*account_select) if account_select
598   ds = ds.where(account_status_column=>[account_unverified_status_value, account_open_status_value]) unless skip_status_checks?
599   ds.first
600 end
_account_from_refresh_token(token)
[show source]
   # File lib/rodauth/features/jwt_refresh.rb
88 def _account_from_refresh_token(token)
89   id, token_id, key = _account_refresh_token_split(token)
90 
91   return unless key
92   return unless actual = get_active_refresh_token(id, token_id)
93   return unless timing_safe_eql?(key, convert_token_key(actual))
94 
95   ds = account_ds(id)
96   ds = ds.where(account_status_column=>account_open_status_value) unless skip_status_checks?
97   ds.first
98 end
_account_from_reset_password_key(token)
[show source]
    # File lib/rodauth/features/reset_password.rb
265 def _account_from_reset_password_key(token)
266   account_from_key(token, account_open_status_value){|id| get_password_reset_key(id)}
267 end
_account_from_session()
[show source]
    # File lib/rodauth/features/base.rb
602 def _account_from_session
603   ds = account_ds(session_value)
604   ds = ds.where(account_session_status_filter) unless skip_status_checks?
605   ds.first
606 end
_account_from_unlock_key(token)
[show source]
    # File lib/rodauth/features/lockout.rb
304 def _account_from_unlock_key(token)
305   account_from_key(token){|id| account_lockouts_ds(id).get(account_lockouts_key_column)}
306 end
_account_from_verify_account_key(token)
[show source]
    # File lib/rodauth/features/verify_account.rb
322 def _account_from_verify_account_key(token)
323   account_from_key(token, account_unverified_status_value){|id| get_verify_account_key(id)}
324 end
_account_from_verify_login_change_key(token)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
207 def _account_from_verify_login_change_key(token)
208   account_from_key(token) do |id|
209     @verify_login_change_new_login, key = get_verify_login_change_login_and_key(id)
210     key
211   end
212 end
_account_refresh_token_split(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
100 def _account_refresh_token_split(token)
101   id, token = split_token(token)
102   return unless id && token
103 
104   token_id, key = split_token(token)
105   return unless token_id && key
106 
107   [id, token_id, key]
108 end
_email_auth_request()
[show source]
    # File lib/rodauth/features/email_auth.rb
186 def _email_auth_request
187   if email_auth_email_recently_sent?
188     set_redirect_error_flash email_auth_email_recently_sent_error_flash
189     redirect email_auth_email_recently_sent_redirect
190   end
191 
192   generate_email_auth_key_value
193   transaction do
194     before_email_auth_request
195     create_email_auth_key
196     send_email_auth_email
197     after_email_auth_request
198   end
199 
200   set_notice_flash email_auth_email_sent_notice_flash
201 end
_email_auth_request_and_redirect()
[show source]
    # File lib/rodauth/features/email_auth.rb
181 def _email_auth_request_and_redirect
182   _email_auth_request
183   redirect email_auth_email_sent_redirect
184 end
_field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
612 def _field_attributes(field)
613   nil
614 end
_field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
616 def _field_error_attributes(field)
617   " aria-invalid=\"true\" aria-describedby=\"#{field}_error_message\" "
618 end
_formatted_field_error(field, error)
[show source]
    # File lib/rodauth/features/base.rb
620 def _formatted_field_error(field, error)
621   "<span class=\"#{input_field_error_message_class}\" id=\"#{field}_error_message\">#{error}</span>"
622 end
_json_response_body(hash)
[show source]
    # File lib/rodauth/features/jwt.rb
264 def _json_response_body(hash)
265   request.send(:convert_to_json, hash)
266 end
_login(auth_type)
[show source]
    # File lib/rodauth/features/login.rb
140 def _login(auth_type)
141   warn("Deprecated #_login method called, use #login instead.")
142   login(auth_type)
143 end
_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/email_auth.rb
171 def _multi_phase_login_forms
172   forms = super
173   forms << [30, email_auth_request_form, :_email_auth_request_and_redirect] if valid_login_entered? && allow_email_auth?
174   forms
175 end
_new_account(login)
[show source]
    # File lib/rodauth/features/create_account.rb
119 def _new_account(login)
120   acc = {login_column=>login}
121   unless skip_status_checks?
122     acc[account_status_column] = account_initial_status_value
123   end
124   acc
125 end
_otp()
[show source]
    # File lib/rodauth/features/otp.rb
403 def _otp
404   otp_class.new(otp_user_key, :issuer=>otp_issuer, :digits=>otp_digits, :interval=>otp_interval)
405 end
_otp_add_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
392 def _otp_add_key(secret)
393   # Uniqueness errors can't be handled here, as we can't be sure the secret provided
394   # is the same as the current secret.
395   otp_key_ds.insert(otp_keys_id_column=>session_value, otp_keys_column=>secret)
396 end
_otp_key()
[show source]
    # File lib/rodauth/features/otp.rb
398 def _otp_key
399   @otp_user_key = nil
400   otp_key_ds.get(otp_keys_column)
401 end
_otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
386 def _otp_tmp_key(secret)
387   @otp_tmp_key = true
388   @otp_user_key = nil
389   @otp_key = secret
390 end
_recovery_codes()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
230 def _recovery_codes
231   recovery_codes_ds.select_map(recovery_codes_column)
232 end
_sms()
[show source]
    # File lib/rodauth/features/sms_codes.rb
487 def _sms
488   sms_ds.first
489 end
_two_factor_remove_all_from_session()
[show source]
    # File lib/rodauth/features/otp.rb
342 def _two_factor_remove_all_from_session
343   two_factor_remove_session('totp')
344   super
345 end
_update_login(login)
[show source]
   # File lib/rodauth/features/change_login.rb
80 def _update_login(login)
81   updated = nil
82   raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
83   if raised
84     @login_requirement_message = already_an_account_with_this_login_message
85   end
86   updated && !raised
87 end
_view(meth, page)
[show source]
    # File lib/rodauth/features/base.rb
740 def _view(meth, page)
741   scope.send(meth, _view_opts(page))
742 end
_view_opts(page)
[show source]
    # File lib/rodauth/features/base.rb
725 def _view_opts(page)
726   opts = template_opts.dup
727   opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
728   opts[:locals][:rodauth] = self
729   opts[:cache] = cache_templates
730   opts[:cache_key] = :"rodauth_#{page}"
731 
732   opts = scope.send(:find_template, scope.send(:parse_template_opts, page, opts))
733   unless File.file?(scope.send(:template_path, opts))
734     opts[:path] = template_path(page)
735   end
736 
737   opts
738 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
632 def account_ds(id=account_id)
633   raise ArgumentError, "invalid account id passed to account_ds" unless id
634   ds = db[accounts_table].where(account_id_column=>id)
635   ds = ds.select(*account_select) if account_select
636   ds
637 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
130 def account_from_email_auth_key(key)
131   @account = _account_from_email_auth_key(key)
132 end
account_from_key(token, status_id=nil)
[show source]
   # File lib/rodauth/features/email_base.rb
61 def account_from_key(token, status_id=nil)
62   id, key = split_token(token)
63   return unless id && key
64 
65   return unless actual = yield(id)
66 
67   unless timing_safe_eql?(key, convert_email_token_key(actual))
68     if hmac_secret && allow_raw_email_token?
69       return unless timing_safe_eql?(key, actual)
70     else
71       return
72     end
73   end
74 
75   ds = account_ds(id)
76   ds = ds.where(account_status_column=>status_id) if status_id && !skip_status_checks?
77   ds.first
78 end
account_from_login(login)
[show source]
    # File lib/rodauth/features/base.rb
246 def account_from_login(login)
247   @account = _account_from_login(login)
248 end
account_from_refresh_token(token)
[show source]
   # File lib/rodauth/features/jwt_refresh.rb
82 def account_from_refresh_token(token)
83   @account = _account_from_refresh_token(token)
84 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
337 def account_from_session
338   @account = _account_from_session
339 end
account_from_unlock_key(key)
[show source]
    # File lib/rodauth/features/lockout.rb
214 def account_from_unlock_key(key)
215   @account = _account_from_unlock_key(key)
216 end
account_from_verify_account_key(key)
[show source]
    # File lib/rodauth/features/verify_account.rb
203 def account_from_verify_account_key(key)
204   @account = _account_from_verify_account_key(key)
205 end
account_from_verify_login_change_key(key)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
117 def account_from_verify_login_change_key(key)
118   @account = _account_from_verify_login_change_key(key)
119 end
account_id()
[show source]
    # File lib/rodauth/features/base.rb
236 def account_id
237   account[account_id_column]
238 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   account || 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
333 def account_initial_status_value
334   account_open_status_value
335 end
account_lockouts_ds(id=account_id)
[show source]
    # File lib/rodauth/features/lockout.rb
300 def account_lockouts_ds(id=account_id)
301   db[account_lockouts_table].where(account_lockouts_id_column=>id)
302 end
account_login_failures_ds()
[show source]
    # File lib/rodauth/features/lockout.rb
296 def account_login_failures_ds
297   db[account_login_failures_table].where(account_login_failures_id_column=>account_id)
298 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
265 def account_password_hash_column
266   nil
267 end
account_session_status_filter()
[show source]
    # File lib/rodauth/features/base.rb
624 def account_session_status_filter
625   {account_status_column=>account_open_status_value}
626 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
200 def active_remember_key_ds(id=account_id)
201   remember_key_ds(id).where(Sequel.expr(remember_deadline_column) > Sequel::CURRENT_TIMESTAMP)
202 end
active_sessions_ds()
[show source]
    # File lib/rodauth/features/active_sessions.rb
148 def active_sessions_ds
149   db[active_sessions_table].
150     where(active_sessions_account_id_column=>session_value)
151 end
add_active_session()
[show source]
   # File lib/rodauth/features/active_sessions.rb
59 def add_active_session
60   key = random_key
61   set_session_value(session_id_session_key, key)
62   if e = raises_uniqueness_violation? do
63       active_sessions_ds.insert(active_sessions_account_id_column => session_value, active_sessions_session_id_column => compute_hmac(key))
64     end
65     handle_duplicate_active_session_id(e)
66   end
67   nil
68 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
166 def add_field_error_class(field)
167   if field_error(field)
168     " #{input_field_error_class}"
169   end
170 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   keep_before = ds.reverse(previous_password_id_column).
28     limit(nil, previous_passwords_to_check).
29     get(previous_password_id_column)
30 
31   if keep_before
32     ds.where(Sequel.expr(previous_password_id_column) <= keep_before).
33       delete
34   end
35 
36   # This should never raise uniqueness violations, as it uses a serial primary key
37   ds.insert(previous_password_account_id_column=>account_id, previous_password_hash_column=>hash)
38 end
add_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
182 def add_recovery_code
183   # This should never raise uniqueness violations unless the recovery code is the same, and the odds of that
184   # are 1/256**32 assuming a good random number generator.  Still, attempt to handle that case by retrying
185   # on such a uniqueness violation.
186   retry_on_uniqueness_violation do
187     recovery_codes_ds.insert(recovery_codes_id_column=>session_value, recovery_codes_column=>new_recovery_code)
188   end
189 end
add_recovery_codes(number)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
172 def add_recovery_codes(number)
173   return if number <= 0
174   transaction do
175     number.times do
176       add_recovery_code
177     end
178   end
179   remove_instance_variable(:@recovery_codes)
180 end
add_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
155 def add_remember_key
156   hash = {remember_id_column=>account_id, remember_key_column=>remember_key_value}
157   set_deadline_value(hash, remember_deadline_column, remember_deadline_interval)
158 
159   if e = raised_uniqueness_violation{remember_key_ds.insert(hash)}
160     # If inserting into the remember key table causes a violation, we can pull the
161     # existing row from the table.  If there is no invalid row, we can then reraise.
162     raise e unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
163   end
164 end
add_webauthn_credential(_)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
146 def add_webauthn_credential(_)
147   super if defined?(super)
148   auto_add_missing_recovery_codes
149 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
72 def after_create_account
73   if account_password_hash_column && !(respond_to?(:verify_account_set_password?) && verify_account_set_password?)
74     add_previous_password_hash(password_hash(param(password_param)))
75   end
76   super if defined?(super)
77 end
after_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
209 def after_login
210   # Remove the email auth key after any login, even if
211   # it is a password login.  This is done to invalidate
212   # the email login when a user has a password and requests
213   # email authentication, but then remembers their password
214   # and doesn't need the link.  At that point, the link
215   # that allows login access to the account becomes a
216   # security liability, and it is best to remove it.
217   remove_email_auth_key
218   super
219 end
after_login_entered_during_multi_phase_login()
[show source]
    # File lib/rodauth/features/email_auth.rb
152 def after_login_entered_during_multi_phase_login
153   # If forcing email auth, just send the email link.
154   _email_auth_request_and_redirect if force_email_auth?
155 
156   super
157 end
after_login_failure()
[show source]
    # File lib/rodauth/features/lockout.rb
254 def after_login_failure
255   invalid_login_attempted
256   super
257 end
after_logout()
[show source]
    # File lib/rodauth/features/remember.rb
176 def after_logout
177   forget_login
178   super if defined?(super)
179 end
after_refresh_token()
[show source]
    # File lib/rodauth/features/active_sessions.rb
104 def after_refresh_token
105   super if defined?(super)
106   if prev_key = session[session_id_session_key]
107     key = random_key
108     set_session_value(session_id_session_key, key)
109     active_sessions_ds.
110       where(active_sessions_session_id_column => compute_hmac(prev_key)).
111       update(active_sessions_session_id_column => compute_hmac(key))
112   end
113 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
allow_email_auth?()
[show source]
    # File lib/rodauth/features/email_auth.rb
205 def allow_email_auth?
206   defined?(super) ? super : true
207 end
allow_resending_verify_account_email?()
[show source]
    # File lib/rodauth/features/verify_account.rb
169 def allow_resending_verify_account_email?
170   account[account_status_column] == account_unverified_status_value
171 end
already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
273 def already_logged_in
274   nil
275 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
117 def auth_class_eval(&block)
118   auth.class_eval(&block)
119 end
authenticated?()
[show source]
    # File lib/rodauth/features/base.rb
325 def authenticated?
326   logged_in?
327 end
authenticated_by()
[show source]
    # File lib/rodauth/features/base.rb
408 def authenticated_by
409   session[authenticated_by_session_key]
410 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
224 def auto_add_missing_recovery_codes
225   if auto_add_recovery_codes?
226     add_recovery_codes(recovery_codes_limit - recovery_codes.length)
227   end
228 end
autocomplete_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
196 def autocomplete_for_field?(_param)
197   mark_input_fields_with_autocomplete?
198 end
autologin_session(autologin_type)
[show source]
    # File lib/rodauth/features/base.rb
421 def autologin_session(autologin_type)
422   login_session('autologin')
423   set_session_value(autologin_type_session_key, autologin_type)
424 end
autologin_type()
[show source]
    # File lib/rodauth/features/base.rb
417 def autologin_type
418   session[autologin_type_session_key]
419 end
base32_encode(data, length)
[show source]
    # File lib/rodauth/features/otp.rb
381 def base32_encode(data, length)
382   chars = 'abcdefghijklmnopqrstuvwxyz234567'
383   length.times.map{|i|chars[data[i].ord % 32]}.join
384 end
base_url()
[show source]
    # File lib/rodauth/features/base.rb
443 def base_url
444   request.base_url
445 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_login_attempt()
[show source]
    # File lib/rodauth/features/lockout.rb
242 def before_login_attempt
243   if locked_out?
244     show_lockout_page
245   end
246   super
247 end
before_logout()
[show source]
    # File lib/rodauth/features/active_sessions.rb
120 def before_logout
121   if param_or_nil(global_logout_param)
122     remove_all_active_sessions
123   else
124     remove_current_session
125   end
126   super
127 end
before_otp_setup_route()
[show source]
    # File lib/rodauth/features/jwt.rb
223 def before_otp_setup_route
224   super if defined?(super)
225   if use_jwt? && otp_keys_use_hmac? && !param_or_nil(otp_setup_raw_param)
226     _otp_tmp_key(otp_new_secret)
227     json_response[otp_setup_param] = otp_user_key
228     json_response[otp_setup_raw_param] = otp_key
229   end
230 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/jwt.rb
153 def before_rodauth
154   if json_request?
155     if jwt_check_accept? && (accept = request.env['HTTP_ACCEPT']) && accept !~ json_accept_regexp
156       response.status = 406
157       json_response[json_response_error_key] = json_not_accepted_error_message
158       response['Content-Type'] ||= json_response_content_type
159       response.write(_json_response_body(json_response))
160       request.halt
161     end
162 
163     unless request.post?
164       response.status = 405
165       response.headers['Allow'] = 'POST'
166       json_response[json_response_error_key] = json_non_post_error_message
167       return_json_response
168     end
169   elsif only_json?
170     response.status = json_response_error_status
171     response.write non_json_request_error_message
172     request.halt
173   end
174 
175   super
176 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?(:jwt) && use_jwt? && !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_view_recovery_codes()
[show source]
    # File lib/rodauth/features/jwt.rb
178 def before_view_recovery_codes
179   super if defined?(super)
180   if use_jwt?
181     json_response[:codes] = recovery_codes
182     json_response[json_response_success_key] ||= "" if include_success_messages?
183   end
184 end
before_webauthn_auth_route()
[show source]
    # File lib/rodauth/features/jwt.rb
196 def before_webauthn_auth_route
197   super if defined?(super)
198   if use_jwt? && !param_or_nil(webauthn_auth_param)
199     cred = webauth_credential_options_for_get
200     json_response[webauthn_auth_param] = cred.as_json
201     json_response[webauthn_auth_challenge_param] = cred.challenge
202     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
203   end
204 end
before_webauthn_login_route()
[show source]
    # File lib/rodauth/features/jwt.rb
206 def before_webauthn_login_route
207   super if defined?(super)
208   if use_jwt? && !param_or_nil(webauthn_auth_param) && account_from_login(param(login_param))
209     cred = webauth_credential_options_for_get
210     json_response[webauthn_auth_param] = cred.as_json
211     json_response[webauthn_auth_challenge_param] = cred.challenge
212     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
213   end
214 end
before_webauthn_remove_route()
[show source]
    # File lib/rodauth/features/jwt.rb
216 def before_webauthn_remove_route
217   super if defined?(super)
218   if use_jwt? && !param_or_nil(webauthn_remove_param)
219     json_response[webauthn_remove_param] = account_webauthn_usage
220   end
221 end
before_webauthn_setup_route()
[show source]
    # File lib/rodauth/features/jwt.rb
186 def before_webauthn_setup_route
187   super if defined?(super)
188   if use_jwt? && !param_or_nil(webauthn_setup_param)
189     cred = new_webauthn_credential
190     json_response[webauthn_setup_param] = cred.as_json
191     json_response[webauthn_setup_challenge_param] = cred.challenge
192     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
193   end
194 end
button(value, opts={})
[show source]
    # File lib/rodauth/features/base.rb
366 def button(value, opts={})
367   scope.render(button_opts(value, opts))
368 end
button_opts(value, opts)
[show source]
    # File lib/rodauth/features/base.rb
357 def button_opts(value, opts)
358   opts = Hash[template_opts].merge!(opts)
359   opts[:locals] = {:value=>value, :opts=>opts}
360   opts[:path] = template_path('button')
361   opts[:cache] = cache_templates
362   opts[:cache_key] = :rodauth_button
363   opts
364 end
can_add_recovery_codes?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
168 def can_add_recovery_codes?
169   recovery_codes.length < recovery_codes_limit
170 end
catch_error(&block)
[show source]
    # File lib/rodauth/features/base.rb
516 def catch_error(&block)
517   catch(:rodauth_error, &block)
518 end
change_login(login)
[show source]
   # File lib/rodauth/features/change_login.rb
65 def change_login(login)
66   if account_ds.get(login_column).downcase == login.downcase
67     @login_requirement_message = 'same as current login'
68     return false
69   end
70 
71   update_login(login)
72 end
change_login_notice_flash()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
133 def change_login_notice_flash
134   "An email has been sent to you with a link to verify your login change"
135 end
change_login_requires_password?()
[show source]
   # File lib/rodauth/features/change_login.rb
61 def change_login_requires_password?
62   modifications_require_password?
63 end
change_password_requires_password?()
[show source]
   # File lib/rodauth/features/change_password.rb
66 def change_password_requires_password?
67   modifications_require_password?
68 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
46 def check_active_session
47   if logged_in? && !currently_active_session?
48     no_longer_active_session
49   end
50 end
check_already_logged_in()
[show source]
    # File lib/rodauth/features/base.rb
269 def check_already_logged_in
270   already_logged_in if logged_in?
271 end
check_csrf()
[show source]
    # File lib/rodauth/features/base.rb
341 def check_csrf
342   scope.check_csrf!(check_csrf_opts, &check_csrf_block)
343 end
check_csrf?()
[show source]
    # File lib/rodauth/features/base.rb
561 def check_csrf?
562   scope.opts[:rodauth_route_csrf]
563 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
347 def clear_cached_otp
348   remove_instance_variable(:@otp) if defined?(@otp)
349 end
clear_invalid_login_attempts()
[show source]
    # File lib/rodauth/features/lockout.rb
164 def clear_invalid_login_attempts
165   unlock_account
166 end
clear_session()
[show source]
    # File lib/rodauth/features/base.rb
285 def clear_session
286   if scope.respond_to?(:clear_session)
287     scope.clear_session
288   else
289     session.clear
290   end
291 end
close_account()
[show source]
   # File lib/rodauth/features/close_account.rb
64 def close_account
65   unless skip_status_checks?
66     update_account(account_status_column=>account_closed_status_value)
67   end
68 
69   unless account_password_hash_column
70     password_hash_ds.delete
71   end
72 end
close_account_requires_password?()
[show source]
   # File lib/rodauth/features/close_account.rb
60 def close_account_requires_password?
61   modifications_require_password?
62 end
compute_hmac(data)

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

[show source]
    # File lib/rodauth/features/base.rb
230 def compute_hmac(data)
231   s = [compute_raw_hmac(data)].pack('m').chomp!("=\n")
232   s.tr!('+/', '-_')
233   s
234 end
compute_raw_hmac(data)
[show source]
    # File lib/rodauth/features/base.rb
608 def compute_raw_hmac(data)
609   OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, hmac_secret, data)
610 end
confirm_password()
[show source]
   # File lib/rodauth/features/confirm_password.rb
62 def confirm_password
63   authenticated_by.delete('autologin')
64   authenticated_by.delete('remember')
65   authenticated_by.delete('email_auth')
66   authenticated_by.delete('password')
67   authenticated_by.unshift("password")
68   remove_session_value(autologin_type_session_key)
69   nil
70 end
confirm_password_redirect()
[show source]
   # File lib/rodauth/features/confirm_password.rb
72 def confirm_password_redirect
73   remove_session_value(confirm_password_redirect_session_key) || default_redirect
74 end
convert_email_token_key(key)
[show source]
   # File lib/rodauth/features/email_base.rb
57 def convert_email_token_key(key)
58   convert_token_key(key)
59 end
convert_session_key(key)
[show source]
    # File lib/rodauth/features/base.rb
495 def convert_session_key(key)
496   scope.opts[:sessions_convert_symbols] ? key.to_s : key
497 end
convert_timestamp(timestamp)

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

[show source]
    # File lib/rodauth/features/base.rb
644 def convert_timestamp(timestamp)
645   timestamp = db.to_application_timestamp(timestamp) if timestamp.is_a?(String)
646   timestamp
647 end
convert_token_key(key)
[show source]
    # File lib/rodauth/features/base.rb
461 def convert_token_key(key)
462   if key && hmac_secret
463     compute_hmac(key)
464   else
465     key
466   end
467 end
create_account_autologin?()
[show source]
    # File lib/rodauth/features/verify_account.rb
227 def create_account_autologin?
228   false
229 end
create_account_notice_flash()
[show source]
    # File lib/rodauth/features/verify_account.rb
189 def create_account_notice_flash
190   verify_account_email_sent_notice_flash
191 end
create_account_set_password?()
[show source]
    # File lib/rodauth/features/verify_account.rb
231 def create_account_set_password?
232   return false if verify_account_set_password?
233   super
234 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
230 def create_email_auth_email
231   create_email(email_auth_email_subject, email_auth_email_body)
232 end
create_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
101 def create_email_auth_key
102   transaction do
103     if email_auth_key_value = get_email_auth_key(account_id)
104       set_email_auth_email_last_sent
105       @email_auth_key_value = email_auth_key_value
106     elsif e = raised_uniqueness_violation{email_auth_ds.insert(email_auth_key_insert_hash)}
107       # If inserting into the email auth table causes a violation, we can pull the
108       # existing email auth key from the table, or reraise.
109       raise e unless @email_auth_key_value = get_email_auth_key(account_id)
110     end
111   end
112 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
239 def create_reset_password_email
240   create_email(reset_password_email_subject, reset_password_email_body)
241 end
create_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
164 def create_reset_password_key
165   transaction do
166     if reset_password_key_value = get_password_reset_key(account_id)
167       set_reset_password_email_last_sent
168       @reset_password_key_value = reset_password_key_value
169     elsif e = raised_uniqueness_violation{password_reset_ds.insert(reset_password_key_insert_hash)}
170       # If inserting into the reset password table causes a violation, we can pull the
171       # existing reset password key from the table, or reraise.
172       raise e unless @reset_password_key_value = get_password_reset_key(account_id)
173     end
174   end
175 end
create_unlock_account_email()
[show source]
    # File lib/rodauth/features/lockout.rb
280 def create_unlock_account_email
281   create_email(unlock_account_email_subject, unlock_account_email_body)
282 end
create_verify_account_email()
[show source]
    # File lib/rodauth/features/verify_account.rb
310 def create_verify_account_email
311   create_email(verify_account_email_subject, verify_account_email_body)
312 end
create_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
293 def create_verify_account_key
294   ds = verify_account_ds
295   transaction do
296     if ds.empty?
297       if e = raised_uniqueness_violation{ds.insert(verify_account_key_insert_hash)}
298         # If inserting into the verify account table causes a violation, we can pull the
299         # key from the verify account table, or reraise.
300         raise e unless @verify_account_key_value = get_verify_account_key(account_id)
301       end
302     end
303   end
304 end
create_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
195 def create_verify_login_change_email(login)
196   create_email_to(login, verify_login_change_email_subject, verify_login_change_email_body)
197 end
create_verify_login_change_key(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
173 def create_verify_login_change_key(login)
174   ds = verify_login_change_ds
175   transaction do
176     ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
177     if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
178       old_login, key = get_verify_login_change_login_and_key(account_id)
179       # If inserting into the verify login change table causes a violation, we can pull the
180       # key from the verify login change table if the logins match, or reraise.
181       @verify_login_change_key_value = if old_login.downcase == login.downcase
182         key
183       end
184       raise e unless @verify_login_change_key_value
185     end
186   end
187 end
csrf_tag(path=request.path)
[show source]
    # File lib/rodauth/features/base.rb
345 def csrf_tag(path=request.path)
346   return unless scope.respond_to?(:csrf_tag)
347 
348   if use_request_specific_csrf_tokens?
349     scope.csrf_tag(path)
350   else
351     # :nocov:
352     scope.csrf_tag
353     # :nocov:
354   end
355 end
currently_active_session?()
[show source]
   # File lib/rodauth/features/active_sessions.rb
32 def currently_active_session?
33   return false unless session_id = session[session_id_session_key]
34 
35   remove_inactive_sessions
36   ds = active_sessions_ds.
37     where(active_sessions_session_id_column => compute_hmac(session_id))
38 
39   if session_inactivity_deadline
40     ds.update(active_sessions_last_use_column => Sequel::CURRENT_TIMESTAMP) == 1
41   else
42     ds.count == 1
43   end
44 end
db()
[show source]
    # File lib/rodauth/features/base.rb
254 def db
255   Sequel::DATABASES.first
256 end
delete_account()
[show source]
   # File lib/rodauth/features/close_account.rb
74 def delete_account
75   account_ds.delete
76 end
delete_account_on_close?()
[show source]
   # File lib/rodauth/features/close_account.rb
78 def delete_account_on_close?
79   skip_status_checks?
80 end
disable_remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
151 def disable_remember_login
152   remove_remember_key
153 end
domain()
[show source]
    # File lib/rodauth/features/base.rb
447 def domain
448   request.host
449 end
email_auth_ds(id=account_id)
[show source]
    # File lib/rodauth/features/email_auth.rb
248 def email_auth_ds(id=account_id)
249   db[email_auth_table].where(email_auth_id_column=>id)
250 end
email_auth_email_body()
[show source]
    # File lib/rodauth/features/email_auth.rb
234 def email_auth_email_body
235   render('email-auth-email')
236 end
email_auth_email_recently_sent?()
[show source]
    # File lib/rodauth/features/email_auth.rb
177 def email_auth_email_recently_sent?
178   (email_last_sent = get_email_auth_email_last_sent) && (Time.now - email_last_sent < email_auth_skip_resend_email_within)
179 end
email_auth_key_insert_hash()
[show source]
    # File lib/rodauth/features/email_auth.rb
242 def email_auth_key_insert_hash
243   hash = {email_auth_id_column=>account_id, email_auth_key_column=>email_auth_key_value}
244   set_deadline_value(hash, email_auth_deadline_column, email_auth_deadline_interval)
245   hash
246 end
email_auth_request_form()
[show source]
    # File lib/rodauth/features/email_auth.rb
148 def email_auth_request_form
149   render('email-auth-request-form')
150 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_redirect_error_flash session_expiration_error_flash
42   redirect session_expiration_redirect
43 end
features()
[show source]
    # File lib/rodauth/features/base.rb
129 def features
130   self.class.features
131 end
field_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
204 def field_attributes(field)
205   _field_attributes(field) || default_field_attributes
206 end
field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
161 def field_error(field)
162   return nil unless @field_errors
163   @field_errors[field]
164 end
field_error_attributes(field)
[show source]
    # File lib/rodauth/features/base.rb
208 def field_error_attributes(field)
209   if field_error(field)
210     _field_error_attributes(field)
211   end
212 end
flash()
[show source]
    # File lib/rodauth/features/base.rb
145 def flash
146   scope.flash
147 end
forget_login()
[show source]
    # File lib/rodauth/features/remember.rb
136 def forget_login
137   ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, remember_cookie_options)
138 end
formatted_field_error(field)
[show source]
    # File lib/rodauth/features/base.rb
214 def formatted_field_error(field)
215   if error = field_error(field)
216     _formatted_field_error(field, error)
217   end
218 end
function_name(name)
[show source]
    # File lib/rodauth/features/base.rb
565 def function_name(name)
566   if db.database_type == :mssql
567     # :nocov:
568     "dbo.#{name}"
569     # :nocov:
570   else
571     name
572   end
573 end
generate_email_auth_key_value()
[show source]
    # File lib/rodauth/features/email_auth.rb
226 def generate_email_auth_key_value
227   @email_auth_key_value = random_key
228 end
generate_refresh_token()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
138 def generate_refresh_token
139   hash = jwt_refresh_token_insert_hash
140   [account_id, jwt_refresh_token_ds.insert(hash), convert_token_key(hash[jwt_refresh_token_key_column])].join(token_separator)
141 end
generate_remember_key_value()
[show source]
    # File lib/rodauth/features/remember.rb
188 def generate_remember_key_value
189   @remember_key_value = random_key
190 end
generate_reset_password_key_value()
[show source]
    # File lib/rodauth/features/reset_password.rb
235 def generate_reset_password_key_value
236   @reset_password_key_value = random_key
237 end
generate_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
264 def generate_unlock_account_key
265   random_key
266 end
generate_verify_account_key_value()
[show source]
    # File lib/rodauth/features/verify_account.rb
289 def generate_verify_account_key_value
290   @verify_account_key_value = random_key
291 end
generate_verify_login_change_key_value()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
169 def generate_verify_login_change_key_value
170   @verify_login_change_key_value = random_key
171 end
get_active_refresh_token(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
110 def get_active_refresh_token(account_id, token_id)
111   jwt_refresh_token_account_ds(account_id).
112     where(Sequel::CURRENT_TIMESTAMP > jwt_refresh_token_deadline_column).
113     delete
114 
115   jwt_refresh_token_account_token_ds(account_id, token_id).
116     get(jwt_refresh_token_key_column)
117 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
118 def get_email_auth_email_last_sent
119   if column = email_auth_email_last_sent_column
120     if ts = email_auth_ds.get(column)
121       convert_timestamp(ts)
122     end
123   end
124 end
get_email_auth_key(id)
[show source]
    # File lib/rodauth/features/email_auth.rb
142 def get_email_auth_key(id)
143   ds = email_auth_ds(id)
144   ds.where(Sequel::CURRENT_TIMESTAMP > email_auth_deadline_column).delete
145   ds.get(email_auth_key_column)
146 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
583 def get_password_hash
584   if account_password_hash_column
585     (account || account_from_session)[account_password_hash_column]
586   elsif use_database_authentication_functions?
587     db.get(Sequel.function(function_name(:rodauth_get_salt), account ? account_id : session_value))
588   else
589     # :nocov:
590     password_hash_ds.get(password_hash_column)
591     # :nocov:
592   end
593 end
get_password_reset_key(id)
[show source]
    # File lib/rodauth/features/reset_password.rb
193 def get_password_reset_key(id)
194   ds = password_reset_ds(id)
195   ds.where(Sequel::CURRENT_TIMESTAMP > reset_password_deadline_column).delete
196   ds.get(reset_password_key_column)
197 end
get_remember_key()
[show source]
    # File lib/rodauth/features/remember.rb
140 def get_remember_key
141   unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
142    generate_remember_key_value
143    transaction do
144      remove_remember_key
145      add_remember_key
146    end
147   end
148   nil
149 end
get_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
203 def get_reset_password_email_last_sent
204   if column = reset_password_email_last_sent_column
205     if ts = password_reset_ds.get(column)
206       convert_timestamp(ts)
207     end
208   end
209 end
get_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
226 def get_unlock_account_email_last_sent
227   if column = account_lockouts_email_last_sent_column
228     if ts = account_lockouts_ds.get(column)
229       convert_timestamp(ts)
230     end
231   end
232 end
get_unlock_account_key()
[show source]
    # File lib/rodauth/features/lockout.rb
210 def get_unlock_account_key
211   account_lockouts_ds.get(account_lockouts_key_column)
212 end
get_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
240 def get_verify_account_email_last_sent
241   if column = verify_account_email_last_sent_column
242     if ts = verify_account_ds.get(column)
243       convert_timestamp(ts)
244     end
245   end
246 end
get_verify_account_key(id)
[show source]
    # File lib/rodauth/features/verify_account.rb
219 def get_verify_account_key(id)
220   verify_account_ds(id).get(verify_account_key_column)
221 end
get_verify_login_change_login_and_key(id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
129 def get_verify_login_change_login_and_key(id)
130   verify_login_change_ds(id).get([verify_login_change_login_column, verify_login_change_key_column])
131 end
handle_duplicate_active_session_id(_e)
[show source]
   # File lib/rodauth/features/active_sessions.rb
70 def handle_duplicate_active_session_id(_e)
71   # Do nothing by default as session is already tracked.  This will result in
72   # the current session and the existing session with the same id
73   # being tracked together, so that a logout of one will logout
74   # the other, and updating the last use on one will update the other,
75   # but this should be acceptable.  However, this can be overridden if different
76   # behavior is desired.
77 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_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message) 
346 end
has_password?()
[show source]
    # File lib/rodauth/features/base.rb
575 def has_password?
576   return @has_password if defined?(@has_password)
577   return false unless account || session_value
578   @has_password = !!get_password_hash
579 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
141 def inactive_session_cond
142   cond = session_inactivity_deadline_condition
143   cond2 = session_lifetime_deadline_condition
144   return false unless cond || cond2
145   Sequel.|(*[cond, cond2].compact)
146 end
include_success_messages?()
[show source]
    # File lib/rodauth/features/jwt.rb
244 def include_success_messages?
245   !json_response_success_key.nil?
246 end
input_field_string(param, id, opts={})
[show source]
    # File lib/rodauth/features/base.rb
172 def input_field_string(param, id, opts={})
173   type = opts.fetch(:type, "text")
174 
175   unless type == "password"
176     value = opts.fetch(:value){scope.h param(param)}
177   end
178 
179   field_class = opts.fetch(:class, "form-control")
180 
181   if autocomplete_for_field?(param) && opts[:autocomplete]
182     autocomplete = "autocomplete=\"#{opts[:autocomplete]}\""
183   end
184 
185   if inputmode_for_field?(param) && opts[:inputmode]
186     inputmode = "inputmode=\"#{opts[:inputmode]}\""
187   end
188 
189   if mark_input_fields_as_required? && opts[:required] != false
190     required = "required=\"required\""
191   end
192 
193   "<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]}"
194 end
inputmode_for_field?(_param)
[show source]
    # File lib/rodauth/features/base.rb
200 def inputmode_for_field?(_param)
201   mark_input_fields_with_inputmode?
202 end
invalid_login_attempted()
[show source]
    # File lib/rodauth/features/lockout.rb
168 def invalid_login_attempted
169   ds = account_login_failures_ds.
170       where(account_login_failures_id_column=>account_id)
171 
172   number = if db.database_type == :postgres
173     ds.returning(account_login_failures_number_column).
174       with_sql(:update_sql, account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1).
175       single_value
176   else
177     # :nocov:
178     if ds.update(account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1) > 0
179       ds.get(account_login_failures_number_column)
180     end
181     # :nocov:
182   end
183 
184   unless number
185     # Ignoring the violation is safe here.  It may allow slightly more than max_invalid_logins invalid logins before
186     # lockout, but allowing a few extra is OK if the race is lost.
187     ignore_uniqueness_violation{account_login_failures_ds.insert(account_login_failures_id_column=>account_id)}
188     number = 1
189   end
190 
191   if number >= max_invalid_logins
192     @unlock_account_key_value = generate_unlock_account_key
193     hash = {account_lockouts_id_column=>account_id, account_lockouts_key_column=>unlock_account_key_value}
194     set_deadline_value(hash, account_lockouts_deadline_column, account_lockouts_deadline_interval)
195 
196     if e = raised_uniqueness_violation{account_lockouts_ds.insert(hash)}
197       # If inserting into the lockout table raises a violation, we should just be able to pull the already inserted
198       # key out of it.  If that doesn't return a valid key, we should reraise the error.
199       raise e unless @unlock_account_key_value = account_lockouts_ds.get(account_lockouts_key_column)
200 
201       after_account_lockout
202       show_lockout_page
203     else
204       after_account_lockout
205       e
206     end
207   end
208 end
invalid_previous_password_message()
[show source]
   # File lib/rodauth/features/change_password.rb
70 def invalid_previous_password_message
71   invalid_password_message
72 end
json_request?()
[show source]
    # File lib/rodauth/features/jwt.rb
104 def json_request?
105   return @json_request if defined?(@json_request)
106   @json_request = request.content_type =~ json_request_content_type_regexp
107 end
json_response()
[show source]
    # File lib/rodauth/features/jwt.rb
260 def json_response
261   @json_response ||= {}
262 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
232 def jwt_payload
233   return @jwt_payload if defined?(@jwt_payload)
234   @jwt_payload = JWT.decode(jwt_token, jwt_secret, true, jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
235 rescue JWT::DecodeError
236   @jwt_payload = false
237 end
jwt_refresh_token_account_ds(account_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
119 def jwt_refresh_token_account_ds(account_id)
120   jwt_refresh_token_ds.where(jwt_refresh_token_account_id_column => account_id)
121 end
jwt_refresh_token_account_token_ds(account_id, token_id)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
123 def jwt_refresh_token_account_token_ds(account_id, token_id)
124   jwt_refresh_token_account_ds(account_id).
125     where(jwt_refresh_token_id_column=>token_id)
126 end
jwt_refresh_token_ds()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
128 def jwt_refresh_token_ds
129   db[jwt_refresh_token_table]
130 end
jwt_refresh_token_insert_hash()
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
143 def jwt_refresh_token_insert_hash
144   hash = {jwt_refresh_token_account_id_column => account_id, jwt_refresh_token_key_column => random_key}
145   set_deadline_value(hash, jwt_refresh_token_deadline_column, jwt_refresh_token_deadline_interval)
146   hash
147 end
jwt_secret()
[show source]
    # File lib/rodauth/features/jwt.rb
109 def jwt_secret
110   raise ArgumentError, "jwt_secret not set"
111 end
jwt_session_hash()
[show source]
    # File lib/rodauth/features/jwt.rb
113 def jwt_session_hash
114   jwt_session_key ? {jwt_session_key=>session} : session
115 end
jwt_token()
[show source]
    # File lib/rodauth/features/jwt.rb
121 def jwt_token
122   return @jwt_token if defined?(@jwt_token)
123 
124   if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
125     @jwt_token = v.sub(jwt_authorization_remove, '')
126   end
127 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
 82 def load_memory
 83   return if session[session_key]
 84   return unless cookie = request.cookies[remember_cookie_key]
 85   id, key = cookie.split('_', 2)
 86   return unless id && key
 87 
 88   actual, deadline = active_remember_key_ds(id).get([remember_key_column, remember_deadline_column])
 89   unless actual
 90     forget_login
 91     return
 92   end
 93 
 94   if hmac_secret
 95     unless valid = timing_safe_eql?(key, compute_hmac(actual))
 96       unless raw_remember_token_deadline && raw_remember_token_deadline > convert_timestamp(deadline)
 97         forget_login
 98         return
 99       end
100     end
101   end
102 
103   unless valid || timing_safe_eql?(key, actual)
104     forget_login
105     return
106   end
107 
108   set_session_value(session_key, id)
109   account = account_from_session
110   remove_session_value(session_key)
111 
112   unless account
113     remove_remember_key(id)
114     forget_login
115     return 
116   end
117 
118   before_load_memory
119   login_session('remember')
120 
121   if extend_remember_deadline?
122     active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
123     remember_login
124   end
125   after_load_memory
126 end
loaded_templates()
[show source]
    # File lib/rodauth/features/base.rb
649 def loaded_templates
650   []
651 end
locked_out?()
[show source]
    # File lib/rodauth/features/lockout.rb
145 def locked_out?
146   if t = convert_timestamp(account_lockouts_ds.get(account_lockouts_deadline_column))
147     if Time.now < t
148       true
149     else
150       unlock_account
151       false
152     end
153   else
154     false
155   end
156 end
logged_in_via_remember_key?()
[show source]
    # File lib/rodauth/features/remember.rb
170 def logged_in_via_remember_key?
171   authenticated_by.include?('remember')
172 end
login(auth_type)
[show source]
   # File lib/rodauth/features/login.rb
75 def login(auth_type)
76   saved_login_redirect = remove_session_value(login_redirect_session_key)
77   transaction do
78     before_login
79     login_session(auth_type)
80     yield if block_given?
81     after_login
82   end
83   set_notice_flash login_notice_flash
84   redirect(saved_login_redirect || login_redirect)
85 end
login_confirm_label()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
39 def login_confirm_label
40   "Confirm #{login_label}"
41 end
login_does_not_meet_requirements_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
84 def login_does_not_meet_requirements_message
85   "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
86 end
login_failed_reset_password_request_form()
[show source]
    # File lib/rodauth/features/reset_password.rb
243 def login_failed_reset_password_request_form
244   render("reset-password-request")
245 end
login_hidden_field()
[show source]
    # File lib/rodauth/features/login.rb
115 def login_hidden_field
116   "<input type='hidden' name=\"#{login_param}\" value=\"#{scope.h param(login_param)}\" />"
117 end
login_input_type()
[show source]
    # File lib/rodauth/features/base.rb
277 def login_input_type
278   login_uses_email? ? 'email' : 'text'
279 end
login_meets_email_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
108 def login_meets_email_requirements?(login)
109   return true unless require_email_address_logins?
110   return true if login_valid_email?(login)
111   @login_requirement_message = login_not_valid_email_message
112   return false
113 end
login_meets_length_requirements?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
 96 def login_meets_length_requirements?(login)
 97   if login_minimum_length > login.length
 98     @login_requirement_message = login_too_short_message
 99     false
100   elsif login_maximum_length < login.length
101     @login_requirement_message = login_too_long_message
102     false
103   else
104     true
105   end
106 end
login_meets_requirements?(login)
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
47 def login_meets_requirements?(login)
48   login_meets_length_requirements?(login) && \
49     login_meets_email_requirements?(login)
50 end
login_required()
[show source]
    # File lib/rodauth/features/base.rb
293 def login_required
294   set_redirect_error_status(login_required_error_status)
295   set_redirect_error_flash require_login_error_flash
296   redirect require_login_redirect
297 end
login_session(auth_type)
[show source]
    # File lib/rodauth/features/base.rb
412 def login_session(auth_type)
413   update_session
414   set_session_value(authenticated_by_session_key, [auth_type])
415 end
login_too_long_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
88 def login_too_long_message
89   "maximum #{login_maximum_length} characters"
90 end
login_too_short_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
92 def login_too_short_message
93   "minimum #{login_minimum_length} characters"
94 end
login_uses_email?()
[show source]
    # File lib/rodauth/features/base.rb
281 def login_uses_email?
282   login_column == :email
283 end
login_valid_email?(login)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
115 def login_valid_email?(login)
116   login =~ login_email_regexp
117 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
93 def logout_additional_form_tags
94   super.to_s + render('global-logout-field')
95 end
modifications_require_password?()
[show source]
    # File lib/rodauth/features/base.rb
451 def modifications_require_password?
452   has_password?
453 end
new_account(login)
[show source]
   # File lib/rodauth/features/create_account.rb
94 def new_account(login)
95   @account = _new_account(login)
96 end
new_recovery_code()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
216 def new_recovery_code
217   random_key
218 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
52 def no_longer_active_session
53   clear_session
54   set_redirect_error_status inactive_session_error_status
55   set_redirect_error_flash active_sessions_error_flash
56   redirect active_sessions_redirect
57 end
only_json?()
[show source]
    # File lib/rodauth/features/base.rb
379 def only_json?
380   scope.class.opts[:rodauth_json] == :only
381 end
open_account?()
[show source]
    # File lib/rodauth/features/base.rb
250 def open_account?
251   skip_status_checks? || account[account_status_column] == account_open_status_value 
252 end
otp_add_key()
[show source]
    # File lib/rodauth/features/otp.rb
261 def otp_add_key
262   _otp_add_key(otp_key)
263   super if defined?(super)
264 end
otp_exists?()
[show source]
    # File lib/rodauth/features/otp.rb
236 def otp_exists?
237   !otp_key.nil?
238 end
otp_hmac_secret(key)
[show source]
    # File lib/rodauth/features/otp.rb
356 def otp_hmac_secret(key)
357   base32_encode(compute_raw_hmac(ROTP::Base32.decode(key)), key.bytesize)
358 end
otp_issuer()
[show source]
    # File lib/rodauth/features/otp.rb
292 def otp_issuer
293   domain
294 end
otp_key_ds()
[show source]
    # File lib/rodauth/features/otp.rb
407 def otp_key_ds
408   db[otp_keys_table].where(otp_keys_id_column=>session_value)
409 end
otp_keys_use_hmac?()
[show source]
    # File lib/rodauth/features/otp.rb
312 def otp_keys_use_hmac?
313   !!hmac_secret
314 end
otp_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
272 def otp_last_use
273   convert_timestamp(otp_key_ds.get(otp_keys_last_use_column))
274 end
otp_locked_out?()
[show source]
    # File lib/rodauth/features/otp.rb
284 def otp_locked_out?
285   otp_key_ds.get(otp_keys_failures_column) >= otp_auth_failures_limit
286 end
otp_new_secret()
[show source]
    # File lib/rodauth/features/otp.rb
370 def otp_new_secret
371   ROTP::Base32.random_base32.downcase
372 end
otp_provisioning_name()
[show source]
    # File lib/rodauth/features/otp.rb
296 def otp_provisioning_name
297   account[login_column]
298 end
otp_provisioning_uri()
[show source]
    # File lib/rodauth/features/otp.rb
288 def otp_provisioning_uri
289   otp.provisioning_uri(otp_provisioning_name)
290 end
otp_qr_code()
[show source]
    # File lib/rodauth/features/otp.rb
300 def otp_qr_code
301   RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8)
302 end
otp_record_authentication_failure()
[show source]
    # File lib/rodauth/features/otp.rb
276 def otp_record_authentication_failure
277   otp_key_ds.update(otp_keys_failures_column=>Sequel.identifier(otp_keys_failures_column) + 1)
278 end
otp_remove()
[show source]
    # File lib/rodauth/features/otp.rb
256 def otp_remove
257   otp_key_ds.delete
258   @otp_key = nil
259 end
otp_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
280 def otp_remove_auth_failures
281   otp_key_ds.update(otp_keys_failures_column=>0)
282 end
otp_tmp_key(secret)
[show source]
    # File lib/rodauth/features/otp.rb
351 def otp_tmp_key(secret)
352   _otp_tmp_key(secret)
353   clear_cached_otp
354 end
otp_update_last_use()
[show source]
    # File lib/rodauth/features/otp.rb
266 def otp_update_last_use
267   otp_key_ds.
268     where(Sequel.date_add(otp_keys_last_use_column, :seconds=>(otp_interval||30)) < Sequel::CURRENT_TIMESTAMP).
269     update(otp_keys_last_use_column=>Sequel::CURRENT_TIMESTAMP) == 1
270 end
otp_user_key()
[show source]
    # File lib/rodauth/features/otp.rb
304 def otp_user_key
305   @otp_user_key ||= if otp_keys_use_hmac?
306     otp_hmac_secret(otp_key)
307   else
308     otp_key
309   end
310 end
otp_valid_code?(ot_pass)
[show source]
    # File lib/rodauth/features/otp.rb
240 def otp_valid_code?(ot_pass)
241   return false unless otp_exists?
242   ot_pass = ot_pass.gsub(/\s+/, '')
243   if drift = otp_drift
244     if otp.respond_to?(:verify_with_drift)
245       # :nocov:
246       otp.verify_with_drift(ot_pass, drift)
247       # :nocov:
248     else
249       otp.verify(ot_pass, :drift_behind=>drift, :drift_ahead=>drift)
250     end
251   else
252     otp.verify(ot_pass)
253   end
254 end
otp_valid_key?(secret)
[show source]
    # File lib/rodauth/features/otp.rb
360 def otp_valid_key?(secret)
361   return false unless secret =~ /\A([a-z2-7]{16}|[a-z2-7]{32})\z/
362   if otp_keys_use_hmac?
363     timing_safe_eql?(otp_hmac_secret(param(otp_setup_raw_param)), secret)
364   else
365     true
366   end
367 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
428 def param(key)
429   param_or_nil(key).to_s
430 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
434 def param_or_nil(key)
435   value = raw_param(key)
436   value.to_s unless value.nil?
437 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
43 def password_confirm_label
44   "Confirm #{password_label}"
45 end
password_does_not_contain_null_byte?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
125 def password_does_not_contain_null_byte?(password)
126   return true unless password.include?("\0")
127   @password_requirement_message = 'contains null byte'
128   false
129 end
password_does_not_meet_requirements_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
76 def password_does_not_meet_requirements_message
77   "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
78 end
password_doesnt_match_previous_password?(password)
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
47 def password_doesnt_match_previous_password?(password)
48   match = if use_database_authentication_functions?
49     salts = previous_password_ds.
50       select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
51     return true if salts.empty?
52 
53     salts.any? do |hash_id, salt|
54       db.get(Sequel.function(function_name(:rodauth_previous_password_hash_match), hash_id, BCrypt::Engine.hash_secret(password, salt)))
55     end
56   else
57     # :nocov:
58     previous_password_ds.select_map(previous_password_hash_column).any?{|hash| BCrypt::Password.new(hash) == password}
59     # :nocov:
60   end
61 
62   return true unless match
63   @password_requirement_message = password_same_as_previous_password_message
64   false
65 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
258 def password_field_autocomplete_value
259   @password_field_autocomplete_value || 'current-password'
260 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   @password_requirement_message = 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   @password_requirement_message = password_invalid_pattern_message
65   false
66 end
password_hash(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
143 def password_hash(password)
144   BCrypt::Password.create(password, :cost=>password_hash_cost)
145 end
password_hash_cost()
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
132 def password_hash_cost
133   BCrypt::Engine::MIN_COST
134 end
password_hash_ds()
[show source]
    # File lib/rodauth/features/base.rb
639 def password_hash_ds
640   db[password_hash_table].where(password_hash_id_column=>account ? account_id : session_value)
641 end
password_match?(password)
[show source]
    # File lib/rodauth/features/base.rb
393 def password_match?(password)
394   if hash = get_password_hash
395     if account_password_hash_column || !use_database_authentication_functions?
396       BCrypt::Password.new(hash) == password
397     else
398       db.get(Sequel.function(function_name(:rodauth_valid_password_hash), account_id, BCrypt::Engine.hash_secret(password, hash)))
399     end 
400   end
401 end
password_meets_length_requirements?(password)
[show source]
    # File lib/rodauth/features/login_password_requirements_base.rb
119 def password_meets_length_requirements?(password)
120   return true if password_minimum_length <= password.length
121   @password_requirement_message = password_too_short_message
122   false
123 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   @password_requirement_message = 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   @password_requirement_message = 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   @password_requirement_message = 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
261 def password_reset_ds(id=account_id)
262   db[reset_password_table].where(reset_password_id_column=>id)
263 end
password_too_short_message()
[show source]
   # File lib/rodauth/features/login_password_requirements_base.rb
80 def password_too_short_message
81   "minimum #{password_minimum_length} characters"
82 end
possible_authentication_methods()
[show source]
    # File lib/rodauth/features/base.rb
455 def possible_authentication_methods
456   has_password? ? ['password'] : []
457 end
post_configure()
[show source]
    # File lib/rodauth/features/base.rb
383 def post_configure
384   require 'bcrypt' if require_bcrypt?
385   db.extension :date_arithmetic if use_date_arithmetic?
386   route_hash= {}
387   self.class.routes.each do |meth|
388     route_hash["/#{send("#{meth.to_s.sub(/\Ahandle_/, '')}_route")}"] = meth
389   end
390   self.class.route_hash = route_hash.freeze
391 end
previous_password_ds()
[show source]
   # File lib/rodauth/features/disallow_password_reuse.rb
79 def previous_password_ds
80   db[previous_password_hash_table].where(previous_password_account_id_column=>account_id)
81 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
668 def raises_uniqueness_violation?(&block)
669   transaction(:savepoint=>:only, &block)
670   false
671 rescue unique_constraint_violation_class => e
672   e
673 end
random_key()
[show source]
    # File lib/rodauth/features/base.rb
491 def random_key
492   SecureRandom.urlsafe_base64(32)
493 end
raw_param(key)
[show source]
    # File lib/rodauth/features/base.rb
439 def raw_param(key)
440   request.params[key]
441 end
recovery_code_match?(code)
[show source]
    # File lib/rodauth/features/recovery_codes.rb
155 def recovery_code_match?(code)
156   recovery_codes.each do |s|
157     if timing_safe_eql?(code, s)
158       recovery_codes_ds.where(recovery_codes_column=>code).delete
159       if recovery_codes_primary?
160         add_recovery_code
161       end
162       return true
163     end
164   end
165   false
166 end
recovery_codes_ds()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
234 def recovery_codes_ds
235   db[recovery_codes_table].where(recovery_codes_id_column=>session_value)
236 end
recovery_codes_primary?()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
220 def recovery_codes_primary?
221   (features & [:otp, :sms_codes, :webauthn]).empty?
222 end
recovery_codes_remove()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
151 def recovery_codes_remove
152   recovery_codes_ds.delete
153 end
redirect(path)
[show source]
    # File lib/rodauth/features/base.rb
473 def redirect(path)
474   request.redirect(path)
475 end
redirect_two_factor_authenticated()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
235 def redirect_two_factor_authenticated
236   saved_two_factor_auth_redirect = remove_session_value(two_factor_auth_redirect_session_key)
237   redirect saved_two_factor_auth_redirect || two_factor_auth_redirect
238 end
remember_key_ds(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
196 def remember_key_ds(id=account_id)
197   db[remember_table].where(remember_id_column=>id)
198 end
remember_login()
[show source]
    # File lib/rodauth/features/remember.rb
128 def remember_login
129   get_remember_key
130   opts = Hash[remember_cookie_options]
131   opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
132   opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
133   ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
134 end
remove_all_active_sessions()
[show source]
   # File lib/rodauth/features/active_sessions.rb
83 def remove_all_active_sessions
84   active_sessions_ds.delete
85 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
79 def remove_current_session
80   active_sessions_ds.where(active_sessions_session_id_column=>compute_hmac(session[session_id_session_key])).delete
81 end
remove_email_auth_key()
[show source]
    # File lib/rodauth/features/email_auth.rb
126 def remove_email_auth_key
127   email_auth_ds.delete
128 end
remove_inactive_sessions()
[show source]
   # File lib/rodauth/features/active_sessions.rb
87 def remove_inactive_sessions
88   if cond = inactive_session_cond
89     active_sessions_ds.where(cond).delete
90   end
91 end
remove_jwt_refresh_token_key(token)
[show source]
    # File lib/rodauth/features/jwt_refresh.rb
132 def remove_jwt_refresh_token_key(token)
133   account_id, token = split_token(token)
134   token_id, _ = split_token(token)
135   jwt_refresh_token_account_token_ds(account_id, token_id).delete
136 end
remove_lockout_metadata()
[show source]
    # File lib/rodauth/features/lockout.rb
268 def remove_lockout_metadata
269   account_login_failures_ds.delete
270   account_lockouts_ds.delete
271 end
remove_remember_key(id=account_id)
[show source]
    # File lib/rodauth/features/remember.rb
166 def remove_remember_key(id=account_id)
167   remember_key_ds(id).delete
168 end
remove_reset_password_key()
[show source]
    # File lib/rodauth/features/reset_password.rb
177 def remove_reset_password_key
178   password_reset_ds.delete
179 end
remove_session_value(key)
[show source]
    # File lib/rodauth/features/base.rb
707 def remove_session_value(key)
708   session.delete(key)
709 end
remove_verify_account_key()
[show source]
    # File lib/rodauth/features/verify_account.rb
173 def remove_verify_account_key
174   verify_account_ds.delete
175 end
remove_verify_login_change_key()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
105 def remove_verify_login_change_key
106   verify_login_change_ds.delete
107 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
375 def render(page)
376   _view(:render, page)
377 end
render_multi_phase_login_forms()
[show source]
    # File lib/rodauth/features/login.rb
119 def render_multi_phase_login_forms
120   multi_phase_login_forms.sort.map{|_, form, _| form}.join("\n")
121 end
request()
[show source]
    # File lib/rodauth/features/base.rb
133 def request
134   scope.request
135 end
require_account()
[show source]
    # File lib/rodauth/features/base.rb
504 def require_account
505   require_authentication
506   require_account_session
507 end
require_account_session()
[show source]
    # File lib/rodauth/features/base.rb
509 def require_account_session
510   unless account_from_session
511     clear_session
512     login_required
513   end
514 end
require_authentication()
[show source]
    # File lib/rodauth/features/base.rb
329 def require_authentication
330   require_login
331 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
321 def require_login
322   login_required unless logged_in?
323 end
require_login_confirmation?()
[show source]
    # File lib/rodauth/features/verify_account.rb
165 def require_login_confirmation?
166   false
167 end
require_otp_setup()
[show source]
    # File lib/rodauth/features/otp.rb
228 def require_otp_setup
229   unless otp_exists?
230     set_redirect_error_status(two_factor_not_setup_error_status)
231     set_redirect_error_flash two_factor_not_setup_error_flash
232     redirect two_factor_need_setup_redirect
233   end
234 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_redirect_error_flash password_authentication_required_error_flash
57     set_session_value(confirm_password_redirect_session_key, request.fullpath)
58     redirect password_authentication_required_redirect
59   end
60 end
require_password_authentication?()
[show source]
   # File lib/rodauth/features/confirm_password.rb
86 def require_password_authentication?
87   return true if defined?(super) && super
88   !authenticated_by.include?('password')
89 end
require_sms_available()
[show source]
    # File lib/rodauth/features/sms_codes.rb
318 def require_sms_available
319   require_sms_setup
320 
321   if sms_locked_out?
322     set_redirect_error_status(lockout_error_status)
323     set_redirect_error_flash sms_lockout_error_flash
324     redirect sms_lockout_redirect
325   end
326 end
require_sms_not_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
310 def require_sms_not_setup
311   if sms_setup?
312     set_redirect_error_status(sms_already_setup_error_status)
313     set_redirect_error_flash sms_already_setup_error_flash
314     redirect sms_already_setup_redirect
315   end
316 end
require_sms_setup()
[show source]
    # File lib/rodauth/features/sms_codes.rb
302 def require_sms_setup
303   unless sms_setup?
304     set_redirect_error_status(two_factor_not_setup_error_status)
305     set_redirect_error_flash sms_not_setup_error_flash
306     redirect sms_needs_setup_redirect
307   end
308 end
require_two_factor_authenticated()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
159 def require_two_factor_authenticated
160   unless two_factor_authenticated?
161     if two_factor_auth_return_to_requested_location?
162       set_session_value(two_factor_auth_redirect_session_key, request.fullpath)
163     end
164     set_redirect_error_status(two_factor_need_authentication_error_status)
165     set_redirect_error_flash two_factor_need_authentication_error_flash
166     redirect two_factor_auth_required_redirect
167   end
168 end
require_two_factor_not_authenticated(auth_type = nil)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
151 def require_two_factor_not_authenticated(auth_type = nil)
152   if two_factor_authenticated? || (auth_type && two_factor_login_type_match?(auth_type))
153     set_redirect_error_status(two_factor_already_authenticated_error_status)
154     set_redirect_error_flash two_factor_already_authenticated_error_flash
155     redirect two_factor_already_authenticated_redirect
156   end
157 end
require_two_factor_setup()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
140 def require_two_factor_setup
141   # Avoid database query if already authenticated via 2nd factor
142   return if two_factor_authenticated?
143 
144   return if uses_two_factor_authentication?
145 
146   set_redirect_error_status(two_factor_not_setup_error_status)
147   set_redirect_error_flash two_factor_not_setup_error_flash
148   redirect two_factor_need_setup_redirect
149 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_redirect_error_flash webauthn_not_setup_error_flash
396     redirect two_factor_need_setup_redirect
397   end
398 end
reset_password_email_body()
[show source]
    # File lib/rodauth/features/reset_password.rb
247 def reset_password_email_body
248   render('reset-password-email')
249 end
reset_password_email_recently_sent?()
[show source]
    # File lib/rodauth/features/reset_password.rb
217 def reset_password_email_recently_sent?
218   (email_last_sent = get_reset_password_email_last_sent) && (Time.now - email_last_sent < reset_password_skip_resend_email_within)
219 end
reset_password_key_insert_hash()
[show source]
    # File lib/rodauth/features/reset_password.rb
255 def reset_password_key_insert_hash
256   hash = {reset_password_id_column=>account_id, reset_password_key_column=>reset_password_key_value}
257   set_deadline_value(hash, reset_password_deadline_column, reset_password_deadline_interval)
258   hash
259 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
137 def response
138   scope.response
139 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
659 def retry_on_uniqueness_violation(&block)
660   if raises_uniqueness_violation?(&block)
661     yield
662   end
663 end
return_json_response()
[show source]
    # File lib/rodauth/features/jwt.rb
268 def return_json_response
269   response.status ||= json_response_error_status if json_response[json_response_error_key]
270   set_jwt
271   response['Content-Type'] ||= json_response_content_type
272   response.write(_json_response_body(json_response))
273   request.halt
274 end
route!()
[show source]
    # File lib/rodauth/features/base.rb
149 def route!
150   if meth = self.class.route_hash[request.remaining_path]
151     send(meth)
152   end
153 
154   nil
155 end
route_path(route, opts={})
[show source]
    # File lib/rodauth/features/base.rb
477 def route_path(route, opts={})
478   path  = "#{prefix}/#{route}"
479   path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
480   path
481 end
route_url(route, opts={})
[show source]
    # File lib/rodauth/features/base.rb
483 def route_url(route, opts={})
484   "#{base_url}#{route_path(route, opts)}"
485 end
save_account()
[show source]
    # File lib/rodauth/features/create_account.rb
 98 def save_account
 99   id = nil
100   raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}
101 
102   if raised
103     @login_requirement_message = already_an_account_with_this_login_message
104   end
105 
106   if id
107     account[account_id_column] = id
108   end
109 
110   id && !raised
111 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
134 def send_email_auth_email
135   send_email(create_email_auth_email)
136 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
185 def send_reset_password_email
186   send_email(create_reset_password_email)
187 end
send_unlock_account_email()
[show source]
    # File lib/rodauth/features/lockout.rb
218 def send_unlock_account_email
219   send_email(create_unlock_account_email)
220 end
send_verify_account_email()
[show source]
    # File lib/rodauth/features/verify_account.rb
211 def send_verify_account_email
212   send_email(create_verify_account_email)
213 end
send_verify_login_change_email(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
121 def send_verify_login_change_email(login)
122   send_email(create_verify_login_change_email(login))
123 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
141 def session
142   scope.session
143 end
session_inactivity_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
129 def session_inactivity_deadline_condition
130   if deadline = session_inactivity_deadline
131     Sequel[active_sessions_last_use_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
132   end
133 end
session_jwt()
[show source]
    # File lib/rodauth/features/jwt.rb
117 def session_jwt
118   JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
119 end
session_lifetime_deadline_condition()
[show source]
    # File lib/rodauth/features/active_sessions.rb
135 def session_lifetime_deadline_condition
136   if deadline = session_lifetime_deadline
137     Sequel[active_sessions_created_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
138   end
139 end
session_value()
[show source]
    # File lib/rodauth/features/base.rb
241 def session_value
242   session[session_key]
243 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
695 def set_deadline_value(hash, column, interval)
696   if set_deadline_values?
697     # :nocov:
698     hash[column] = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, interval)
699     # :nocov:
700   end
701 end
set_deadline_values?()
[show source]
    # File lib/rodauth/features/base.rb
542 def set_deadline_values?
543   db.database_type == :mysql
544 end
set_email_auth_email_last_sent()
[show source]
    # File lib/rodauth/features/email_auth.rb
114 def set_email_auth_email_last_sent
115    email_auth_ds.update(email_auth_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if email_auth_email_last_sent_column
116 end
set_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
305 def set_error_flash(message)
306   flash.now[flash_error_key] = message
307 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
157 def set_field_error(field, error)
158   (@field_errors ||= {})[field] = error
159 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
276 def set_jwt
277   set_jwt_token(session_jwt)
278 end
set_jwt_token(token)
[show source]
    # File lib/rodauth/features/jwt.rb
129 def set_jwt_token(token)
130   response.headers['Authorization'] = token
131 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_new_account_password(password)
[show source]
   # File lib/rodauth/features/create_account.rb
90 def set_new_account_password(password)
91   account[account_password_hash_column] = password_hash(password)
92 end
set_notice_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
313 def set_notice_flash(message)
314   flash[flash_notice_key] = message
315 end
set_notice_now_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
317 def set_notice_now_flash(message)
318   flash.now[flash_notice_key] = message
319 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_redirect_error_flash(message)
[show source]
    # File lib/rodauth/features/base.rb
309 def set_redirect_error_flash(message)
310   flash[flash_error_key] = message
311 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
521 def set_redirect_error_status(status)
522 end
set_reset_password_email_last_sent()
[show source]
    # File lib/rodauth/features/reset_password.rb
199 def set_reset_password_email_last_sent
200    password_reset_ds.update(reset_password_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if reset_password_email_last_sent_column
201 end
set_response_error_status(status)
[show source]
    # File lib/rodauth/features/base.rb
524 def set_response_error_status(status)
525   response.status = status
526 end
set_session_value(key, value)
[show source]
    # File lib/rodauth/features/base.rb
703 def set_session_value(key, value)
704   session[key] = value
705 end
set_single_session_key(data)
[show source]
   # File lib/rodauth/features/single_session.rb
92 def set_single_session_key(data)
93   data = compute_hmac(data) if hmac_secret
94   set_session_value(single_session_session_key, data)
95 end
set_title(title)
[show source]
    # File lib/rodauth/features/base.rb
299 def set_title(title)
300   if title_instance_variable
301     scope.instance_variable_set(title_instance_variable, title)
302   end
303 end
set_unlock_account_email_last_sent()
[show source]
    # File lib/rodauth/features/lockout.rb
234 def set_unlock_account_email_last_sent
235   account_lockouts_ds.update(account_lockouts_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if account_lockouts_email_last_sent_column
236 end
set_verify_account_email_last_sent()
[show source]
    # File lib/rodauth/features/verify_account.rb
236 def set_verify_account_email_last_sent
237    verify_account_ds.update(verify_account_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if verify_account_email_last_sent_column
238 end
setup_account_verification()
[show source]
    # File lib/rodauth/features/verify_account.rb
279 def setup_account_verification
280   generate_verify_account_key_value
281   create_verify_account_key
282   send_verify_account_email
283 end
show_lockout_page()
[show source]
    # File lib/rodauth/features/lockout.rb
273 def show_lockout_page
274   set_response_error_status lockout_error_status
275   set_error_flash login_lockout_error_flash
276   response.write unlock_account_request_view
277   request.halt
278 end
single_session_ds()
[show source]
    # File lib/rodauth/features/single_session.rb
 97 def single_session_ds
 98   db[single_session_table].
 99     where(single_session_id_column=>session_value)
100 end
skip_login_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
101 def skip_login_field_on_login?
102   return false unless use_multi_phase_login?
103   valid_login_entered?
104 end
skip_password_field_on_login?()
[show source]
    # File lib/rodauth/features/login.rb
106 def skip_password_field_on_login?
107   return false unless use_multi_phase_login?
108   !valid_login_entered?
109 end
skip_status_checks?()
[show source]
   # File lib/rodauth/features/close_account.rb
82 def skip_status_checks?
83   false
84 end
sms_auth_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
378 def sms_auth_message(code)
379   "SMS authentication code for #{domain} is #{code}"
380 end
sms_available?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
420 def sms_available?
421   sms && !sms_needs_confirmation? && !sms_locked_out?
422 end
sms_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
399 def sms_code
400   sms[sms_code_column]
401 end
sms_code_issued_at()
[show source]
    # File lib/rodauth/features/sms_codes.rb
403 def sms_code_issued_at
404   convert_timestamp(sms[sms_issued_at_column])
405 end
sms_code_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
328 def sms_code_match?(code)
329   return false unless sms_current_auth?
330   timing_safe_eql?(code, sms_code)
331 end
sms_codes_primary?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
463 def sms_codes_primary?
464   (features & [:otp, :webauthn]).empty?
465 end
sms_confirm()
[show source]
    # File lib/rodauth/features/recovery_codes.rb
141 def sms_confirm
142   super if defined?(super)
143   auto_add_missing_recovery_codes
144 end
sms_confirm_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
342 def sms_confirm_failure
343   sms_ds.delete
344 end
sms_confirm_message(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
382 def sms_confirm_message(code)
383   "SMS confirmation code for #{domain} is #{code}"
384 end
sms_confirmation_match?(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
333 def sms_confirmation_match?(code)
334   sms_needs_confirmation? && sms_code_match?(code)
335 end
sms_current_auth?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
428 def sms_current_auth?
429   sms_code && sms_code_issued_at + sms_code_allowed_seconds > Time.now
430 end
sms_disable()
[show source]
    # File lib/rodauth/features/sms_codes.rb
337 def sms_disable
338   sms_ds.delete
339   @sms = nil
340 end
sms_ds()
[show source]
    # File lib/rodauth/features/sms_codes.rb
491 def sms_ds
492   db[sms_codes_table].where(sms_id_column=>session_value)
493 end
sms_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
407 def sms_failures
408   sms[sms_failures_column]
409 end
sms_locked_out?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
424 def sms_locked_out?
425   sms_failures >= sms_failure_limit
426 end
sms_needs_confirmation?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
416 def sms_needs_confirmation?
417   sms && sms_failures.nil?
418 end
sms_new_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
471 def sms_new_auth_code
472   SecureRandom.random_number(10**sms_auth_code_length).to_s.rjust(sms_auth_code_length, "0")
473 end
sms_new_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
475 def sms_new_confirm_code
476   SecureRandom.random_number(10**sms_confirm_code_length).to_s.rjust(sms_confirm_code_length, "0")
477 end
sms_normalize_phone(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
467 def sms_normalize_phone(phone)
468   phone.to_s.gsub(/\D+/, '')
469 end
sms_phone()
[show source]
    # File lib/rodauth/features/sms_codes.rb
395 def sms_phone
396   sms[sms_phone_column]
397 end
sms_record_failure()
[show source]
    # File lib/rodauth/features/sms_codes.rb
390 def sms_record_failure
391   update_sms(sms_failures_column=>Sequel.expr(sms_failures_column)+1)
392   sms[sms_failures_column] = sms_ds.get(sms_failures_column)
393 end
sms_remove_failures()
[show source]
    # File lib/rodauth/features/sms_codes.rb
353 def sms_remove_failures
354   update_sms(sms_failures_column => 0, sms_code_column => nil)
355 end
sms_send(phone, message)
[show source]
    # File lib/rodauth/features/sms_codes.rb
479 def sms_send(phone, message)
480   raise NotImplementedError, "sms_send needs to be defined in the Rodauth configuration for SMS sending to work"
481 end
sms_send_auth_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
362 def sms_send_auth_code
363   code = sms_new_auth_code
364   sms_set_code(code)
365   sms_send(sms_phone, sms_auth_message(code))
366 end
sms_send_confirm_code()
[show source]
    # File lib/rodauth/features/sms_codes.rb
368 def sms_send_confirm_code
369   code = sms_new_confirm_code
370   sms_set_code(code)
371   sms_send(sms_phone, sms_confirm_message(code))
372 end
sms_set_code(code)
[show source]
    # File lib/rodauth/features/sms_codes.rb
386 def sms_set_code(code)
387  update_sms(sms_code_column=>code, sms_issued_at_column=>Sequel::CURRENT_TIMESTAMP)
388 end
sms_setup(phone_number)
[show source]
    # File lib/rodauth/features/sms_codes.rb
346 def sms_setup(phone_number)
347   # Cannot handle uniqueness violation here, as the phone number given may not match the
348   # one in the table.
349   sms_ds.insert(sms_id_column=>session_value, sms_phone_column=>phone_number)
350   remove_instance_variable(:@sms) if instance_variable_defined?(:@sms)
351 end
sms_setup?()
[show source]
    # File lib/rodauth/features/sms_codes.rb
411 def sms_setup?
412   return false unless sms
413   !sms_needs_confirmation?
414 end
sms_valid_phone?(phone)
[show source]
    # File lib/rodauth/features/sms_codes.rb
374 def sms_valid_phone?(phone)
375   phone.length >= sms_phone_min_length
376 end
split_token(token)
[show source]
    # File lib/rodauth/features/base.rb
469 def split_token(token)
470   token.split(token_separator, 2)
471 end
template_path(page)
[show source]
    # File lib/rodauth/features/base.rb
628 def template_path(page)
629   File.join(File.dirname(__FILE__), '../../../templates', "#{page}.str")
630 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
528 def throw_error(field, error)
529   set_field_error(field, error)
530   throw :rodauth_error
531 end
throw_error_status(status, field, error)
[show source]
    # File lib/rodauth/features/base.rb
533 def throw_error_status(status, field, error)
534   set_response_error_status(status)
535   throw_error(field, error)
536 end
timing_safe_eql?(provided, actual)
[show source]
    # File lib/rodauth/features/base.rb
499 def timing_safe_eql?(provided, actual)
500   provided = provided.to_s
501   Rack::Utils.secure_compare(provided.ljust(actual.length), actual) && provided.length == actual.length
502 end
transaction(opts={}, &block)
[show source]
    # File lib/rodauth/features/base.rb
487 def transaction(opts={}, &block)
488   db.transaction(opts, &block)
489 end
translate(_key, default)
[show source]
    # File lib/rodauth/features/base.rb
224 def translate(_key, default)
225   # do not attempt to translate by default
226   default
227 end
two_factor_authenticate(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
227 def two_factor_authenticate(type)
228   two_factor_update_session(type)
229   two_factor_remove_auth_failures
230   after_two_factor_authentication
231   set_notice_flash two_factor_auth_notice_flash
232   redirect_two_factor_authenticated
233 end
two_factor_authenticated?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
182 def two_factor_authenticated?
183   authenticated_by && authenticated_by.length >= 2
184 end
two_factor_authentication_setup?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
186 def two_factor_authentication_setup?
187   possible_authentication_methods.length >= 2
188 end
two_factor_login_type_match?(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
196 def two_factor_login_type_match?(type)
197   authenticated_by && authenticated_by.include?(type)
198 end
two_factor_modifications_require_password?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
116 def two_factor_modifications_require_password?
117   modifications_require_password?
118 end
two_factor_password_match?(password)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
174 def two_factor_password_match?(password)
175   if two_factor_modifications_require_password?
176     password_match?(password)
177   else
178     true
179   end
180 end
two_factor_remove()
[show source]
    # File lib/rodauth/features/otp.rb
218 def two_factor_remove
219   super
220   otp_remove
221 end
two_factor_remove_auth_failures()
[show source]
    # File lib/rodauth/features/otp.rb
223 def two_factor_remove_auth_failures
224   super
225   otp_remove_auth_failures
226 end
two_factor_remove_session(type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
240 def two_factor_remove_session(type)
241   authenticated_by.delete(type)
242   remove_session_value(two_factor_setup_session_key)
243   if authenticated_by.empty?
244     clear_session
245   end
246 end
two_factor_update_session(auth_type)
[show source]
    # File lib/rodauth/features/two_factor_base.rb
248 def two_factor_update_session(auth_type)
249   authenticated_by << auth_type
250   set_session_value(two_factor_setup_session_key, true)
251 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
677 def unique_constraint_violation_class
678   if db.adapter_scheme == :jdbc && db.database_type == :sqlite
679     # :nocov:
680     Sequel::ConstraintViolation
681     # :nocov:
682   else
683     Sequel::UniqueConstraintViolation
684   end
685 end
unlock_account()
[show source]
    # File lib/rodauth/features/lockout.rb
158 def unlock_account
159   transaction do
160     remove_lockout_metadata
161   end
162 end
unlock_account_email_body()
[show source]
    # File lib/rodauth/features/lockout.rb
284 def unlock_account_email_body
285   render('unlock-account-email')
286 end
unlock_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/lockout.rb
288 def unlock_account_email_recently_sent?
289   (email_last_sent = get_unlock_account_email_last_sent) && (Time.now - email_last_sent < unlock_account_skip_resend_email_within)
290 end
update_account(values, ds=account_ds)
[show source]
    # File lib/rodauth/features/base.rb
721 def update_account(values, ds=account_ds)
722   update_hash_ds(account, ds, values)
723 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_hash_ds(hash, ds, values)
[show source]
    # File lib/rodauth/features/base.rb
711 def update_hash_ds(hash, ds, values)
712   num = ds.update(values)
713   if num == 1
714     values.each do |k, v|
715       account[k] = v == Sequel::CURRENT_TIMESTAMP ? Time.now : v
716     end
717   end
718   num
719 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
76 def update_login(login)
77   _update_login(login)
78 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
64 def update_single_session_key
65   key = random_key
66   set_single_session_key(key)
67   if single_session_ds.update(single_session_key_column=>key) == 0
68     # Don't handle uniqueness violations here.  While we could get the stored key from the
69     # database, it could lead to two sessions sharing the same key, which this feature is
70     # designed to prevent.
71     single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key)
72   end
73 end
update_sms(values)
[show source]
    # File lib/rodauth/features/sms_codes.rb
483 def update_sms(values)
484   update_hash_ds(sms, sms_ds, values)
485 end
use_database_authentication_functions?()
[show source]
    # File lib/rodauth/features/base.rb
546 def use_database_authentication_functions?
547   case db.database_type
548   when :postgres, :mysql, :mssql
549     true
550   else
551     # :nocov:
552     false
553     # :nocov:
554   end
555 end
use_date_arithmetic?()
[show source]
    # File lib/rodauth/features/active_sessions.rb
153 def use_date_arithmetic?
154   true
155 end
use_jwt?()
[show source]
    # File lib/rodauth/features/jwt.rb
133 def use_jwt?
134   jwt_token || only_json? || json_request?
135 end
use_multi_phase_login?()
[show source]
    # File lib/rodauth/features/email_auth.rb
159 def use_multi_phase_login?
160   true
161 end
use_request_specific_csrf_tokens?()
[show source]
    # File lib/rodauth/features/base.rb
557 def use_request_specific_csrf_tokens?
558   scope.opts[:rodauth_route_csrf] && scope.use_request_specific_csrf_tokens?
559 end
uses_two_factor_authentication?()
[show source]
    # File lib/rodauth/features/two_factor_base.rb
190 def uses_two_factor_authentication?
191   return false unless logged_in?
192   set_session_value(two_factor_setup_session_key, two_factor_authentication_setup?) unless session.has_key?(two_factor_setup_session_key)
193   session[two_factor_setup_session_key]
194 end
valid_jwt?()
[show source]
    # File lib/rodauth/features/jwt.rb
137 def valid_jwt?
138   !!(jwt_token && jwt_payload)
139 end
valid_login_entered?()
[show source]
    # File lib/rodauth/features/login.rb
111 def valid_login_entered?
112   @valid_login_entered
113 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
177 def verify_account
178   update_account(account_status_column=>account_open_status_value) == 1
179 end
verify_account_check_already_logged_in()
[show source]
    # File lib/rodauth/features/verify_account.rb
285 def verify_account_check_already_logged_in
286   check_already_logged_in
287 end
verify_account_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_account.rb
318 def verify_account_ds(id=account_id)
319   db[verify_account_table].where(verify_account_id_column=>id)
320 end
verify_account_email_body()
[show source]
    # File lib/rodauth/features/verify_account.rb
314 def verify_account_email_body
315   render('verify-account-email')
316 end
verify_account_email_recently_sent?()
[show source]
    # File lib/rodauth/features/verify_account.rb
258 def verify_account_email_recently_sent?
259   (email_last_sent = get_verify_account_email_last_sent) && (Time.now - email_last_sent < verify_account_skip_resend_email_within)
260 end
verify_account_email_resend()
[show source]
    # File lib/rodauth/features/verify_account.rb
181 def verify_account_email_resend
182   if @verify_account_key_value = get_verify_account_key(account_id)
183     set_verify_account_email_last_sent
184     send_verify_account_email
185     true
186   end
187 end
verify_account_key_insert_hash()
[show source]
    # File lib/rodauth/features/verify_account.rb
306 def verify_account_key_insert_hash
307   {verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
308 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
109 def verify_login_change
110   unless res = _update_login(verify_login_change_new_login)
111     remove_verify_login_change_key
112   end
113 
114   res
115 end
verify_login_change_ds(id=account_id)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
203 def verify_login_change_ds(id=account_id)
204   db[verify_login_change_table].where(verify_login_change_id_column=>id)
205 end
verify_login_change_email_body()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
199 def verify_login_change_email_body
200   render('verify-login-change-email')
201 end
verify_login_change_key_insert_hash(login)
[show source]
    # File lib/rodauth/features/verify_login_change.rb
189 def verify_login_change_key_insert_hash(login)
190   hash = {verify_login_change_id_column=>account_id, verify_login_change_key_column=>verify_login_change_key_value, verify_login_change_login_column=>login}
191   set_deadline_value(hash, verify_login_change_deadline_column, verify_login_change_deadline_interval)
192   hash
193 end
verify_login_change_old_login()
[show source]
    # File lib/rodauth/features/verify_login_change.rb
137 def verify_login_change_old_login
138   account_ds.get(login_column)
139 end
view(page, title)
[show source]
    # File lib/rodauth/features/base.rb
370 def view(page, title)
371   set_title(title)
372   _view(:view, page)
373 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
435 def webauthn_account_id
436   session_value
437 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
447 def webauthn_auth_credential_from_form_submission
448   case auth_data = raw_param(webauthn_auth_param)
449   when String
450     begin
451       auth_data = JSON.parse(auth_data)
452     rescue
453       throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
454     end
455   when Hash
456     # nothing
457   else
458     throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
459   end
460 
461   begin
462     webauthn_credential = WebAuthn::Credential.from_get(auth_data)
463     unless valid_webauthn_credential_auth?(webauthn_credential)
464       throw_error_status(invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
465     end
466   rescue WebAuthn::SignCountVerificationError
467     handle_webauthn_sign_count_verification_error
468   rescue WebAuthn::Error, RuntimeError, NoMethodError
469     throw_error_status(invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
470   end
471 
472   webauthn_credential
473 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
443 def webauthn_keys_ds
444   db[webauthn_keys_table].where(webauthn_keys_account_id_column => webauthn_account_id)
445 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
475 def webauthn_setup_credential_from_form_submission
476   case setup_data = raw_param(webauthn_setup_param)
477   when String
478     begin
479       setup_data = JSON.parse(setup_data)
480     rescue
481       throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
482     end
483   when Hash
484     # nothing
485   else
486     throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
487   end
488 
489   unless two_factor_password_match?(param(password_param))
490     throw_error_status(invalid_password_error_status, password_param, invalid_password_message)
491   end
492 
493   begin
494     webauthn_credential = WebAuthn::Credential.from_create(setup_data)
495     unless valid_new_webauthn_credential?(webauthn_credential)
496       throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
497     end
498   rescue WebAuthn::Error, RuntimeError, NoMethodError
499     throw_error_status(invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
500   end
501 
502   webauthn_credential
503 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
439 def webauthn_user_ids_ds
440   db[webauthn_user_ids_table].where(webauthn_user_ids_account_id_column => webauthn_account_id)
441 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