module Rodauth

  1. lib/rodauth.rb
  2. lib/rodauth/features/account_expiration.rb
  3. lib/rodauth/features/base.rb
  4. lib/rodauth/features/change_login.rb
  5. lib/rodauth/features/change_password.rb
  6. lib/rodauth/features/change_password_notify.rb
  7. lib/rodauth/features/close_account.rb
  8. lib/rodauth/features/confirm_password.rb
  9. lib/rodauth/features/create_account.rb
  10. lib/rodauth/features/disallow_common_passwords.rb
  11. lib/rodauth/features/disallow_password_reuse.rb
  12. lib/rodauth/features/email_base.rb
  13. lib/rodauth/features/http_basic_auth.rb
  14. lib/rodauth/features/jwt.rb
  15. lib/rodauth/features/lockout.rb
  16. lib/rodauth/features/login.rb
  17. lib/rodauth/features/login_password_requirements_base.rb
  18. lib/rodauth/features/logout.rb
  19. lib/rodauth/features/otp.rb
  20. lib/rodauth/features/password_complexity.rb
  21. lib/rodauth/features/password_expiration.rb
  22. lib/rodauth/features/password_grace_period.rb
  23. lib/rodauth/features/recovery_codes.rb
  24. lib/rodauth/features/remember.rb
  25. lib/rodauth/features/reset_password.rb
  26. lib/rodauth/features/session_expiration.rb
  27. lib/rodauth/features/single_session.rb
  28. lib/rodauth/features/sms_codes.rb
  29. lib/rodauth/features/two_factor_base.rb
  30. lib/rodauth/features/update_password_hash.rb
  31. lib/rodauth/features/verify_account.rb
  32. lib/rodauth/features/verify_account_grace_period.rb
  33. lib/rodauth/features/verify_change_login.rb
  34. lib/rodauth/features/verify_login_change.rb
  35. lib/rodauth/migrations.rb
  36. lib/rodauth/version.rb
  37. 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_login
  2. _account_from_reset_password_key
  3. _account_from_session
  4. _account_from_unlock_key
  5. _account_from_verify_account_key
  6. _account_from_verify_login_change_key
  7. _json_response_body
  8. _new_account
  9. _otp
  10. _otp_add_key
  11. _otp_key
  12. _otp_tmp_key
  13. _recovery_codes
  14. _sms
  15. _two_factor_auth_required_redirect
  16. _view
  17. _view_opts
  18. account_activity_ds
  19. account_ds
  20. account_expired?
  21. account_expired_at
  22. account_from_key
  23. account_from_login
  24. account_from_reset_password_key
  25. account_from_session
  26. account_from_unlock_key
  27. account_from_verify_account_key
  28. account_from_verify_login_change_key
  29. account_id
  30. account_in_unverified_grace_period?
  31. account_initial_status_value
  32. account_lockouts_ds
  33. account_login_failures_ds
  34. account_model
  35. account_password_hash_column
  36. account_session_status_filter
  37. active_remember_key_ds
  38. add_previous_password_hash
  39. add_recovery_code
  40. add_recovery_codes
  41. add_remember_key
  42. after_change_login
  43. after_change_password
  44. after_close_account
  45. after_confirm_password
  46. after_create_account
  47. after_login
  48. after_login_failure
  49. after_logout
  50. after_reset_password
  51. allow_resending_verify_account_email?
  52. already_logged_in
  53. auth_class_eval
  54. authenticated?
  55. before_change_login_route
  56. before_change_password_route
  57. before_login_attempt
  58. before_logout
  59. before_reset_password
  60. before_reset_password_request
  61. before_rodauth
  62. before_unlock_account
  63. before_unlock_account_request
  64. before_view_recovery_codes
  65. button
  66. button_opts
  67. can_add_recovery_codes?
  68. catch_error
  69. change_login
  70. change_login_notice_flash
  71. change_login_requires_password?
  72. change_password_requires_password?
  73. check_account_expiration
  74. check_already_logged_in
  75. check_password_change_allowed
  76. check_session_expiration
  77. check_single_session
  78. clear_cached_otp
  79. clear_invalid_login_attempts
  80. clear_remembered_session_key
  81. clear_session
  82. close_account
  83. close_account_requires_password?
  84. confirm_password
  85. confirm_password_redirect
  86. convert_session_key
  87. convert_timestamp
  88. create_account_autologin?
  89. create_account_link
  90. create_account_notice_flash
  91. create_account_set_password?
  92. create_email
  93. create_email_to
  94. create_password_changed_email
  95. create_reset_password_email
  96. create_reset_password_key
  97. create_unlock_account_email
  98. create_verify_account_email
  99. create_verify_account_key
  100. create_verify_login_change_email
  101. create_verify_login_change_key
  102. csrf_tag
  103. currently_active_session?
  104. db
  105. delete_account
  106. delete_account_on_close?
  107. disable_remember_login
  108. email_from
  109. email_to
  110. expire_session
  111. features
  112. field_error
  113. flash
  114. forget_login
  115. function_name
  116. generate_remember_key_value
  117. generate_reset_password_key_value
  118. generate_unlock_account_key
  119. generate_verify_account_key_value
  120. generate_verify_login_change_key_value
  121. get_activity_timestamp
  122. get_password_changed_at
  123. get_password_hash
  124. get_password_reset_key
  125. get_remember_key
  126. get_unlock_account_key
  127. get_verify_account_key
  128. get_verify_login_change_login_and_key
  129. include_success_messages?
  130. invalid_login_attempted
  131. invalid_previous_password_message
  132. json_request?
  133. json_response
  134. jwt_payload
  135. jwt_secret
  136. jwt_session_hash
  137. jwt_token
  138. last_account_activity_at
  139. last_account_login_at
  140. load_memory
  141. loaded_templates
  142. locked_out?
  143. logged_in_via_remember_key?
  144. login_confirm_label
  145. login_does_not_meet_requirements_message
  146. login_failed_reset_password_request_form
  147. login_form_footer
  148. login_meets_email_requirements?
  149. login_meets_length_requirements?
  150. login_meets_requirements?
  151. login_required
  152. login_too_long_message
  153. login_too_short_message
  154. logout
  155. modifications_require_password?
  156. new_account
  157. new_recovery_code
  158. no_longer_active_session
  159. only_json?
  160. open_account?
  161. otp_add_key
  162. otp_auth_form_footer
  163. otp_exists?
  164. otp_issuer
  165. otp_key_ds
  166. otp_locked_out?
  167. otp_lockout_error_flash
  168. otp_lockout_redirect
  169. otp_new_secret
  170. otp_provisioning_name
  171. otp_provisioning_uri
  172. otp_qr_code
  173. otp_record_authentication_failure
  174. otp_remove
  175. otp_remove_auth_failures
  176. otp_tmp_key
  177. otp_update_last_use
  178. otp_valid_code?
  179. otp_valid_key?
  180. param
  181. param_or_nil
  182. password_changed_email_body
  183. password_confirm_label
  184. password_does_not_contain_null_byte?
  185. password_does_not_meet_requirements_message
  186. password_doesnt_match_previous_password?
  187. password_expiration_ds
  188. password_expired?
  189. password_has_enough_character_groups?
  190. password_has_no_invalid_pattern?
  191. password_hash
  192. password_hash_cost
  193. password_hash_ds
  194. password_match?
  195. password_meets_length_requirements?
  196. password_meets_requirements?
  197. password_not_in_dictionary?
  198. password_not_one_of_the_most_common?
  199. password_not_too_many_repeating_characters?
  200. password_one_of_most_common?
  201. password_recently_entered?
  202. password_reset_ds
  203. password_too_many_repeating_characters_message
  204. password_too_short_message
  205. post_configure
  206. previous_password_ds
  207. raises_uniqueness_violation?
  208. random_key
  209. recovery_code_match?
  210. recovery_codes_ds
  211. recovery_codes_primary?
  212. recovery_codes_remove
  213. redirect
  214. remember_key_ds
  215. remember_login
  216. remove_lockout_metadata
  217. remove_remember_key
  218. remove_reset_password_key
  219. remove_verify_account_key
  220. remove_verify_login_change_key
  221. render
  222. request
  223. require_account
  224. require_account_session
  225. require_authentication
  226. require_current_password
  227. require_login
  228. require_otp_setup
  229. require_sms_available
  230. require_sms_not_setup
  231. require_sms_setup
  232. require_two_factor_authenticated
  233. require_two_factor_not_authenticated
  234. require_two_factor_setup
  235. reset_password_email_body
  236. reset_password_email_link
  237. reset_password_key_insert_hash
  238. reset_password_request_link
  239. reset_single_session_key
  240. response
  241. retry_on_uniqueness_violation
  242. return_json_response
  243. route!
  244. save_account
  245. send_password_changed_email
  246. send_reset_password_email
  247. send_unlock_account_email
  248. send_verify_account_email
  249. send_verify_login_change_email
  250. session
  251. session_expiration_redirect
  252. session_jwt
  253. session_value
  254. set_deadline_value
  255. set_deadline_values?
  256. set_error_flash
  257. set_expired
  258. set_field_error
  259. set_http_basic_auth_error_response
  260. set_jwt
  261. set_jwt_token
  262. set_last_password_entry
  263. set_new_account_password
  264. set_notice_flash
  265. set_notice_now_flash
  266. set_password
  267. set_redirect_error_flash
  268. set_redirect_error_status
  269. set_response_error_status
  270. set_session_value
  271. set_title
  272. setup_account_verification
  273. show_lockout_page
  274. single_session_ds
  275. skip_status_checks?
  276. sms_auth_message
  277. sms_available?
  278. sms_code
  279. sms_code_issued_at
  280. sms_code_match?
  281. sms_codes_primary?
  282. sms_confirm
  283. sms_confirm_failure
  284. sms_confirm_message
  285. sms_confirmation_match?
  286. sms_current_auth?
  287. sms_disable
  288. sms_ds
  289. sms_failures
  290. sms_locked_out?
  291. sms_lockout_redirect
  292. sms_needs_confirmation?
  293. sms_new_auth_code
  294. sms_new_confirm_code
  295. sms_normalize_phone
  296. sms_phone
  297. sms_record_failure
  298. sms_remove_failures
  299. sms_send
  300. sms_send_auth_code
  301. sms_send_confirm_code
  302. sms_set_code
  303. sms_setup
  304. sms_setup?
  305. sms_valid_phone?
  306. split_token
  307. template_path
  308. throw_basic_auth_error
  309. throw_error
  310. throw_error_status
  311. timing_safe_eql?
  312. token_link
  313. transaction
  314. two_factor_auth_fallback_redirect
  315. two_factor_auth_required_redirect
  316. two_factor_authenticate
  317. two_factor_authenticated?
  318. two_factor_authentication_setup?
  319. two_factor_modifications_require_password?
  320. two_factor_need_setup_redirect
  321. two_factor_password_match?
  322. two_factor_remove
  323. two_factor_remove_auth_failures
  324. two_factor_remove_session
  325. two_factor_update_session
  326. unique_constraint_violation_class
  327. unlock_account
  328. unlock_account_email_body
  329. unlock_account_email_link
  330. update_account
  331. update_activity
  332. update_hash_ds
  333. update_last_activity
  334. update_last_login
  335. update_login
  336. update_password_changed_at
  337. update_password_hash?
  338. update_session
  339. update_single_session_key
  340. update_sms
  341. use_database_authentication_functions?
  342. use_date_arithmetic?
  343. use_jwt?
  344. use_request_specific_csrf_tokens?
  345. uses_two_factor_authentication?
  346. valid_jwt?
  347. verified_account?
  348. verify_account
  349. verify_account_check_already_logged_in
  350. verify_account_ds
  351. verify_account_email_body
  352. verify_account_email_link
  353. verify_account_email_resend
  354. verify_account_key_insert_hash
  355. verify_account_resend_link
  356. verify_login_change
  357. verify_login_change_ds
  358. verify_login_change_email_body
  359. verify_login_change_email_link
  360. verify_login_change_key_insert_hash
  361. verify_login_change_old_login
  362. view

Constants

FEATURES = {}  
MAJOR = 1  

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

MINOR = 18  

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, line 32
def self.configure(app, opts={}, &block)
  app.opts[:rodauth_json] = opts.fetch(:json, app.opts[:rodauth_json])
  app.opts[:rodauth_csrf] = opts.fetch(:csrf, app.opts[:rodauth_route_csrf])
  auth_class = (app.opts[:rodauths] ||= {})[opts[:name]] ||= Class.new(Auth)
  if !auth_class.roda_class
    auth_class.roda_class = app
  elsif auth_class.roda_class != app
    auth_class = app.opts[:rodauths][opts[:name]] = Class.new(auth_class)
    auth_class.roda_class = app
  end
  auth_class.configure(&block)
end
create_database_authentication_functions (db, opts={})
[show source]
# File lib/rodauth/migrations.rb, line 3
  def self.create_database_authentication_functions(db, opts={})
    table_name = opts[:table_name] || :account_password_hashes
    get_salt_name = opts[:get_salt_name] || :rodauth_get_salt
    valid_hash_name = opts[:valid_hash_name] || :rodauth_valid_password_hash 

    case db.database_type
    when :postgres
      search_path = opts[:search_path] || 'public, pg_temp'

      db.run <<END
CREATE OR REPLACE FUNCTION #{get_salt_name}(acct_id int8) RETURNS text AS $$
DECLARE salt text;
BEGIN
SELECT substr(password_hash, 0, 30) INTO salt 
FROM #{table_name}
WHERE acct_id = id;
RETURN salt;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = #{search_path};
END

      db.run <<END
CREATE OR REPLACE FUNCTION #{valid_hash_name}(acct_id int8, hash text) RETURNS boolean AS $$
DECLARE valid boolean;
BEGIN
SELECT password_hash = hash INTO valid 
FROM #{table_name}
WHERE acct_id = id;
RETURN valid;
END;
$$ LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = #{search_path};
END
    when :mysql
      db.run <<END
CREATE FUNCTION #{get_salt_name}(acct_id int8) RETURNS varchar(255)
SQL SECURITY DEFINER
READS SQL DATA
BEGIN
DECLARE salt varchar(255);
DECLARE csr CURSOR FOR
SELECT substr(password_hash, 1, 30)
FROM #{table_name}
WHERE acct_id = id;
OPEN csr;
FETCH csr INTO salt;
CLOSE csr;
RETURN salt;
END;
END

      db.run <<END
CREATE FUNCTION #{valid_hash_name}(acct_id int8, hash varchar(255)) RETURNS tinyint(1)
SQL SECURITY DEFINER
READS SQL DATA
BEGIN
DECLARE valid tinyint(1);
DECLARE csr CURSOR FOR 
SELECT password_hash = hash
FROM #{table_name}
WHERE acct_id = id;
OPEN csr;
FETCH csr INTO valid;
CLOSE csr;
RETURN valid;
END;
END
    when :mssql
      db.run <<END
CREATE FUNCTION #{get_salt_name}(@account_id bigint) RETURNS nvarchar(255)
WITH EXECUTE AS OWNER
AS
BEGIN
DECLARE @salt nvarchar(255);
SELECT @salt = substring(password_hash, 0, 30)
FROM #{table_name}
WHERE id = @account_id;
RETURN @salt;
END;
END

      db.run <<END
CREATE FUNCTION #{valid_hash_name}(@account_id bigint, @hash nvarchar(255)) RETURNS bit
WITH EXECUTE AS OWNER
AS
BEGIN
DECLARE @valid bit;
DECLARE @ph nvarchar(255);
SELECT @ph = password_hash
FROM #{table_name}
WHERE id = @account_id;
IF(@hash = @ph)
  SET @valid = 1;
ELSE
  SET @valid = 0
RETURN @valid;
END;
END
    end
  end
create_database_previous_password_check_functions (db, opts={})
[show source]
# File lib/rodauth/migrations.rb, line 121
def self.create_database_previous_password_check_functions(db, opts={})
  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))
end
drop_database_authentication_functions (db, opts={})
[show source]
# File lib/rodauth/migrations.rb, line 107
def self.drop_database_authentication_functions(db, opts={})
  get_salt_name = opts[:get_salt_name] || :rodauth_get_salt
  valid_hash_name = opts[:valid_hash_name] || :rodauth_valid_password_hash 

  case db.database_type
  when :postgres
    db.run "DROP FUNCTION #{get_salt_name}(int8)"
    db.run "DROP FUNCTION #{valid_hash_name}(int8, text)"
  when :mysql, :mssql
    db.run "DROP FUNCTION #{get_salt_name}"
    db.run "DROP FUNCTION #{valid_hash_name}"
  end
end
drop_database_previous_password_check_functions (db, opts={})
[show source]
# File lib/rodauth/migrations.rb, line 125
def self.drop_database_previous_password_check_functions(db, opts={})
  drop_database_authentication_functions(db, {:get_salt_name=>:rodauth_get_previous_salt, :valid_hash_name=>:rodauth_previous_password_hash_match}.merge(opts))
end
load_dependencies (app, opts={})
[show source]
# File lib/rodauth.rb, line 5
def self.load_dependencies(app, opts={})
  json_opt = opts.fetch(:json, app.opts[:rodauth_json])
  if json_opt
    app.plugin :json
    app.plugin :json_parser
  end

  unless json_opt == :only
    require 'tilt/string'
    app.plugin :render

    case opts.fetch(:csrf, app.opts[:rodauth_route_csrf])
    when false
      # nothing
    when :route_csrf
      # :nocov:
      app.plugin :route_csrf
      # :nocov:
    else
      app.plugin :csrf
    end

    app.plugin :flash unless opts[:flash] == false
    app.plugin :h
  end
end
new (scope)
[show source]
# File lib/rodauth/features/base.rb, line 106
def initialize(scope)
  @scope = scope
end
version ()
[show source]
# File lib/rodauth/version.rb, line 20
def self.version
  VERSION
end

Public Instance methods

_account_from_login (login)
[show source]
# File lib/rodauth/features/base.rb, line 428
def _account_from_login(login)
  ds = db[accounts_table].where(login_column=>login)
  ds = ds.select(*account_select) if account_select
  ds = ds.where(account_status_column=>[account_unverified_status_value, account_open_status_value]) unless skip_status_checks?
  ds.first
end
_account_from_reset_password_key (token)
[show source]
# File lib/rodauth/features/reset_password.rb, line 233
def _account_from_reset_password_key(token)
  account_from_key(token, account_open_status_value){|id| get_password_reset_key(id)}
end
_account_from_session ()
[show source]
# File lib/rodauth/features/base.rb, line 435
def _account_from_session
  ds = account_ds(session_value)
  ds = ds.where(account_session_status_filter) unless skip_status_checks?
  ds.first
end
_account_from_unlock_key (token)
[show source]
# File lib/rodauth/features/lockout.rb, line 272
def _account_from_unlock_key(token)
  account_from_key(token){|id| account_lockouts_ds(id).get(account_lockouts_key_column)}
end
_account_from_verify_account_key (token)
[show source]
# File lib/rodauth/features/verify_account.rb, line 282
def _account_from_verify_account_key(token)
  account_from_key(token, account_unverified_status_value){|id| get_verify_account_key(id)}
end
_account_from_verify_login_change_key (token)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 180
def _account_from_verify_login_change_key(token)
  account_from_key(token) do |id|
    @verify_login_change_new_login, key = get_verify_login_change_login_and_key(id)
    key
  end
end
_json_response_body (hash)
[show source]
# File lib/rodauth/features/jwt.rb, line 207
def _json_response_body(hash)
  request.send(:convert_to_json, hash)
end
_new_account (login)
[show source]
# File lib/rodauth/features/create_account.rb, line 123
def _new_account(login)
  acc = {login_column=>login}
  unless skip_status_checks?
    acc[account_status_column] = account_initial_status_value
  end
  acc
end
_otp ()
[show source]
# File lib/rodauth/features/otp.rb, line 335
def _otp
  otp_class.new(otp_key, :issuer=>otp_issuer, :digits=>otp_digits, :interval=>otp_interval)
end
_otp_add_key (secret)
[show source]
# File lib/rodauth/features/otp.rb, line 325
def _otp_add_key(secret)
  # Uniqueness errors can't be handled here, as we can't be sure the secret provided
  # is the same as the current secret.
  otp_key_ds.insert(otp_keys_id_column=>session_value, otp_keys_column=>secret)
end
_otp_key ()
[show source]
# File lib/rodauth/features/otp.rb, line 331
def _otp_key
  otp_key_ds.get(otp_keys_column)
end
_otp_tmp_key (secret)
[show source]
# File lib/rodauth/features/otp.rb, line 321
def _otp_tmp_key(secret)
  @otp_key = secret
end
_recovery_codes ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 234
def _recovery_codes
  recovery_codes_ds.select_map(recovery_codes_column)
end
_sms ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 502
def _sms
  sms_ds.first
end
_two_factor_auth_required_redirect ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 137
def _two_factor_auth_required_redirect
  two_factor_auth_required_redirect || two_factor_auth_fallback_redirect || default_redirect
end
_view (meth, page)
[show source]
# File lib/rodauth/features/base.rb, line 556
def _view(meth, page)
  scope.send(meth, _view_opts(page))
end
_view_opts (page)
[show source]
# File lib/rodauth/features/base.rb, line 538
def _view_opts(page)
  auth_template_path = template_path(page)
  opts = template_opts.dup
  opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
  opts[:locals][:rodauth] = self
  opts[:cache] = cache_templates
  opts[:cache_key] = :"rodauth_#{page}"

  scope.instance_exec do
    opts = find_template(parse_template_opts(page, opts))
    unless File.file?(template_path(opts))
      opts[:path] = auth_template_path
    end
  end

  opts
end
account_activity_ds (account_id)
[show source]
# File lib/rodauth/features/account_expiration.rb, line 103
def account_activity_ds(account_id)
  db[account_activity_table].
    where(account_activity_id_column=>account_id)
end
account_ds (id=account_id)
[show source]
# File lib/rodauth/features/base.rb, line 449
def account_ds(id=account_id)
  raise ArgumentError, "invalid account id passed to account_ds" unless id
  ds = db[accounts_table].where(account_id_column=>id)
  ds = ds.select(*account_select) if account_select
  ds
end
account_expired? ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 53
def account_expired?
  columns = [account_activity_last_activity_column, account_activity_last_login_column, account_activity_expired_column]
  last_activity, last_login, expired = account_activity_ds(account_id).get(columns)
  return true if expired
  timestamp = convert_timestamp(expire_account_on_last_activity? ? last_activity : last_login)
  return false unless timestamp
  timestamp < Time.now - expire_account_after
end
account_expired_at ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 34
def account_expired_at
  get_activity_timestamp(account_id, account_activity_expired_column)
end
account_from_key (token, status_id=nil)
[show source]
# File lib/rodauth/features/email_base.rb, line 53
def account_from_key(token, status_id=nil)
  id, key = split_token(token)
  return unless id && key

  return unless actual = yield(id)

  return unless timing_safe_eql?(key, actual)

  ds = account_ds(id)
  ds = ds.where(account_status_column=>status_id) if status_id && !skip_status_checks?
  ds.first
end
account_from_login (login)
[show source]
# File lib/rodauth/features/base.rb, line 157
def account_from_login(login)
  @account = _account_from_login(login)
end
account_from_reset_password_key (key)
[show source]
# File lib/rodauth/features/password_expiration.rb, line 44
def account_from_reset_password_key(key)
  if a = super
    check_password_change_allowed
  end
  a
end
account_from_session ()
[show source]
# File lib/rodauth/features/base.rb, line 236
def account_from_session
  @account = _account_from_session
end
account_from_unlock_key (key)
[show source]
# File lib/rodauth/features/lockout.rb, line 197
def account_from_unlock_key(key)
  @account = _account_from_unlock_key(key)
end
account_from_verify_account_key (key)
[show source]
# File lib/rodauth/features/verify_account.rb, line 179
def account_from_verify_account_key(key)
  @account = _account_from_verify_account_key(key)
end
account_from_verify_login_change_key (key)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 101
def account_from_verify_login_change_key(key)
  @account = _account_from_verify_login_change_key(key)
end
account_id ()
[show source]
# File lib/rodauth/features/base.rb, line 147
def account_id
  account[account_id_column]
end
account_in_unverified_grace_period? ()
[show source]
# File lib/rodauth/features/verify_account_grace_period.rb, line 65
def account_in_unverified_grace_period?
  account[account_status_column] == account_unverified_status_value &&
    verify_account_grace_period &&
    !verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
end
account_initial_status_value ()
[show source]
# File lib/rodauth/features/base.rb, line 232
def account_initial_status_value
  account_open_status_value
end
account_lockouts_ds (id=account_id)
[show source]
# File lib/rodauth/features/lockout.rb, line 268
def account_lockouts_ds(id=account_id)
  db[account_lockouts_table].where(account_lockouts_id_column=>id)
end
account_login_failures_ds ()
[show source]
# File lib/rodauth/features/lockout.rb, line 264
def account_login_failures_ds
  db[account_login_failures_table].where(account_login_failures_id_column=>account_id)
end
account_model (model)
[show source]
# File lib/rodauth/features/base.rb, line 95
def account_model(model)
  warn "account_model is deprecated, use db and accounts_table settings"
  db model.db
  accounts_table model.table_name
  account_select model.dataset.opts[:select]
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, line 172
def account_password_hash_column
  nil
end
account_session_status_filter ()
[show source]
# File lib/rodauth/features/base.rb, line 441
def account_session_status_filter
  {account_status_column=>account_open_status_value}
end
active_remember_key_ds (id=account_id)
[show source]
# File lib/rodauth/features/remember.rb, line 197
def active_remember_key_ds(id=account_id)
  remember_key_ds(id).where(Sequel.expr(remember_deadline_column) > Sequel::CURRENT_TIMESTAMP)
end
add_previous_password_hash (hash)
[show source]
# File lib/rodauth/features/disallow_password_reuse.rb, line 24
def add_previous_password_hash(hash) 
  ds = previous_password_ds
  keep_before = ds.reverse(previous_password_id_column).
    limit(nil, previous_passwords_to_check).
    get(previous_password_id_column)

  ds.where(Sequel.expr(previous_password_id_column) <= keep_before).
    delete

  # This should never raise uniqueness violations, as it uses a serial primary key
  ds.insert(previous_password_account_id_column=>account_id, previous_password_hash_column=>hash)
end
add_recovery_code ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 215
def add_recovery_code
  # This should never raise uniqueness violations unless the recovery code is the same, and the odds of that
  # are 1/256**32 assuming a good random number generator.  Still, attempt to handle that case by retrying
  # on such a uniqueness violation.
  retry_on_uniqueness_violation do
    recovery_codes_ds.insert(recovery_codes_id_column=>session_value, recovery_codes_column=>new_recovery_code)
  end
end
add_recovery_codes (number)
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 205
def add_recovery_codes(number)
  return if number <= 0
  transaction do
    number.times do
      add_recovery_code
    end
  end
  remove_instance_variable(:@recovery_codes)
end
add_remember_key ()
[show source]
# File lib/rodauth/features/remember.rb, line 143
def add_remember_key
  hash = {remember_id_column=>account_id, remember_key_column=>remember_key_value}
  set_deadline_value(hash, remember_deadline_column, remember_deadline_interval)

  if e = raised_uniqueness_violation{remember_key_ds.insert(hash)}
    # If inserting into the remember key table causes a violation, we can pull the
    # existing row from the table.  If there is no invalid row, we can then reraise.
    raise e unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
  end
end
after_change_login ()
[show source]
# File lib/rodauth/features/verify_change_login.rb, line 12
def after_change_login
  super
  update_account(account_status_column=>account_unverified_status_value)
  setup_account_verification
  session[unverified_account_session_key] = true
end
after_change_password ()
[show source]
# File lib/rodauth/features/change_password_notify.rb, line 30
def after_change_password
  super
  send_password_changed_email
end
after_close_account ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 93
def after_close_account
  super if defined?(super)
  account_activity_ds(account_id).delete
end
after_confirm_password ()
[show source]
# File lib/rodauth/features/remember.rb, line 178
def after_confirm_password
  super
  clear_remembered_session_key
end
after_create_account ()
[show source]
# File lib/rodauth/features/disallow_password_reuse.rb, line 69
def after_create_account
  if account_password_hash_column
    add_previous_password_hash(password_hash(param(password_param)))
  end
  super if defined?(super)
end
after_login ()
[show source]
# File lib/rodauth/features/lockout.rb, line 221
def after_login
  clear_invalid_login_attempts
  super
end
after_login_failure ()
[show source]
# File lib/rodauth/features/lockout.rb, line 226
def after_login_failure
  invalid_login_attempted
  super
end
after_logout ()
[show source]
# File lib/rodauth/features/remember.rb, line 168
def after_logout
  forget_login
  super if defined?(super)
end
after_reset_password ()
[show source]
# File lib/rodauth/features/password_grace_period.rb, line 26
def after_reset_password
  super if defined?(super)
  @last_password_entry = Time.now.to_i
end
allow_resending_verify_account_email? ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 146
def allow_resending_verify_account_email?
  account[account_status_column] == account_unverified_status_value
end
already_logged_in ()
[show source]
# File lib/rodauth/features/base.rb, line 180
def already_logged_in
  nil
end
auth_class_eval (&block)
[show source]
# File lib/rodauth/features/base.rb, line 91
def auth_class_eval(&block)
  auth.class_eval(&block)
end
authenticated? ()
[show source]
# File lib/rodauth/features/base.rb, line 224
def authenticated?
  logged_in?
end
before_change_login_route ()
[show source]
# File lib/rodauth/features/verify_account_grace_period.rb, line 35
def before_change_login_route
  unless verified_account?
    set_redirect_error_flash unverified_change_login_error_flash
    redirect unverified_change_login_redirect
  end
  super if defined?(super)
end
before_change_password_route ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 89
def before_change_password_route
  check_password_change_allowed
  super
end
before_login_attempt ()
[show source]
# File lib/rodauth/features/lockout.rb, line 214
def before_login_attempt
  if locked_out?
    show_lockout_page
  end
  super
end
before_logout ()
[show source]
# File lib/rodauth/features/single_session.rb, line 71
def before_logout
  reset_single_session_key if request.post?
  super if defined?(super)
end
before_reset_password ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 73
def before_reset_password
  check_account_expiration
  super if defined?(super)
end
before_reset_password_request ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 78
def before_reset_password_request
  check_account_expiration
  super if defined?(super)
end
before_rodauth ()
[show source]
# File lib/rodauth/features/jwt.rb, line 142
def before_rodauth
  if json_request?
    if jwt_check_accept? && (accept = request.env['HTTP_ACCEPT']) && accept !~ json_accept_regexp
      response.status = 406
      json_response[json_response_error_key] = json_not_accepted_error_message
      response['Content-Type'] ||= json_response_content_type
      response.write(request.send(:convert_to_json, json_response))
      request.halt
    end

    unless request.post?
      response.status = 405
      response.headers['Allow'] = 'POST'
      json_response[json_response_error_key] = json_non_post_error_message
      return_json_response
    end
  elsif only_json?
    response.status = json_response_error_status
    response.write non_json_request_error_message
    request.halt
  end

  super
end
before_unlock_account ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 83
def before_unlock_account
  check_account_expiration
  super if defined?(super)
end
before_unlock_account_request ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 88
def before_unlock_account_request
  check_account_expiration
  super if defined?(super)
end
before_view_recovery_codes ()
[show source]
# File lib/rodauth/features/jwt.rb, line 167
def before_view_recovery_codes
  super if defined?(super)
  if use_jwt?
    json_response[:codes] = recovery_codes
    json_response[json_response_success_key] ||= "" if include_success_messages?
  end
end
button (value, opts={})
[show source]
# File lib/rodauth/features/base.rb, line 261
def button(value, opts={})
  scope.render(button_opts(value, opts))
end
button_opts (value, opts)
[show source]
# File lib/rodauth/features/base.rb, line 252
def button_opts(value, opts)
  opts = Hash[template_opts].merge!(opts)
  opts[:locals] = {:value=>value, :opts=>opts}
  opts[:path] = template_path('button')
  opts[:cache] = cache_templates
  opts[:cache_key] = :rodauth_button
  opts
end
can_add_recovery_codes? ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 201
def can_add_recovery_codes?
  recovery_codes.length < recovery_codes_limit
end
catch_error (&block)
[show source]
# File lib/rodauth/features/base.rb, line 359
def catch_error(&block)
  catch(:rodauth_error, &block)
end
change_login (login)
[show source]
# File lib/rodauth/features/change_login.rb, line 64
def change_login(login)
  if account_ds.get(login_column).downcase == login.downcase
    @login_requirement_message = 'same as current login'
    return false
  end

  update_login(login)
end
change_login_notice_flash ()
[show source]
# File lib/rodauth/features/verify_change_login.rb, line 6
def change_login_notice_flash
  "#{super}. #{verify_account_email_sent_notice_flash}"
end
change_login_requires_password? ()
[show source]
# File lib/rodauth/features/change_login.rb, line 60
def change_login_requires_password?
  modifications_require_password?
end
change_password_requires_password? ()
[show source]
# File lib/rodauth/features/change_password.rb, line 65
def change_password_requires_password?
  modifications_require_password?
end
check_account_expiration ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 62
def check_account_expiration
  if account_expired?
    set_expired unless account_expired_at
    set_redirect_error_flash account_expiration_error_flash
    redirect account_expiration_redirect
  end
  update_last_login
end
check_already_logged_in ()
[show source]
# File lib/rodauth/features/base.rb, line 176
def check_already_logged_in
  already_logged_in if logged_in?
end
check_password_change_allowed ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 29
def check_password_change_allowed
  if password_changed_at = get_password_changed_at
    if password_changed_at > Time.now - allow_password_change_after
      set_redirect_error_flash password_not_changeable_yet_error_flash
      redirect password_not_changeable_yet_redirect
    end
  end
end
check_session_expiration ()
[show source]
# File lib/rodauth/features/session_expiration.rb, line 14
def check_session_expiration
  return unless logged_in?

  unless session.has_key?(session_last_activity_session_key) && session.has_key?(session_created_session_key)
    if session_expiration_default
      expire_session
    end

    return
  end

  time = Time.now.to_i

  if session[session_last_activity_session_key] + session_inactivity_timeout < time
    expire_session
  end
  set_session_value(session_last_activity_session_key, time)

  if session[session_created_session_key] + max_session_lifetime < time
    expire_session
  end
end
check_single_session ()
[show source]
# File lib/rodauth/features/single_session.rb, line 41
def check_single_session
  if logged_in? && !currently_active_session?
    no_longer_active_session
  end
end
clear_cached_otp ()
[show source]
# File lib/rodauth/features/otp.rb, line 304
def clear_cached_otp
  remove_instance_variable(:@otp) if defined?(@otp)
end
clear_invalid_login_attempts ()
[show source]
# File lib/rodauth/features/lockout.rb, line 151
def clear_invalid_login_attempts
  unlock_account
end
clear_remembered_session_key ()
[show source]
# File lib/rodauth/features/remember.rb, line 158
def clear_remembered_session_key
  session.delete(remembered_session_key)
end
clear_session ()
[show source]
# File lib/rodauth/features/base.rb, line 184
def clear_session
  if scope.respond_to?(:clear_session)
    scope.clear_session
  else
    session.clear
  end
end
close_account ()
[show source]
# File lib/rodauth/features/close_account.rb, line 61
def close_account
  unless skip_status_checks?
    update_account(account_status_column=>account_closed_status_value)
  end

  unless account_password_hash_column
    password_hash_ds.delete
  end
end
close_account_requires_password? ()
[show source]
# File lib/rodauth/features/close_account.rb, line 57
def close_account_requires_password?
  modifications_require_password?
end
confirm_password ()
[show source]
# File lib/rodauth/features/confirm_password.rb, line 44
def confirm_password
  nil
end
confirm_password_redirect ()
[show source]
# File lib/rodauth/features/confirm_password.rb, line 48
def confirm_password_redirect
  session.delete(confirm_password_redirect_session_key) || default_redirect
end
convert_session_key (key)
[show source]
# File lib/rodauth/features/base.rb, line 338
def convert_session_key(key)
  scope.opts[:sessions_convert_symbols] ? key.to_s : key
end
convert_timestamp (timestamp)

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

[show source]
# File lib/rodauth/features/base.rb, line 461
def convert_timestamp(timestamp)
  timestamp = db.to_application_timestamp(timestamp) if timestamp.is_a?(String)
  timestamp
end
create_account_autologin? ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 203
def create_account_autologin?
  false
end
create_account_notice_flash ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 165
def create_account_notice_flash
  verify_account_email_sent_notice_flash
end
create_account_set_password? ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 215
def create_account_set_password?
  return false if verify_account_set_password?
  super
end
create_email (subject, body)
[show source]
# File lib/rodauth/features/email_base.rb, line 24
def create_email(subject, body)
  create_email_to(email_to, subject, body)
end
create_email_to (to, subject, body)
[show source]
# File lib/rodauth/features/email_base.rb, line 28
def create_email_to(to, subject, body)
  m = Mail.new
  m.from = email_from
  m.to = to
  m.subject = "#{email_subject_prefix}#{subject}"
  m.body = body
  m
end
create_password_changed_email ()
[show source]
# File lib/rodauth/features/change_password_notify.rb, line 22
def create_password_changed_email
  create_email(password_changed_email_subject, password_changed_email_body)
end
create_reset_password_email ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 207
def create_reset_password_email
  create_email(reset_password_email_subject, reset_password_email_body)
end
create_reset_password_key ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 145
def create_reset_password_key
  transaction do
    if reset_password_key_value = get_password_reset_key(account_id)
      @reset_password_key_value = reset_password_key_value
    elsif e = raised_uniqueness_violation{password_reset_ds.insert(reset_password_key_insert_hash)}
      # If inserting into the reset password table causes a violation, we can pull the
      # existing reset password key from the table, or reraise.
      raise e unless @reset_password_key_value = get_password_reset_key(account_id)
    end
  end
end
create_unlock_account_email ()
[show source]
# File lib/rodauth/features/lockout.rb, line 252
def create_unlock_account_email
  create_email(unlock_account_email_subject, unlock_account_email_body)
end
create_verify_account_email ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 270
def create_verify_account_email
  create_email(verify_account_email_subject, verify_account_email_body)
end
create_verify_account_key ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 253
def create_verify_account_key
  ds = verify_account_ds
  transaction do
    if ds.empty?
      if e = raised_uniqueness_violation{ds.insert(verify_account_key_insert_hash)}
        # If inserting into the verify account table causes a violation, we can pull the
        # key from the verify account table, or reraise.
        raise e unless @verify_account_key_value = get_verify_account_key(account_id)
      end
    end
  end
end
create_verify_login_change_email (login)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 168
def create_verify_login_change_email(login)
  create_email_to(login, verify_login_change_email_subject, verify_login_change_email_body)
end
create_verify_login_change_key (login)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 146
def create_verify_login_change_key(login)
  ds = verify_login_change_ds
  transaction do
    ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
    if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
      old_login, key = get_verify_login_change_login_and_key(account_id)
      # If inserting into the verify account table causes a violation, we can pull the
      # key from the verify login change table if the logins match, or reraise.
      @verify_login_change_key_value = if old_login.downcase == login.downcase
        key
      end
      raise e unless @verify_login_change_key_value
    end
  end
end
csrf_tag (path=request.path)
[show source]
# File lib/rodauth/features/base.rb, line 240
def csrf_tag(path=request.path)
  return unless scope.respond_to?(:csrf_tag)

  if use_request_specific_csrf_tokens?
    # :nocov:
    scope.csrf_tag(path)
    # :nocov:
  else
    scope.csrf_tag
  end
end
currently_active_session? ()
[show source]
# File lib/rodauth/features/single_session.rb, line 25
def currently_active_session?
  single_session_key = session[single_session_session_key]
  current_key = single_session_ds.get(single_session_key_column)
  if single_session_key.nil?
    unless current_key
      # No row exists for this user, indicating the feature has never
      # been used, so it is OK to treat the current session as a new
      # session.
      update_single_session_key
    end
    true
  elsif current_key
    timing_safe_eql?(single_session_key, current_key)
  end
end
db ()
[show source]
# File lib/rodauth/features/base.rb, line 165
def db
  Sequel::DATABASES.first
end
delete_account ()
[show source]
# File lib/rodauth/features/close_account.rb, line 71
def delete_account
  account_ds.delete
end
delete_account_on_close? ()
[show source]
# File lib/rodauth/features/close_account.rb, line 75
def delete_account_on_close?
  skip_status_checks?
end
disable_remember_login ()
[show source]
# File lib/rodauth/features/remember.rb, line 139
def disable_remember_login
  remove_remember_key
end
email_from ()
[show source]
# File lib/rodauth/features/email_base.rb, line 37
def email_from
  "webmaster@#{request.host}"
end
email_to ()
[show source]
# File lib/rodauth/features/email_base.rb, line 41
def email_to
  account[login_column]
end
expire_session ()
[show source]
# File lib/rodauth/features/session_expiration.rb, line 37
def expire_session
  clear_session
  set_redirect_error_flash session_expiration_error_flash
  redirect session_expiration_redirect
end
features ()
[show source]
# File lib/rodauth/features/base.rb, line 110
def features
  self.class.features
end
field_error (field)
[show source]
# File lib/rodauth/features/base.rb, line 142
def field_error(field)
  return nil unless @field_errors
  @field_errors[field]
end
flash ()
[show source]
# File lib/rodauth/features/base.rb, line 126
def flash
  scope.flash
end
forget_login ()
[show source]
# File lib/rodauth/features/remember.rb, line 124
def forget_login
  ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, remember_cookie_options)
end
function_name (name)
[show source]
# File lib/rodauth/features/base.rb, line 404
def function_name(name)
  if db.database_type == :mssql
    # :nocov:
    "dbo.#{name}"
    # :nocov:
  else
    name
  end
end
generate_remember_key_value ()
[show source]
# File lib/rodauth/features/remember.rb, line 185
def generate_remember_key_value
  @remember_key_value = random_key
end
generate_reset_password_key_value ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 203
def generate_reset_password_key_value
  @reset_password_key_value = random_key
end
generate_unlock_account_key ()
[show source]
# File lib/rodauth/features/lockout.rb, line 236
def generate_unlock_account_key
  random_key
end
generate_verify_account_key_value ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 249
def generate_verify_account_key_value
  @verify_account_key_value = random_key
end
generate_verify_login_change_key_value ()
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 142
def generate_verify_login_change_key_value
  @verify_login_change_key_value = random_key
end
get_activity_timestamp (account_id, column)
[show source]
# File lib/rodauth/features/account_expiration.rb, line 108
def get_activity_timestamp(account_id, column)
  convert_timestamp(account_activity_ds(account_id).get(column))
end
get_password_changed_at ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 25
def get_password_changed_at
  convert_timestamp(password_expiration_ds.get(password_expiration_changed_at_column))
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, line 416
def get_password_hash
  if account_password_hash_column
    account[account_password_hash_column]
  elsif use_database_authentication_functions?
    db.get(Sequel.function(function_name(:rodauth_get_salt), account_id))
  else
    # :nocov:
    password_hash_ds.get(password_hash_column)
    # :nocov:
  end
end
get_password_reset_key (id)
[show source]
# File lib/rodauth/features/reset_password.rb, line 173
def get_password_reset_key(id)
  ds = password_reset_ds(id)
  ds.where(Sequel::CURRENT_TIMESTAMP > reset_password_deadline_column).delete
  ds.get(reset_password_key_column)
end
get_remember_key ()
[show source]
# File lib/rodauth/features/remember.rb, line 128
def get_remember_key
  unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
   generate_remember_key_value
   transaction do
     remove_remember_key
     add_remember_key
   end
  end
  nil
end
get_unlock_account_key ()
[show source]
# File lib/rodauth/features/lockout.rb, line 193
def get_unlock_account_key
  account_lockouts_ds.get(account_lockouts_key_column)
end
get_verify_account_key (id)
[show source]
# File lib/rodauth/features/verify_account.rb, line 195
def get_verify_account_key(id)
  verify_account_ds(id).get(verify_account_key_column)
end
get_verify_login_change_login_and_key (id)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 113
def get_verify_login_change_login_and_key(id)
  verify_login_change_ds(id).get([verify_login_change_login_column, verify_login_change_key_column])
end
include_success_messages? ()
[show source]
# File lib/rodauth/features/jwt.rb, line 187
def include_success_messages?
  !json_response_success_key.nil?
end
invalid_login_attempted ()
[show source]
# File lib/rodauth/features/lockout.rb, line 155
def invalid_login_attempted
  ds = account_login_failures_ds.
      where(account_login_failures_id_column=>account_id)

  number = if db.database_type == :postgres
    ds.returning(account_login_failures_number_column).
      with_sql(:update_sql, account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1).
      single_value
  else
    # :nocov:
    if ds.update(account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1) > 0
      ds.get(account_login_failures_number_column)
    end
    # :nocov:
  end

  unless number
    # Ignoring the violation is safe here.  It may allow slightly more than max_invalid_logins invalid logins before
    # lockout, but allowing a few extra is OK if the race is lost.
    ignore_uniqueness_violation{account_login_failures_ds.insert(account_login_failures_id_column=>account_id)}
    number = 1
  end

  if number >= max_invalid_logins
    @unlock_account_key_value = generate_unlock_account_key
    hash = {account_lockouts_id_column=>account_id, account_lockouts_key_column=>unlock_account_key_value}
    set_deadline_value(hash, account_lockouts_deadline_column, account_lockouts_deadline_interval)

    if e = raised_uniqueness_violation{account_lockouts_ds.insert(hash)}
      # If inserting into the lockout table raises a violation, we should just be able to pull the already inserted
      # key out of it.  If that doesn't return a valid key, we should reraise the error.
      raise e unless @unlock_account_key_value = account_lockouts_ds.get(account_lockouts_key_column)

      show_lockout_page
    end
  end
end
invalid_previous_password_message ()
[show source]
# File lib/rodauth/features/change_password.rb, line 69
def invalid_previous_password_message
  invalid_password_message
end
json_request? ()
[show source]
# File lib/rodauth/features/jwt.rb, line 103
def json_request?
  return @json_request if defined?(@json_request)
  @json_request = request.content_type =~ json_request_content_type_regexp
end
json_response ()
[show source]
# File lib/rodauth/features/jwt.rb, line 197
def json_response
  @json_response ||= {}
end
jwt_payload ()
[show source]
# File lib/rodauth/features/jwt.rb, line 175
def jwt_payload
  return @jwt_payload if defined?(@jwt_payload)
  @jwt_payload = JWT.decode(jwt_token, jwt_secret, true, jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
rescue JWT::DecodeError
  @jwt_payload = false
end
jwt_secret ()
[show source]
# File lib/rodauth/features/jwt.rb, line 108
def jwt_secret
  raise ArgumentError, "jwt_secret not set"
end
jwt_session_hash ()
[show source]
# File lib/rodauth/features/jwt.rb, line 112
def jwt_session_hash
  jwt_session_key ? {jwt_session_key=>session} : session
end
jwt_token ()
[show source]
# File lib/rodauth/features/jwt.rb, line 120
def jwt_token
  return @jwt_token if defined?(@jwt_token)

  if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
    @jwt_token = v.sub(jwt_authorization_remove, '')
  end
end
last_account_activity_at ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 26
def last_account_activity_at
  get_activity_timestamp(session_value, account_activity_last_activity_column)
end
last_account_login_at ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 30
def last_account_login_at
  get_activity_timestamp(session_value, account_activity_last_login_column)
end
load_memory ()
[show source]
# File lib/rodauth/features/remember.rb, line 84
def load_memory
  return if session[session_key]
  return unless cookie = request.cookies[remember_cookie_key]
  id, key = cookie.split('_', 2)
  return unless id && key

  unless (actual = active_remember_key_ds(id).get(remember_key_column)) && timing_safe_eql?(key, actual)
    forget_login
    return
  end

  session[session_key] = id
  account = account_from_session
  session.delete(session_key)

  unless account
    remove_remember_key(id)
    forget_login
    return 
  end

  before_load_memory
  update_session

  set_session_value(remembered_session_key, true)
  if extend_remember_deadline?
    active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
    remember_login
  end
  after_load_memory
end
loaded_templates ()
[show source]
# File lib/rodauth/features/base.rb, line 466
def loaded_templates
  []
end
locked_out? ()
[show source]
# File lib/rodauth/features/lockout.rb, line 132
def locked_out?
  if t = convert_timestamp(account_lockouts_ds.get(account_lockouts_deadline_column))
    if Time.now < t
      true
    else
      unlock_account
      false
    end
  else
    false
  end
end
logged_in_via_remember_key? ()
[show source]
# File lib/rodauth/features/remember.rb, line 162
def logged_in_via_remember_key?
  !!session[remembered_session_key]
end
login_confirm_label ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 34
def login_confirm_label
  "Confirm #{login_label}"
end
login_does_not_meet_requirements_message ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 79
def login_does_not_meet_requirements_message
  "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
end
login_failed_reset_password_request_form ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 211
def login_failed_reset_password_request_form
  render("reset-password-request")
end
login_meets_email_requirements? (login)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 103
def login_meets_email_requirements?(login)
  return true unless require_email_address_logins?
  if login =~ /\A[^,;@ \r\n]+@[^,@; \r\n]+\.[^,@; \r\n]+\z/
    return true
  end
  @login_requirement_message = 'not a valid email address'
  return false
end
login_meets_length_requirements? (login)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 91
def login_meets_length_requirements?(login)
  if login_minimum_length > login.length
    @login_requirement_message = login_too_short_message
    false
  elsif login_maximum_length < login.length
    @login_requirement_message = login_too_long_message
    false
  else
    true
  end
end
login_meets_requirements? (login)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 42
def login_meets_requirements?(login)
  login_meets_length_requirements?(login) && \
    login_meets_email_requirements?(login)
end
login_required ()
[show source]
# File lib/rodauth/features/base.rb, line 192
def login_required
  set_redirect_error_status(login_required_error_status)
  set_redirect_error_flash require_login_error_flash
  redirect require_login_redirect
end
login_too_long_message ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 83
def login_too_long_message
  "maximum #{login_maximum_length} characters"
end
login_too_short_message ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 87
def login_too_short_message
  "minimum #{login_minimum_length} characters"
end
logout ()
[show source]
# File lib/rodauth/features/logout.rb, line 33
def logout
  clear_session
end
modifications_require_password? ()
[show source]
# File lib/rodauth/features/password_grace_period.rb, line 7
def modifications_require_password?
  return false unless super
  !password_recently_entered?
end
new_account (login)
[show source]
# File lib/rodauth/features/create_account.rb, line 102
def new_account(login)
  @account = _new_account(login)
end
new_recovery_code ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 226
def new_recovery_code
  random_key
end
no_longer_active_session ()
[show source]
# File lib/rodauth/features/single_session.rb, line 47
def no_longer_active_session
  clear_session
  set_redirect_error_flash single_session_error_flash
  redirect single_session_redirect
end
only_json? ()
[show source]
# File lib/rodauth/features/base.rb, line 274
def only_json?
  scope.class.opts[:rodauth_json] == :only
end
open_account? ()
[show source]
# File lib/rodauth/features/base.rb, line 161
def open_account?
  skip_status_checks? || account[account_status_column] == account_open_status_value 
end
otp_add_key ()
[show source]
# File lib/rodauth/features/otp.rb, line 263
def otp_add_key
  _otp_add_key(otp_key)
  super if defined?(super)
end
otp_exists? ()
[show source]
# File lib/rodauth/features/otp.rb, line 244
def otp_exists?
  !otp_key.nil?
end
otp_issuer ()
[show source]
# File lib/rodauth/features/otp.rb, line 290
def otp_issuer
  request.host
end
otp_key_ds ()
[show source]
# File lib/rodauth/features/otp.rb, line 339
def otp_key_ds
  db[otp_keys_table].where(otp_keys_id_column=>session_value)
end
otp_locked_out? ()
[show source]
# File lib/rodauth/features/otp.rb, line 282
def otp_locked_out?
  otp_key_ds.get(otp_keys_failures_column) >= otp_auth_failures_limit
end
otp_lockout_error_flash ()
[show source]
# File lib/rodauth/features/otp.rb, line 232
def otp_lockout_error_flash
  "Authentication code use locked out due to numerous failures.#{super if defined?(super)}"
end
otp_lockout_redirect ()
[show source]
# File lib/rodauth/features/otp.rb, line 227
def otp_lockout_redirect
  return super if defined?(super)
  default_redirect
end
otp_new_secret ()
[show source]
# File lib/rodauth/features/otp.rb, line 317
def otp_new_secret
  ROTP::Base32.random_base32
end
otp_provisioning_name ()
[show source]
# File lib/rodauth/features/otp.rb, line 294
def otp_provisioning_name
  account[login_column]
end
otp_provisioning_uri ()
[show source]
# File lib/rodauth/features/otp.rb, line 286
def otp_provisioning_uri
  otp.provisioning_uri(otp_provisioning_name)
end
otp_qr_code ()
[show source]
# File lib/rodauth/features/otp.rb, line 298
def otp_qr_code
  RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8)
end
otp_record_authentication_failure ()
[show source]
# File lib/rodauth/features/otp.rb, line 274
def otp_record_authentication_failure
  otp_key_ds.update(otp_keys_failures_column=>Sequel.identifier(otp_keys_failures_column) + 1)
end
otp_remove ()
[show source]
# File lib/rodauth/features/otp.rb, line 258
def otp_remove
  otp_key_ds.delete
  super if defined?(super)
end
otp_remove_auth_failures ()
[show source]
# File lib/rodauth/features/otp.rb, line 278
def otp_remove_auth_failures
  otp_key_ds.update(otp_keys_failures_column=>0)
end
otp_tmp_key (secret)
[show source]
# File lib/rodauth/features/otp.rb, line 308
def otp_tmp_key(secret)
  _otp_tmp_key(secret)
  clear_cached_otp
end
otp_update_last_use ()
[show source]
# File lib/rodauth/features/otp.rb, line 268
def otp_update_last_use
  otp_key_ds.
    where(Sequel.date_add(otp_keys_last_use_column, :seconds=>(otp_interval||30)) < Sequel::CURRENT_TIMESTAMP).
    update(otp_keys_last_use_column=>Sequel::CURRENT_TIMESTAMP) == 1
end
otp_valid_code? (ot_pass)
[show source]
# File lib/rodauth/features/otp.rb, line 248
def otp_valid_code?(ot_pass)
  return false unless otp_exists?
  ot_pass = ot_pass.gsub(/\s+/, '')
  if drift = otp_drift
    otp.verify_with_drift(ot_pass, drift)
  else
    otp.verify(ot_pass)
  end
end
otp_valid_key? (secret)
[show source]
# File lib/rodauth/features/otp.rb, line 313
def otp_valid_key?(secret)
  secret =~ /\A[a-z2-7]{16}\z/
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, line 305
def param(key)
  param_or_nil(key).to_s
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, line 311
def param_or_nil(key)
  value = request.params[key]
  value.to_s unless value.nil?
end
password_changed_email_body ()
[show source]
# File lib/rodauth/features/change_password_notify.rb, line 26
def password_changed_email_body
  render('password-changed-email')
end
password_confirm_label ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 38
def password_confirm_label
  "Confirm #{password_label}"
end
password_does_not_contain_null_byte? (password)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 118
def password_does_not_contain_null_byte?(password)
  return true unless password.include?("\0")
  @password_requirement_message = 'contains null byte'
  false
end
password_does_not_meet_requirements_message ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 71
def password_does_not_meet_requirements_message
  "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
end
password_doesnt_match_previous_password? (password)
[show source]
# File lib/rodauth/features/disallow_password_reuse.rb, line 44
def password_doesnt_match_previous_password?(password)
  match = if use_database_authentication_functions?
    salts = previous_password_ds.
      select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
    return true if salts.empty?

    salts.any? do |hash_id, salt|
      db.get(Sequel.function(function_name(:rodauth_previous_password_hash_match), hash_id, BCrypt::Engine.hash_secret(password, salt)))
    end
  else
    # :nocov:
    previous_password_ds.select_map(previous_password_hash_column).any?{|hash| BCrypt::Password.new(hash) == password}
    # :nocov:
  end

  return true unless match
  @password_requirement_message = password_same_as_previous_password_message
  false
end
password_expiration_ds ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 106
def password_expiration_ds
  db[password_expiration_table].where(password_expiration_id_column=>account_id)
end
password_expired? ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 67
def password_expired?
  if password_changed_at = session[password_changed_at_session_key]
    return password_changed_at + require_password_change_after < Time.now.to_i
  end

  account_from_session
  if password_changed_at = get_password_changed_at
    set_session_value(password_changed_at_session_key, password_changed_at.to_i)
    password_changed_at + require_password_change_after < Time.now
  else
    set_session_value(password_changed_at_session_key, password_expiration_default ? 0 : 2147483647)
    password_expiration_default
  end
end
password_has_enough_character_groups? (password)
[show source]
# File lib/rodauth/features/password_complexity.rb, line 54
def password_has_enough_character_groups?(password)
  return true if password.length > password_max_length_for_groups_check
  return true if password_character_groups.select{|re| password =~ re}.length >= password_min_groups
  @password_requirement_message = password_not_enough_character_groups_message
  false
end
password_has_no_invalid_pattern? (password)
[show source]
# File lib/rodauth/features/password_complexity.rb, line 61
def password_has_no_invalid_pattern?(password)
  return true unless password_invalid_pattern
  return true if password !~ password_invalid_pattern
  @password_requirement_message = password_invalid_pattern_message
  false
end
password_hash (password)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 136
def password_hash(password)
  BCrypt::Password.create(password, :cost=>password_hash_cost)
end
password_hash_cost ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 125
def password_hash_cost
  BCrypt::Engine::MIN_COST
end
password_hash_ds ()
[show source]
# File lib/rodauth/features/base.rb, line 456
def password_hash_ds
  db[password_hash_table].where(password_hash_id_column=>account_id)
end
password_match? (password)
[show source]
# File lib/rodauth/features/base.rb, line 288
def password_match?(password)
  if hash = get_password_hash
    if account_password_hash_column || !use_database_authentication_functions?
      BCrypt::Password.new(hash) == password
    else
      db.get(Sequel.function(function_name(:rodauth_valid_password_hash), account_id, BCrypt::Engine.hash_secret(password, hash)))
    end 
  end
end
password_meets_length_requirements? (password)
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 112
def password_meets_length_requirements?(password)
  return true if password_minimum_length <= password.length
  @password_requirement_message = password_too_short_message
  false
end
password_meets_requirements? (password)
[show source]
# File lib/rodauth/features/disallow_common_passwords.rb, line 12
def password_meets_requirements?(password)
  super && password_not_one_of_the_most_common?(password)
end
password_not_in_dictionary? (password)
[show source]
# File lib/rodauth/features/password_complexity.rb, line 79
def password_not_in_dictionary?(password)
  return true unless dict = password_dictionary
  return true unless password =~ /\A(?:\d*)([A-Za-z!@$+|][A-Za-z!@$+|0134578]+[A-Za-z!@$+|])(?:\d*)\z/
  word = $1.downcase.tr('!@$+|0134578', 'iastloleastb')
  return true if !dict.include?(word)
  @password_requirement_message = password_in_dictionary_message
  false
end
password_not_one_of_the_most_common? (password)
[show source]
# File lib/rodauth/features/disallow_common_passwords.rb, line 32
def password_not_one_of_the_most_common?(password)
  return true unless password_one_of_most_common?(password)
  @password_requirement_message = password_is_one_of_the_most_common_message
  false
end
password_not_too_many_repeating_characters? (password)
[show source]
# File lib/rodauth/features/password_complexity.rb, line 68
def password_not_too_many_repeating_characters?(password)
  return true if password_max_repeating_characters < 2
  return true if password !~ /(.)(\1){#{password_max_repeating_characters-1}}/ 
  @password_requirement_message = password_too_many_repeating_characters_message
  false
end
password_one_of_most_common? (password)
[show source]
# File lib/rodauth/features/disallow_common_passwords.rb, line 26
def password_one_of_most_common?(password)
  most_common_passwords.include?(password)
end
password_recently_entered? ()
[show source]
# File lib/rodauth/features/password_grace_period.rb, line 36
def password_recently_entered?
  return false unless last_password_entry = session[last_password_entry_session_key]
  last_password_entry + password_grace_period > Time.now.to_i
end
password_reset_ds (id=account_id)
[show source]
# File lib/rodauth/features/reset_password.rb, line 229
def password_reset_ds(id=account_id)
  db[reset_password_table].where(reset_password_id_column=>id)
end
password_too_many_repeating_characters_message ()
[show source]
# File lib/rodauth/features/password_complexity.rb, line 75
def password_too_many_repeating_characters_message
  "contains #{password_max_repeating_characters} or more of the same character in a row"
end
password_too_short_message ()
[show source]
# File lib/rodauth/features/login_password_requirements_base.rb, line 75
def password_too_short_message
  "minimum #{password_minimum_length} characters"
end
post_configure ()
[show source]
# File lib/rodauth/features/base.rb, line 278
def post_configure
  require 'bcrypt' if require_bcrypt?
  db.extension :date_arithmetic if use_date_arithmetic?
  route_hash= {}
  self.class.routes.each do |meth|
    route_hash["/#{send("#{meth.to_s.sub(/\Ahandle_/, '')}_route")}"] = meth
  end
  self.class.route_hash = route_hash.freeze
end
previous_password_ds ()
[show source]
# File lib/rodauth/features/disallow_password_reuse.rb, line 76
def previous_password_ds
  db[previous_password_hash_table].where(previous_password_account_id_column=>account_id)
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, line 485
def raises_uniqueness_violation?(&block)
  transaction(:savepoint=>:only, &block)
  false
rescue unique_constraint_violation_class => e
  e
end
random_key ()
[show source]
# File lib/rodauth/features/base.rb, line 327
def random_key
  SecureRandom.urlsafe_base64(32)
end
recovery_code_match? (code)
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 188
def recovery_code_match?(code)
  recovery_codes.each do |s|
    if timing_safe_eql?(code, s)
      recovery_codes_ds.where(recovery_codes_column=>code).delete
      if recovery_codes_primary?
        add_recovery_code
      end
      return true
    end
  end
  false
end
recovery_codes_ds ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 238
def recovery_codes_ds
  db[recovery_codes_table].where(recovery_codes_id_column=>session_value)
end
recovery_codes_primary? ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 230
def recovery_codes_primary?
  (features & [:otp, :sms_codes]).empty?
end
recovery_codes_remove ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 184
def recovery_codes_remove
  recovery_codes_ds.delete
end
redirect (path)
[show source]
# File lib/rodauth/features/base.rb, line 318
def redirect(path)
  request.redirect(path)
end
remember_key_ds (id=account_id)
[show source]
# File lib/rodauth/features/remember.rb, line 193
def remember_key_ds(id=account_id)
  db[remember_table].where(remember_id_column=>id)
end
remember_login ()
[show source]
# File lib/rodauth/features/remember.rb, line 116
def remember_login
  get_remember_key
  opts = Hash[remember_cookie_options]
  opts[:value] = "#{account_id}_#{remember_key_value}"
  opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
  ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
end
remove_lockout_metadata ()
[show source]
# File lib/rodauth/features/lockout.rb, line 240
def remove_lockout_metadata
  account_login_failures_ds.delete
  account_lockouts_ds.delete
end
remove_remember_key (id=account_id)
[show source]
# File lib/rodauth/features/remember.rb, line 154
def remove_remember_key(id=account_id)
  remember_key_ds(id).delete
end
remove_reset_password_key ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 157
def remove_reset_password_key
  password_reset_ds.delete
end
remove_verify_account_key ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 150
def remove_verify_account_key
  verify_account_ds.delete
end
remove_verify_login_change_key ()
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 93
def remove_verify_login_change_key
  verify_login_change_ds.delete
end
render (page)
[show source]
# File lib/rodauth/features/base.rb, line 270
def render(page)
  _view(:render, page)
end
request ()
[show source]
# File lib/rodauth/features/base.rb, line 114
def request
  scope.request
end
require_account ()
[show source]
# File lib/rodauth/features/base.rb, line 347
def require_account
  require_authentication
  require_account_session
end
require_account_session ()
[show source]
# File lib/rodauth/features/base.rb, line 352
def require_account_session
  unless account_from_session
    clear_session
    login_required
  end
end
require_authentication ()
[show source]
# File lib/rodauth/features/base.rb, line 228
def require_authentication
  require_login
end
require_current_password ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 60
def require_current_password
  if authenticated? && password_expired? && password_change_needed_redirect != request.path_info
    set_redirect_error_flash password_expiration_error_flash
    redirect password_change_needed_redirect
  end
end
require_login ()
[show source]
# File lib/rodauth/features/base.rb, line 220
def require_login
  login_required unless logged_in?
end
require_otp_setup ()
[show source]
# File lib/rodauth/features/otp.rb, line 236
def require_otp_setup
  unless otp_exists?
    set_redirect_error_status(two_factor_not_setup_error_status)
    set_redirect_error_flash two_factor_not_setup_error_flash
    redirect two_factor_need_setup_redirect
  end
end
require_sms_available ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 357
def require_sms_available
  require_sms_setup

  if sms_locked_out?
    set_redirect_error_status(lockout_error_status)
    set_redirect_error_flash sms_lockout_error_flash
    redirect sms_lockout_redirect
  end
end
require_sms_not_setup ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 349
def require_sms_not_setup
  if sms_setup?
    set_redirect_error_status(sms_already_setup_error_status)
    set_redirect_error_flash sms_already_setup_error_flash
    redirect sms_already_setup_redirect
  end
end
require_sms_setup ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 341
def require_sms_setup
  unless sms_setup?
    set_redirect_error_status(two_factor_not_setup_error_status)
    set_redirect_error_flash sms_not_setup_error_flash
    redirect sms_needs_setup_redirect
  end
end
require_two_factor_authenticated ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 66
def require_two_factor_authenticated
  unless two_factor_authenticated?
    set_redirect_error_status(two_factor_need_authentication_error_status)
    set_redirect_error_flash two_factor_need_authentication_error_flash
    redirect _two_factor_auth_required_redirect
  end
end
require_two_factor_not_authenticated ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 58
def require_two_factor_not_authenticated
  if two_factor_authenticated?
    set_redirect_error_status(two_factor_already_authenticated_error_status)
    set_redirect_error_flash two_factor_already_authenticated_error_flash
    redirect two_factor_already_authenticated_redirect
  end
end
require_two_factor_setup ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 50
def require_two_factor_setup
  unless uses_two_factor_authentication?
    set_redirect_error_status(two_factor_not_setup_error_status)
    set_redirect_error_flash two_factor_not_setup_error_flash
    redirect two_factor_need_setup_redirect
  end
end
reset_password_email_body ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 215
def reset_password_email_body
  render('reset-password-email')
end
reset_password_key_insert_hash ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 223
def reset_password_key_insert_hash
  hash = {reset_password_id_column=>account_id, reset_password_key_column=>reset_password_key_value}
  set_deadline_value(hash, reset_password_deadline_column, reset_password_deadline_interval)
  hash
end
reset_single_session_key ()
[show source]
# File lib/rodauth/features/single_session.rb, line 19
def reset_single_session_key
  if logged_in?
    single_session_ds.update(single_session_key_column=>random_key)
  end
end
response ()
[show source]
# File lib/rodauth/features/base.rb, line 118
def response
  scope.response
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, line 476
def retry_on_uniqueness_violation(&block)
  if raises_uniqueness_violation?(&block)
    yield
  end
end
return_json_response ()
[show source]
# File lib/rodauth/features/jwt.rb, line 211
def return_json_response
  response.status ||= json_response_error_status if json_response[json_response_error_key]
  set_jwt
  response['Content-Type'] ||= json_response_content_type
  response.write(_json_response_body(json_response))
  request.halt
end
route! ()
[show source]
# File lib/rodauth/features/base.rb, line 130
def route!
  if meth = self.class.route_hash[request.remaining_path]
    send(meth)
  end

  nil
end
save_account ()
[show source]
# File lib/rodauth/features/create_account.rb, line 106
def save_account
  id = nil
  raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}

  if raised
    @login_requirement_message = 'already an account with this login'
  end

  if id
    account[account_id_column] = id
  end

  id && !raised
end
send_password_changed_email ()
[show source]
# File lib/rodauth/features/change_password_notify.rb, line 18
def send_password_changed_email
  create_password_changed_email.deliver!
end
send_reset_password_email ()
[show source]
# File lib/rodauth/features/reset_password.rb, line 165
def send_reset_password_email
  create_reset_password_email.deliver!
end
send_unlock_account_email ()
[show source]
# File lib/rodauth/features/lockout.rb, line 201
def send_unlock_account_email
  @unlock_account_key_value = get_unlock_account_key
  create_unlock_account_email.deliver!
end
send_verify_account_email ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 187
def send_verify_account_email
  create_verify_account_email.deliver!
end
send_verify_login_change_email (login)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 105
def send_verify_login_change_email(login)
  create_verify_login_change_email(login).deliver!
end
session ()
[show source]
# File lib/rodauth/features/base.rb, line 122
def session
  scope.session
end
session_expiration_redirect ()
[show source]
# File lib/rodauth/features/session_expiration.rb, line 43
def session_expiration_redirect
  require_login_redirect
end
session_jwt ()
[show source]
# File lib/rodauth/features/jwt.rb, line 116
def session_jwt
  JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
end
session_value ()
[show source]
# File lib/rodauth/features/base.rb, line 152
def session_value
  session[session_key]
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, line 512
def set_deadline_value(hash, column, interval)
  if set_deadline_values?
    # :nocov:
    hash[column] = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, interval)
    # :nocov:
  end
end
set_deadline_values? ()
[show source]
# File lib/rodauth/features/base.rb, line 385
def set_deadline_values?
  db.database_type == :mysql
end
set_error_flash (message)
[show source]
# File lib/rodauth/features/base.rb, line 204
def set_error_flash(message)
  flash.now[flash_error_key] = message
end
set_expired ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 48
def set_expired
  update_activity(account_id, account_activity_expired_column)
  after_account_expiration
end
set_field_error (field, error)
[show source]
# File lib/rodauth/features/base.rb, line 138
def set_field_error(field, error)
  (@field_errors ||= {})[field] = error
end
set_http_basic_auth_error_response ()
[show source]
# File lib/rodauth/features/http_basic_auth.rb, line 53
def set_http_basic_auth_error_response
  response.status = 401
  response.headers["WWW-Authenticate"] = "Basic realm=\"#{http_basic_auth_realm}\""
end
set_jwt ()
[show source]
# File lib/rodauth/features/jwt.rb, line 219
def set_jwt
  set_jwt_token(session_jwt)
end
set_jwt_token (token)
[show source]
# File lib/rodauth/features/jwt.rb, line 128
def set_jwt_token(token)
  response.headers['Authorization'] = token
end
set_last_password_entry ()
[show source]
# File lib/rodauth/features/password_grace_period.rb, line 41
def set_last_password_entry
  session[last_password_entry_session_key] = Time.now.to_i
end
set_new_account_password (password)
[show source]
# File lib/rodauth/features/create_account.rb, line 98
def set_new_account_password(password)
  account[account_password_hash_column] = password_hash(password)
end
set_notice_flash (message)
[show source]
# File lib/rodauth/features/base.rb, line 212
def set_notice_flash(message)
  flash[flash_notice_key] = message
end
set_notice_now_flash (message)
[show source]
# File lib/rodauth/features/base.rb, line 216
def set_notice_now_flash(message)
  flash.now[flash_notice_key] = message
end
set_password (password)
[show source]
# File lib/rodauth/features/disallow_password_reuse.rb, line 18
def set_password(password)
  hash = super
  add_previous_password_hash(hash)
  hash
end
set_redirect_error_flash (message)
[show source]
# File lib/rodauth/features/base.rb, line 208
def set_redirect_error_flash(message)
  flash[flash_error_key] = message
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, line 364
def set_redirect_error_status(status)
end
set_response_error_status (status)
[show source]
# File lib/rodauth/features/base.rb, line 367
def set_response_error_status(status)
  response.status = status
end
set_session_value (key, value)
[show source]
# File lib/rodauth/features/base.rb, line 520
def set_session_value(key, value)
  session[key] = value
end
set_title (title)
[show source]
# File lib/rodauth/features/base.rb, line 198
def set_title(title)
  if title_instance_variable
    scope.instance_variable_set(title_instance_variable, title)
  end
end
setup_account_verification ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 239
def setup_account_verification
  generate_verify_account_key_value
  create_verify_account_key
  send_verify_account_email
end
show_lockout_page ()
[show source]
# File lib/rodauth/features/lockout.rb, line 245
def show_lockout_page
  set_response_error_status lockout_error_status
  set_error_flash login_lockout_error_flash
  response.write unlock_account_request_view
  request.halt
end
single_session_ds ()
[show source]
# File lib/rodauth/features/single_session.rb, line 81
def single_session_ds
  db[single_session_table].
    where(single_session_id_column=>session_value)
end
skip_status_checks? ()
[show source]
# File lib/rodauth/features/close_account.rb, line 79
def skip_status_checks?
  false
end
sms_auth_message (code)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 422
def sms_auth_message(code)
  "SMS authentication code for #{request.host} is #{code}"
end
sms_available? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 464
def sms_available?
  sms && !sms_needs_confirmation? && !sms_locked_out?
end
sms_code ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 443
def sms_code
  sms[sms_code_column]
end
sms_code_issued_at ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 447
def sms_code_issued_at
  convert_timestamp(sms[sms_issued_at_column])
end
sms_code_match? (code)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 367
def sms_code_match?(code)
  return false unless sms_current_auth?
  timing_safe_eql?(code, sms_code)
end
sms_codes_primary? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 478
def sms_codes_primary?
  !features.include?(:otp)
end
sms_confirm ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 165
def sms_confirm
  super if defined?(super)
  add_recovery_codes(recovery_codes_limit - recovery_codes.length)
end
sms_confirm_failure ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 382
def sms_confirm_failure
  sms_ds.delete
end
sms_confirm_message (code)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 426
def sms_confirm_message(code)
  "SMS confirmation code for #{request.host} is #{code}"
end
sms_confirmation_match? (code)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 372
def sms_confirmation_match?(code)
  sms_needs_confirmation? && sms_code_match?(code)
end
sms_current_auth? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 472
def sms_current_auth?
  sms_code && sms_code_issued_at + sms_code_allowed_seconds > Time.now
end
sms_disable ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 177
def sms_disable
  super if defined?(super)
  unless recovery_codes_primary?
    recovery_codes_remove
  end
end
sms_ds ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 506
def sms_ds
  db[sms_codes_table].where(sms_id_column=>session_value)
end
sms_failures ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 451
def sms_failures
  sms[sms_failures_column]
end
sms_locked_out? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 468
def sms_locked_out?
  sms_failures >= sms_failure_limit
end
sms_lockout_redirect ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 418
def sms_lockout_redirect
  _two_factor_auth_required_redirect
end
sms_needs_confirmation? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 460
def sms_needs_confirmation?
  sms && sms_failures.nil?
end
sms_new_auth_code ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 486
def sms_new_auth_code
  SecureRandom.random_number(10**sms_auth_code_length).to_s.rjust(sms_auth_code_length, "0")
end
sms_new_confirm_code ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 490
def sms_new_confirm_code
  SecureRandom.random_number(10**sms_confirm_code_length).to_s.rjust(sms_confirm_code_length, "0")
end
sms_normalize_phone (phone)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 482
def sms_normalize_phone(phone)
  phone.to_s.gsub(/\D+/, '')
end
sms_phone ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 439
def sms_phone
  sms[sms_phone_column]
end
sms_record_failure ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 434
def sms_record_failure
  update_sms(sms_failures_column=>Sequel.expr(sms_failures_column)+1)
  sms[sms_failures_column] = sms_ds.get(sms_failures_column)
end
sms_remove_failures ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 393
def sms_remove_failures
  update_sms(sms_failures_column => 0, sms_code_column => nil)
end
sms_send (phone, message)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 494
def sms_send(phone, message)
  raise NotImplementedError, "sms_send needs to be defined in the Rodauth configuration for SMS sending to work"
end
sms_send_auth_code ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 402
def sms_send_auth_code
  code = sms_new_auth_code
  sms_set_code(code)
  sms_send(sms_phone, sms_auth_message(code))
end
sms_send_confirm_code ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 408
def sms_send_confirm_code
  code = sms_new_confirm_code
  sms_set_code(code)
  sms_send(sms_phone, sms_confirm_message(code))
end
sms_set_code (code)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 430
def sms_set_code(code)
 update_sms(sms_code_column=>code, sms_issued_at_column=>Sequel::CURRENT_TIMESTAMP)
end
sms_setup (phone_number)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 386
def sms_setup(phone_number)
  # Cannot handle uniqueness violation here, as the phone number given may not match the
  # one in the table.
  sms_ds.insert(sms_id_column=>session_value, sms_phone_column=>phone_number)
  remove_instance_variable(:@sms) if instance_variable_defined?(:@sms)
end
sms_setup? ()
[show source]
# File lib/rodauth/features/sms_codes.rb, line 455
def sms_setup?
  return false unless sms
  !sms_needs_confirmation?
end
sms_valid_phone? (phone)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 414
def sms_valid_phone?(phone)
  phone.length >= sms_phone_min_length
end
split_token (token)
[show source]
# File lib/rodauth/features/email_base.rb, line 45
def split_token(token)
  token.split(token_separator, 2)
end
template_path (page)
[show source]
# File lib/rodauth/features/base.rb, line 445
def template_path(page)
  File.join(File.dirname(__FILE__), '../../../templates', "#{page}.str")
end
throw_basic_auth_error (*args)
[show source]
# File lib/rodauth/features/http_basic_auth.rb, line 58
def throw_basic_auth_error(*args)
  set_http_basic_auth_error_response
  throw_error(*args) 
end
throw_error (field, error)
[show source]
# File lib/rodauth/features/base.rb, line 371
def throw_error(field, error)
  set_field_error(field, error)
  throw :rodauth_error
end
throw_error_status (status, field, error)
[show source]
# File lib/rodauth/features/base.rb, line 376
def throw_error_status(status, field, error)
  set_response_error_status(status)
  throw_error(field, error)
end
timing_safe_eql? (provided, actual)
[show source]
# File lib/rodauth/features/base.rb, line 342
def timing_safe_eql?(provided, actual)
  provided = provided.to_s
  Rack::Utils.secure_compare(provided.ljust(actual.length), actual) && provided.length == actual.length
end
transaction (opts={}, &block)
[show source]
# File lib/rodauth/features/base.rb, line 322
def transaction(opts={}, &block)
  db.transaction(opts, &block)
end
two_factor_auth_fallback_redirect ()
[show source]
# File lib/rodauth/features/recovery_codes.rb, line 135
def two_factor_auth_fallback_redirect
  recovery_auth_redirect
end
two_factor_auth_required_redirect ()
[show source]
# File lib/rodauth/features/otp.rb, line 209
def two_factor_auth_required_redirect
  "#{prefix}/#{otp_auth_route}"
end
two_factor_authenticate (type)
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 119
def two_factor_authenticate(type)
  two_factor_update_session(type)
  two_factor_remove_auth_failures
  after_two_factor_authentication
  set_notice_flash two_factor_auth_notice_flash
  redirect two_factor_auth_redirect
end
two_factor_authenticated? ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 94
def two_factor_authenticated?
  !!session[two_factor_session_key]
end
two_factor_authentication_setup? ()
[show source]
# File lib/rodauth/features/otp.rb, line 201
def two_factor_authentication_setup?
  super || otp_exists?
end
two_factor_modifications_require_password? ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 36
def two_factor_modifications_require_password?
  modifications_require_password?
end
two_factor_need_setup_redirect ()
[show source]
# File lib/rodauth/features/otp.rb, line 205
def two_factor_need_setup_redirect
  "#{prefix}/#{otp_setup_route}"
end
two_factor_password_match? (password)
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 86
def two_factor_password_match?(password)
  if two_factor_modifications_require_password?
    password_match?(password)
  else
    true
  end
end
two_factor_remove ()
[show source]
# File lib/rodauth/features/otp.rb, line 213
def two_factor_remove
  super
  otp_remove
end
two_factor_remove_auth_failures ()
[show source]
# File lib/rodauth/features/otp.rb, line 218
def two_factor_remove_auth_failures
  super
  otp_remove_auth_failures
end
two_factor_remove_session ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 127
def two_factor_remove_session
  session.delete(two_factor_session_key)
  session[two_factor_setup_session_key] = false
end
two_factor_update_session (type)
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 132
def two_factor_update_session(type)
  session[two_factor_session_key] = type
  session[two_factor_setup_session_key] = true
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, line 494
def unique_constraint_violation_class
  if db.adapter_scheme == :jdbc && db.database_type == :sqlite
    # :nocov:
    Sequel::ConstraintViolation
    # :nocov:
  else
    Sequel::UniqueConstraintViolation
  end
end
unlock_account ()
[show source]
# File lib/rodauth/features/lockout.rb, line 145
def unlock_account
  transaction do
    remove_lockout_metadata
  end
end
unlock_account_email_body ()
[show source]
# File lib/rodauth/features/lockout.rb, line 256
def unlock_account_email_body
  render('unlock-account-email')
end
update_account (values, ds=account_ds)
[show source]
# File lib/rodauth/features/base.rb, line 534
def update_account(values, ds=account_ds)
  update_hash_ds(account, ds, values)
end
update_activity (account_id, *columns)
[show source]
# File lib/rodauth/features/account_expiration.rb, line 112
def update_activity(account_id, *columns)
  ds = account_activity_ds(account_id)
  hash = {}
  columns.each do |c|
    hash[c] = Sequel::CURRENT_TIMESTAMP
  end
  if ds.update(hash) == 0
    hash[account_activity_id_column] = account_id
    hash[account_activity_last_activity_column] ||= Sequel::CURRENT_TIMESTAMP
    hash[account_activity_last_login_column] ||= Sequel::CURRENT_TIMESTAMP
    # It is safe to ignore uniqueness violations here, as a concurrent insert would also use current timestamps.
    ignore_uniqueness_violation{ds.insert(hash)}
  end
end
update_hash_ds (hash, ds, values)
[show source]
# File lib/rodauth/features/base.rb, line 524
def update_hash_ds(hash, ds, values)
  num = ds.update(values)
  if num == 1
    values.each do |k, v|
      account[k] = v == Sequel::CURRENT_TIMESTAMP ? Time.now : v
    end
  end
  num
end
update_last_activity ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 42
def update_last_activity
  if session_value
    update_activity(session_value, account_activity_last_activity_column)
  end
end
update_last_login ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 38
def update_last_login
  update_activity(account_id, account_activity_last_login_column, account_activity_last_activity_column)
end
update_login (login)
[show source]
# File lib/rodauth/features/change_login.rb, line 75
def update_login(login)
  updated = nil
  raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
  if raised
    @login_requirement_message = 'already an account with this login'
  end
  updated && !raised
end
update_password_changed_at ()
[show source]
# File lib/rodauth/features/password_expiration.rb, line 51
def update_password_changed_at
  ds = password_expiration_ds
  if ds.update(password_expiration_changed_at_column=>Sequel::CURRENT_TIMESTAMP) == 0
    # Ignoring the violation is safe here, since a concurrent insert would also set it to the
    # current timestamp.
    ignore_uniqueness_violation{ds.insert(password_expiration_id_column=>account_id)}
  end
end
update_password_hash? ()
[show source]
# File lib/rodauth/features/update_password_hash.rb, line 16
def update_password_hash?
  password_hash_cost != @current_password_hash_cost
end
update_session ()
[show source]
# File lib/rodauth/features/account_expiration.rb, line 98
def update_session
  check_account_expiration
  super
end
update_single_session_key ()
[show source]
# File lib/rodauth/features/single_session.rb, line 53
def update_single_session_key
  key = random_key
  set_session_value(single_session_session_key, key)
  if single_session_ds.update(single_session_key_column=>key) == 0
    # Don't handle uniqueness violations here.  While we could get the stored key from the
    # database, it could lead to two sessions sharing the same key, which this feature is
    # designed to prevent.
    single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key)
  end
end
update_sms (values)
[show source]
# File lib/rodauth/features/sms_codes.rb, line 498
def update_sms(values)
  update_hash_ds(sms, sms_ds, values)
end
use_database_authentication_functions? ()
[show source]
# File lib/rodauth/features/base.rb, line 389
def use_database_authentication_functions?
  case db.database_type
  when :postgres, :mysql, :mssql
    true
  else
    # :nocov:
    false
    # :nocov:
  end
end
use_date_arithmetic? ()
[show source]
# File lib/rodauth/features/base.rb, line 381
def use_date_arithmetic?
  set_deadline_values?
end
use_jwt? ()
[show source]
# File lib/rodauth/features/jwt.rb, line 132
def use_jwt?
  jwt_token || only_json? || json_request?
end
use_request_specific_csrf_tokens? ()
[show source]
# File lib/rodauth/features/base.rb, line 400
def use_request_specific_csrf_tokens?
  scope.opts[:rodauth_csrf] == :route_csrf && scope.use_request_specific_csrf_tokens?
end
uses_two_factor_authentication? ()
[show source]
# File lib/rodauth/features/two_factor_base.rb, line 102
def uses_two_factor_authentication?
  return false unless logged_in?
  session[two_factor_setup_session_key] = two_factor_authentication_setup? unless session.has_key?(two_factor_setup_session_key)
  session[two_factor_setup_session_key]
end
valid_jwt? ()
[show source]
# File lib/rodauth/features/jwt.rb, line 136
def valid_jwt?
  !!(jwt_token && jwt_payload)
end
verified_account? ()
[show source]
# File lib/rodauth/features/verify_account_grace_period.rb, line 16
def verified_account?
  logged_in? && !session[unverified_account_session_key]
end
verify_account ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 154
def verify_account
  update_account(account_status_column=>account_open_status_value) == 1
end
verify_account_check_already_logged_in ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 245
def verify_account_check_already_logged_in
  check_already_logged_in
end
verify_account_ds (id=account_id)
[show source]
# File lib/rodauth/features/verify_account.rb, line 278
def verify_account_ds(id=account_id)
  db[verify_account_table].where(verify_account_id_column=>id)
end
verify_account_email_body ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 274
def verify_account_email_body
  render('verify-account-email')
end
verify_account_email_resend ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 158
def verify_account_email_resend
  if @verify_account_key_value = get_verify_account_key(account_id)
    send_verify_account_email
    true
  end
end
verify_account_key_insert_hash ()
[show source]
# File lib/rodauth/features/verify_account.rb, line 266
def verify_account_key_insert_hash
  {verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
end
verify_login_change ()
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 97
def verify_login_change
  update_account(login_column=>verify_login_change_new_login)
end
verify_login_change_ds (id=account_id)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 176
def verify_login_change_ds(id=account_id)
  db[verify_login_change_table].where(verify_login_change_id_column=>id)
end
verify_login_change_email_body ()
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 172
def verify_login_change_email_body
  render('verify-login-change-email')
end
verify_login_change_key_insert_hash (login)
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 162
def verify_login_change_key_insert_hash(login)
  hash = {verify_login_change_id_column=>account_id, verify_login_change_key_column=>verify_login_change_key_value, verify_login_change_login_column=>login}
  set_deadline_value(hash, verify_login_change_deadline_column, verify_login_change_deadline_interval)
  hash
end
verify_login_change_old_login ()
[show source]
# File lib/rodauth/features/verify_login_change.rb, line 121
def verify_login_change_old_login
  account_ds.get(login_column)
end
view (page, title)
[show source]
# File lib/rodauth/features/base.rb, line 265
def view(page, title)
  set_title(title)
  _view(:view, page)
end