module Rodauth

:nocov:

Constants

FEATURES
INVALID_DOMAIN
MAJOR

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

MINOR

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

TINY

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

VERSION

The full version of Rodauth as a string

VERSION_NUMBER

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

Public Class Methods

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

Public Instance Methods

_account_from_email_auth_key(token) click to toggle source
    # File lib/rodauth/features/email_auth.rb
236 def _account_from_email_auth_key(token)
237   account_from_key(token, account_open_status_value){|id| get_email_auth_key(id)}
238 end
_account_from_id(id, status_id=nil) click to toggle source
    # File lib/rodauth/features/base.rb
748 def _account_from_id(id, status_id=nil)
749   ds = account_ds(id)
750   ds = ds.where(account_status_column=>status_id) if status_id && !skip_status_checks?
751   ds.first
752 end
_account_from_login(login) click to toggle source
    # File lib/rodauth/features/base.rb
735 def _account_from_login(login)
736   ds = account_table_ds.where(login_column=>login)
737   ds = ds.select(*account_select) if account_select
738   ds = ds.where(account_status_column=>[account_unverified_status_value, account_open_status_value]) unless skip_status_checks?
739   ds.first
740 end
_account_from_refresh_token(token) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
111 def _account_from_refresh_token(token)
112   id, token_id, key = _account_refresh_token_split(token)
113 
114   unless key &&
115          (id.to_s == session_value.to_s) &&
116          (actual = get_active_refresh_token(id, token_id)) &&
117          (timing_safe_eql?(key, convert_token_key(actual)) || (hmac_secret_rotation? && timing_safe_eql?(key, compute_old_hmac(actual)))) &&
118          jwt_refresh_token_match?(key)
119     return
120   end
121 
122   ds = account_ds(id)
123   ds = ds.where(account_session_status_filter) unless skip_status_checks?
124   ds.first
125 end
_account_from_reset_password_key(token) click to toggle source
    # File lib/rodauth/features/reset_password.rb
253 def _account_from_reset_password_key(token)
254   account_from_key(token, account_open_status_value){|id| get_password_reset_key(id)}
255 end
_account_from_session() click to toggle source
    # File lib/rodauth/features/base.rb
742 def _account_from_session
743   ds = account_ds(session_value)
744   ds = ds.where(account_session_status_filter) unless skip_status_checks?
745   ds.first
746 end
_account_from_unlock_key(token) click to toggle source
    # File lib/rodauth/features/lockout.rb
297 def _account_from_unlock_key(token)
298   account_from_key(token){|id| account_lockouts_ds(id).get(account_lockouts_key_column)}
299 end
_account_from_verify_account_key(token) click to toggle source
    # File lib/rodauth/features/verify_account.rb
302 def _account_from_verify_account_key(token)
303   account_from_key(token, account_unverified_status_value){|id| get_verify_account_key(id)}
304 end
_account_from_verify_login_change_key(token) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
210 def _account_from_verify_login_change_key(token)
211   account_from_key(token) do |id|
212     @verify_login_change_new_login, key = get_verify_login_change_login_and_key(id)
213     key
214   end
215 end
_account_refresh_token_split(token) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
127 def _account_refresh_token_split(token)
128   id, token = split_token(token)
129   id = convert_token_id(id)
130   return unless id && token
131 
132   token_id, key = split_token(token)
133   token_id = convert_token_id(token_id)
134   return unless token_id && key
135 
136   [id, token_id, key]
137 end
_around_rodauth() { || ... } click to toggle source
    # File lib/rodauth/features/base.rb
537 def _around_rodauth
538   yield
539 end
_email_auth_request() click to toggle source
    # File lib/rodauth/features/email_auth.rb
178 def _email_auth_request
179   if email_auth_email_recently_sent?
180     set_redirect_error_flash email_auth_email_recently_sent_error_flash
181     redirect email_auth_email_recently_sent_redirect
182   end
183 
184   generate_email_auth_key_value
185   transaction do
186     before_email_auth_request
187     create_email_auth_key
188     send_email_auth_email
189     after_email_auth_request
190   end
191 
192   email_auth_email_sent_response
193 end
_field_attributes(field) click to toggle source
    # File lib/rodauth/features/base.rb
767 def _field_attributes(field)
768   nil
769 end
_field_error_attributes(field) click to toggle source
    # File lib/rodauth/features/base.rb
771 def _field_error_attributes(field)
772   " aria-invalid=\"true\" aria-describedby=\"#{field}_error_message\" "
773 end
_formatted_field_error(field, error) click to toggle source
    # File lib/rodauth/features/base.rb
775 def _formatted_field_error(field, error)
776   "<span class=\"#{input_field_error_message_class}\" id=\"#{field}_error_message\">#{error}</span>"
777 end
_json_response_body(hash) click to toggle source
    # File lib/rodauth/features/json.rb
215 def _json_response_body(hash)
216   request.send(:convert_to_json, hash)
217 end
_jwt_decode_opts() click to toggle source
    # File lib/rodauth/features/jwt.rb
112 def _jwt_decode_opts
113   jwt_decode_opts
114 end
_jwt_decode_secrets() click to toggle source
    # File lib/rodauth/features/jwt.rb
117 def _jwt_decode_secrets
118   secrets = [jwt_secret, jwt_old_secret]
119   secrets.compact!
120   secrets
121 end
_login(auth_type) click to toggle source
    # File lib/rodauth/features/login.rb
167 def _login(auth_type)
168   warn("Deprecated #_login method called, use #login instead.")
169   login(auth_type)
170 end
_login_response() click to toggle source
    # File lib/rodauth/features/login.rb
147 def _login_response
148   set_notice_flash login_notice_flash
149   redirect(saved_login_redirect || login_redirect)
150 end
_multi_phase_login_forms() click to toggle source
Calls superclass method
    # File lib/rodauth/features/email_auth.rb
168 def _multi_phase_login_forms
169   forms = super
170   forms << [30, email_auth_request_form, :_email_auth_request] if valid_login_entered? && allow_email_auth?
171   forms
172 end
_new_account(login) click to toggle source
    # File lib/rodauth/features/create_account.rb
121 def _new_account(login)
122   acc = {login_column=>login}
123   unless skip_status_checks?
124     acc[account_status_column] = account_initial_status_value
125   end
126   acc
127 end
_otp() click to toggle source
    # File lib/rodauth/features/otp.rb
446 def _otp
447   _otp_for_key(otp_user_key)
448 end
_otp_add_key(secret) click to toggle source
    # File lib/rodauth/features/otp.rb
431 def _otp_add_key(secret)
432   # Uniqueness errors can't be handled here, as we can't be sure the secret provided
433   # is the same as the current secret.
434   otp_key_ds.insert(otp_keys_id_column=>session_value, otp_keys_column=>secret)
435 end
_otp_for_key(key) click to toggle source
    # File lib/rodauth/features/otp.rb
442 def _otp_for_key(key)
443   otp_class.new(key, :issuer=>otp_issuer, :digits=>otp_digits, :interval=>otp_interval)
444 end
_otp_interval() click to toggle source
    # File lib/rodauth/features/otp.rb
423 def _otp_interval
424   otp_interval || 30
425 end
_otp_key() click to toggle source
    # File lib/rodauth/features/otp.rb
437 def _otp_key
438   @otp_user_key = nil
439   otp_key_ds.get(otp_keys_column)
440 end
_otp_tmp_key(secret) click to toggle source
    # File lib/rodauth/features/otp.rb
417 def _otp_tmp_key(secret)
418   @otp_tmp_key = true
419   @otp_user_key = nil
420   @otp_key = secret
421 end
_otp_valid_code?(ot_pass, otp) click to toggle source
    # File lib/rodauth/features/otp.rb
262 def _otp_valid_code?(ot_pass, otp)
263   return false unless otp_exists?
264   ot_pass = ot_pass.gsub(/\s+/, '')
265   if drift = otp_drift
266     if otp.respond_to?(:verify_with_drift)
267       # :nocov:
268       otp.verify_with_drift(ot_pass, drift)
269       # :nocov:
270     else
271       otp.verify(ot_pass, :drift_behind=>drift, :drift_ahead=>drift)
272     end
273   else
274     otp.verify(ot_pass)
275   end
276 end
_otp_valid_code_for_old_secret() click to toggle source

Called for valid OTP codes for old secrets

    # File lib/rodauth/features/otp.rb
428 def _otp_valid_code_for_old_secret
429 end
_override_webauthn_credential_response_verify(webauthn_credential) click to toggle source
    # File lib/rodauth/features/webauthn.rb
431 def _override_webauthn_credential_response_verify(webauthn_credential)
432   # no need to override
433 end
_process_raw_hmac(hmac) click to toggle source
    # File lib/rodauth/features/base.rb
541 def _process_raw_hmac(hmac)
542   s = [hmac].pack('m')
543   s.chomp!("=\n")
544   s.tr!('+/', '-_')
545   s
546 end
_recovery_codes() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
260 def _recovery_codes
261   recovery_codes_ds.select_map(recovery_codes_column)
262 end
_return_json_response() click to toggle source
    # File lib/rodauth/features/json.rb
205 def _return_json_response
206   response.status ||= json_response_error_status if json_response_error?
207   response['Content-Type'] ||= json_response_content_type
208   return_response _json_response_body(json_response)
209 end
_set_otp_unlock_info() click to toggle source
   # File lib/rodauth/features/json.rb
75 def _set_otp_unlock_info
76   if use_json?
77     json_response[:num_successes] = otp_unlock_num_successes
78     json_response[:required_successes] = otp_unlock_auths_required
79     json_response[:next_attempt_after] = otp_unlock_next_auth_attempt_after.to_i
80   end
81 end
_setup_account_lockouts_hash(account_id, key) click to toggle source
    # File lib/rodauth/features/lockout.rb
169 def _setup_account_lockouts_hash(account_id, key)
170   hash = {account_lockouts_id_column=>account_id, account_lockouts_key_column=>key}
171   set_deadline_value(hash, account_lockouts_deadline_column, account_lockouts_deadline_interval)
172   hash
173 end
_sms() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
524 def _sms
525   sms_ds.first
526 end
_sms_request_response() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
472 def _sms_request_response
473   set_notice_flash sms_request_notice_flash
474   redirect sms_auth_redirect
475 end
_template_opts(opts, page) click to toggle source

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

    # File lib/rodauth/features/base.rb
910 def _template_opts(opts, page)
911   opts = scope.send(:find_template, scope.send(:parse_template_opts, page, opts))
912   unless File.file?(scope.send(:template_path, opts))
913     opts[:path] = template_path(page)
914   end
915   opts
916 end
_two_factor_auth_response() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
255 def _two_factor_auth_response
256   saved_two_factor_auth_redirect = remove_session_value(two_factor_auth_redirect_session_key)
257   set_notice_flash two_factor_auth_notice_flash
258   redirect(saved_two_factor_auth_redirect || two_factor_auth_redirect)
259 end
_two_factor_remove_all_from_session() click to toggle source
Calls superclass method
    # File lib/rodauth/features/otp.rb
365 def _two_factor_remove_all_from_session
366   two_factor_remove_session('totp')
367   super
368 end
_update_login(login) click to toggle source
   # File lib/rodauth/features/change_login.rb
83 def _update_login(login)
84   updated = nil
85   raised = raises_uniqueness_violation?{updated = update_account({login_column=>login}, account_ds.exclude(login_column=>login)) == 1}
86   if raised
87     set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
88   end
89   updated && !raised
90 end
_view(meth, page) click to toggle source
    # File lib/rodauth/features/base.rb
918 def _view(meth, page)
919   scope.send(meth, _view_opts(page))
920 end
_view_opts(page) click to toggle source
    # File lib/rodauth/features/base.rb
899 def _view_opts(page)
900   opts = template_opts.dup
901   opts[:locals] = opts[:locals] ? opts[:locals].dup : {}
902   opts[:locals][:rodauth] = self
903   opts[:cache] = cache_templates
904   opts[:cache_key] = :"rodauth_#{page}"
905   _template_opts(opts, page)
906 end
account!() click to toggle source
    # File lib/rodauth/features/base.rb
381 def account!
382   account || (session_value && account_from_session)
383 end
account_activity_ds(account_id) click to toggle source
    # File lib/rodauth/features/account_expiration.rb
104 def account_activity_ds(account_id)
105   db[account_activity_table].
106     where(account_activity_id_column=>account_id)
107 end
account_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/base.rb
787 def account_ds(id=account_id)
788   raise ArgumentError, "invalid account id passed to account_ds" unless id
789   ds = account_table_ds.where(account_id_column=>id)
790   ds = ds.select(*account_select) if account_select
791   ds
792 end
account_expired?() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
54 def account_expired?
55   columns = [account_activity_last_activity_column, account_activity_last_login_column, account_activity_expired_column]
56   last_activity, last_login, expired = account_activity_ds(account_id).get(columns)
57   return true if expired
58   timestamp = convert_timestamp(expire_account_on_last_activity? ? last_activity : last_login)
59   return false unless timestamp
60   timestamp < Time.now - expire_account_after
61 end
account_expired_at() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
35 def account_expired_at
36   get_activity_timestamp(account_id, account_activity_expired_column)
37 end
account_from_email_auth_key(key) click to toggle source
    # File lib/rodauth/features/email_auth.rb
131 def account_from_email_auth_key(key)
132   @account = _account_from_email_auth_key(key)
133 end
account_from_id(id, status_id=nil) click to toggle source
    # File lib/rodauth/features/base.rb
389 def account_from_id(id, status_id=nil)
390   @account = _account_from_id(id, status_id)
391 end
account_from_key(token, status_id=nil) { |id| ... } click to toggle source
   # File lib/rodauth/features/email_base.rb
65 def account_from_key(token, status_id=nil)
66   id, key = split_token(token)
67   id = convert_token_id(id)
68   return unless id && key
69 
70   return unless actual = yield(id)
71 
72   unless (hmac_secret && timing_safe_eql?(key, convert_email_token_key(actual))) ||
73      (hmac_secret_rotation? && timing_safe_eql?(key, compute_old_hmac(actual))) ||
74      ((!hmac_secret || allow_raw_email_token?) && timing_safe_eql?(key, actual))
75     return
76   end
77   _account_from_id(id, status_id)
78 end
account_from_login(login) click to toggle source
    # File lib/rodauth/features/base.rb
279 def account_from_login(login)
280   @account = _account_from_login(login)
281 end
account_from_refresh_token(token) click to toggle source
   # File lib/rodauth/features/jwt_refresh.rb
88 def account_from_refresh_token(token)
89   @account = _account_from_refresh_token(token)
90 end
account_from_reset_password_key(key) click to toggle source
Calls superclass method
   # File lib/rodauth/features/password_expiration.rb
45 def account_from_reset_password_key(key)
46   if a = super
47     check_password_change_allowed
48   end
49   a
50 end
account_from_session() click to toggle source
    # File lib/rodauth/features/base.rb
385 def account_from_session
386   @account = _account_from_session
387 end
account_from_unlock_key(key) click to toggle source
    # File lib/rodauth/features/lockout.rb
220 def account_from_unlock_key(key)
221   @account = _account_from_unlock_key(key)
222 end
account_from_verify_account_key(key) click to toggle source
    # File lib/rodauth/features/verify_account.rb
196 def account_from_verify_account_key(key)
197   @account = _account_from_verify_account_key(key)
198 end
account_from_verify_login_change_key(key) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
120 def account_from_verify_login_change_key(key)
121   @account = _account_from_verify_login_change_key(key)
122 end
account_from_webauthn_login() click to toggle source
Calls superclass method
   # File lib/rodauth/features/webauthn_autofill.rb
44 def account_from_webauthn_login
45   return super if param_or_nil(login_param)
46 
47   credential_id = webauthn_auth_data["id"]
48   account_id = db[webauthn_keys_table]
49     .where(webauthn_keys_webauthn_id_column => credential_id)
50     .get(webauthn_keys_account_id_column)
51 
52   unless account_id
53     throw_error_reason(:invalid_webauthn_id, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_webauthn_id_message)
54   end
55 
56   account_from_id(account_id)
57 end
account_id() click to toggle source
    # File lib/rodauth/features/base.rb
269 def account_id
270   account[account_id_column]
271 end
Also aliased as: account_session_value
account_in_unverified_grace_period?() click to toggle source
   # File lib/rodauth/features/verify_account_grace_period.rb
85 def account_in_unverified_grace_period?
86   return false unless account!
87   account[account_status_column] == account_unverified_status_value &&
88     verify_account_grace_period &&
89     !verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
90 end
account_initial_status_value() click to toggle source
    # File lib/rodauth/features/base.rb
377 def account_initial_status_value
378   account_open_status_value
379 end
account_lockouts_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/lockout.rb
293 def account_lockouts_ds(id=account_id)
294   db[account_lockouts_table].where(account_lockouts_id_column=>id)
295 end
account_login_failures_ds() click to toggle source
    # File lib/rodauth/features/lockout.rb
289 def account_login_failures_ds
290   db[account_login_failures_table].where(account_login_failures_id_column=>account_id)
291 end
account_password_hash_column() click to toggle source

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.

    # File lib/rodauth/features/base.rb
303 def account_password_hash_column
304   nil
305 end
Also aliased as: account_password_hash_column
account_session_status_filter() click to toggle source
    # File lib/rodauth/features/base.rb
779 def account_session_status_filter
780   {account_status_column=>account_open_status_value}
781 end
account_session_value()
Alias for: account_id
account_table_ds() click to toggle source
    # File lib/rodauth/features/base.rb
794 def account_table_ds
795   db[accounts_table]
796 end
account_webauthn_ids() click to toggle source
    # File lib/rodauth/features/webauthn.rb
271 def account_webauthn_ids
272   webauthn_keys_ds.select_map(webauthn_keys_webauthn_id_column)
273 end
account_webauthn_usage() click to toggle source
    # File lib/rodauth/features/webauthn.rb
275 def account_webauthn_usage
276   webauthn_keys_ds.select_hash(webauthn_keys_webauthn_id_column, webauthn_keys_last_use_column)
277 end
account_webauthn_user_id() click to toggle source
    # File lib/rodauth/features/webauthn.rb
279 def account_webauthn_user_id
280   unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
281     webauthn_id = WebAuthn.generate_user_id
282     if e = raised_uniqueness_violation do
283           webauthn_user_ids_ds.insert(
284             webauthn_user_ids_account_id_column => webauthn_account_id,
285             webauthn_user_ids_webauthn_id_column => webauthn_id
286           )
287         end
288       # If two requests to create a webauthn user id are sent at the same time and an insert
289       # is attempted for both, one will fail with a unique constraint violation.  In that case
290       # it is safe for the second one to use the webauthn user id inserted by the other request.
291       # If there is still no webauthn user id at this point, then we'll just reraise the
292       # exception.
293       # :nocov:
294       raise e unless webauthn_id = webauthn_user_ids_ds.get(webauthn_user_ids_webauthn_id_column)
295       # :nocov:
296     end
297   end
298 
299   webauthn_id
300 end
active_remember_key_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/remember.rb
259 def active_remember_key_ds(id=account_id)
260   remember_key_ds(id).where(Sequel.expr(remember_deadline_column) > Sequel::CURRENT_TIMESTAMP)
261 end
active_sessions_ds() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
199 def active_sessions_ds
200   db[active_sessions_table].
201     where(active_sessions_account_id_column=>session_value || account_id)
202 end
active_sessions_insert_hash() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
162 def active_sessions_insert_hash
163   {active_sessions_account_id_column => session_value, active_sessions_session_id_column => compute_hmac(active_sessions_key)}
164 end
active_sessions_update_hash() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
166 def active_sessions_update_hash
167   h = {active_sessions_last_use_column => Sequel::CURRENT_TIMESTAMP}
168 
169   if hmac_secret_rotation?
170     h[active_sessions_session_id_column] = compute_hmac(session[session_id_session_key])
171   end
172 
173   h
174 end
add_active_session() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
68 def add_active_session
69   key = generate_active_sessions_key
70   set_session_value(session_id_session_key, key)
71   if e = raises_uniqueness_violation?{active_sessions_ds.insert(active_sessions_insert_hash)}
72     handle_duplicate_active_session_id(e)
73   end
74   nil
75 end
add_audit_log(account_id, action) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
39 def add_audit_log(account_id, action)
40   if hash = audit_log_insert_hash(account_id, action)
41     audit_log_ds.insert(hash)
42   end
43 end
add_field_error_class(field) click to toggle source
    # File lib/rodauth/features/base.rb
184 def add_field_error_class(field)
185   if field_error(field)
186     " #{input_field_error_class}"
187   end
188 end
add_previous_password_hash(hash) click to toggle source
   # File lib/rodauth/features/disallow_password_reuse.rb
25 def add_previous_password_hash(hash) 
26   ds = previous_password_ds
27 
28   unless @dont_check_previous_password
29     keep_before = ds.reverse(previous_password_id_column).
30       limit(nil, previous_passwords_to_check).
31       get(previous_password_id_column)
32 
33     if keep_before
34       ds.where(Sequel.expr(previous_password_id_column) <= keep_before).
35         delete
36     end
37   end
38 
39   # This should never raise uniqueness violations, as it uses a serial primary key
40   ds.insert(previous_password_account_id_column=>account_id, previous_password_hash_column=>hash)
41 end
add_recovery_code() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
187 def add_recovery_code
188   # This should never raise uniqueness violations unless the recovery code is the same, and the odds of that
189   # are 1/256**32 assuming a good random number generator.  Still, attempt to handle that case by retrying
190   # on such a uniqueness violation.
191   retry_on_uniqueness_violation do
192     recovery_codes_ds.insert(recovery_codes_id_column=>session_value, recovery_codes_column=>new_recovery_code)
193   end
194 end
add_recovery_codes(number) click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
177 def add_recovery_codes(number)
178   return if number <= 0
179   transaction do
180     number.times do
181       add_recovery_code
182     end
183   end
184   remove_instance_variable(:@recovery_codes)
185 end
add_remember_key() click to toggle source
    # File lib/rodauth/features/remember.rb
159 def add_remember_key
160   hash = {remember_id_column=>account_id, remember_key_column=>remember_key_value}
161   set_deadline_value(hash, remember_deadline_column, remember_deadline_interval)
162 
163   if e = raised_uniqueness_violation{remember_key_ds.insert(hash)}
164     # If inserting into the remember key table causes a violation, we can pull the
165     # existing row from the table.  If there is no invalid row, we can then reraise.
166     raise e unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
167   end
168 end
add_webauthn_credential(_) click to toggle source
Calls superclass method
    # File lib/rodauth/features/recovery_codes.rb
151 def add_webauthn_credential(_)
152   super if defined?(super)
153   auto_add_missing_recovery_codes
154 end
after_change_password() click to toggle source
Calls superclass method
   # File lib/rodauth/features/change_password_notify.rb
11 def after_change_password
12   super
13   send_password_changed_email
14 end
after_close_account() click to toggle source
Calls superclass method
    # File lib/rodauth/features/account_expiration.rb
 99 def after_close_account
100   super if defined?(super)
101   account_activity_ds(account_id).delete
102 end
after_create_account() click to toggle source
Calls superclass method
   # File lib/rodauth/features/disallow_password_reuse.rb
87 def after_create_account
88   if account_password_hash_column && !(respond_to?(:verify_account_set_password?) && verify_account_set_password?)
89     add_previous_password_hash(password_hash(param(password_param)))
90   end
91   super if defined?(super)
92 end
after_login() click to toggle source
Calls superclass method
    # File lib/rodauth/features/email_auth.rb
201 def after_login
202   # Remove the email auth key after any login, even if
203   # it is a password login.  This is done to invalidate
204   # the email login when a user has a password and requests
205   # email authentication, but then remembers their password
206   # and doesn't need the link.  At that point, the link
207   # that allows login access to the account becomes a
208   # security liability, and it is best to remove it.
209   remove_email_auth_key
210   super
211 end
after_login_entered_during_multi_phase_login() click to toggle source
Calls superclass method
    # File lib/rodauth/features/email_auth.rb
149 def after_login_entered_during_multi_phase_login
150   # If forcing email auth, just send the email link.
151   _email_auth_request if force_email_auth?
152 
153   super
154 end
after_login_failure() click to toggle source
Calls superclass method
    # File lib/rodauth/features/lockout.rb
256 def after_login_failure
257   invalid_login_attempted
258   super
259 end
after_logout() click to toggle source
Calls superclass method
    # File lib/rodauth/features/remember.rb
235 def after_logout
236   forget_login
237   super if defined?(super)
238 end
after_otp_authentication_failure() click to toggle source
Calls superclass method
   # File lib/rodauth/features/otp_lockout_email.rb
18 def after_otp_authentication_failure
19   super
20 
21   if otp_locked_out? && send_otp_locked_out_email?
22     send_otp_locked_out_email
23   end
24 end
after_otp_disable() click to toggle source
Calls superclass method
   # File lib/rodauth/features/otp_modify_email.rb
18 def after_otp_disable
19   super
20   send_otp_disabled_email
21 end
after_otp_setup() click to toggle source
Calls superclass method
   # File lib/rodauth/features/otp_modify_email.rb
13 def after_otp_setup
14   super
15   send_otp_setup_email
16 end
after_otp_unlock_auth_failure() click to toggle source
Calls superclass method
   # File lib/rodauth/features/json.rb
91 def after_otp_unlock_auth_failure
92   super if defined?(super)
93   _set_otp_unlock_info
94 end
after_otp_unlock_auth_success() click to toggle source
Calls superclass method
   # File lib/rodauth/features/json.rb
83 def after_otp_unlock_auth_success
84   super if defined?(super)
85   if otp_locked_out?
86     _set_otp_unlock_info
87     json_response[:deadline] = otp_unlock_deadline.to_i
88   end
89 end
after_otp_unlock_not_yet_available() click to toggle source
Calls superclass method
   # File lib/rodauth/features/json.rb
96 def after_otp_unlock_not_yet_available
97   super if defined?(super)
98   _set_otp_unlock_info
99 end
after_refresh_token() click to toggle source
Calls superclass method
    # File lib/rodauth/features/active_sessions.rb
130 def after_refresh_token
131   super if defined?(super)
132   if prev_key = session[session_id_session_key]
133     key = generate_active_sessions_key
134     set_session_value(session_id_session_key, key)
135     active_sessions_ds.
136       where(active_sessions_session_id_column => compute_hmacs(prev_key)).
137       update(active_sessions_session_id_column => compute_hmac(key))
138   end
139 end
after_reset_password() click to toggle source
Calls superclass method
   # File lib/rodauth/features/password_grace_period.rb
39 def after_reset_password
40   super if defined?(super)
41   @last_password_entry = Time.now.to_i
42 end
after_sms_disable() click to toggle source
Calls superclass method
    # File lib/rodauth/features/recovery_codes.rb
230 def after_sms_disable
231   super if defined?(super)
232   auto_remove_recovery_codes
233 end
after_webauthn_remove() click to toggle source
Calls superclass method
    # File lib/rodauth/features/recovery_codes.rb
235 def after_webauthn_remove
236   super if defined?(super)
237   auto_remove_recovery_codes
238 end
after_webauthn_setup() click to toggle source
Calls superclass method
   # File lib/rodauth/features/webauthn_modify_email.rb
13 def after_webauthn_setup
14   super
15   send_webauthn_authenticator_added_email
16 end
allow_email_auth?() click to toggle source
Calls superclass method
    # File lib/rodauth/features/email_auth.rb
197 def allow_email_auth?
198   defined?(super) ? super : true
199 end
allow_resending_verify_account_email?() click to toggle source
    # File lib/rodauth/features/verify_account.rb
163 def allow_resending_verify_account_email?
164   account[account_status_column] == account_unverified_status_value
165 end
already_logged_in() click to toggle source
    # File lib/rodauth/features/base.rb
311 def already_logged_in
312   nil
313 end
argon2_hash_algorithm?(hash) click to toggle source

:nocov:

    # File lib/rodauth/features/argon2.rb
105 def argon2_hash_algorithm?(hash)
106   hash.start_with?('$argon2id$')
107 end
argon2_hash_cost() click to toggle source
   # File lib/rodauth/features/argon2.rb
76 def argon2_hash_cost
77   { t_cost: 1, m_cost: 5, p_cost: 1 }
78 end
argon2_password_hash_match?(hash, password) click to toggle source
    # File lib/rodauth/features/argon2.rb
109 def argon2_password_hash_match?(hash, password)
110   ret = ::Argon2::Password.verify_password(password, hash, argon2_secret)
111 
112   if ret == false && argon2_old_secret != argon2_secret && (ret = ::Argon2::Password.verify_password(password, hash, argon2_old_secret))
113     @update_password_hash = true
114   end
115 
116   ret
117 end
argon2_password_hash_using_salt_and_secret(password, salt, secret) click to toggle source
   # File lib/rodauth/features/argon2.rb
60 def argon2_password_hash_using_salt_and_secret(password, salt, secret)
61   argon2_params = Hash[extract_password_hash_cost(salt)]
62   argon2_params[argon2_salt_option] = salt.split('$').last.unpack("m")[0]
63   argon2_params[:secret] = secret
64   ::Argon2::Password.new(argon2_params).create(password)
65 end
argon2_salt_option() click to toggle source
   # File lib/rodauth/features/argon2.rb
34 def argon2_salt_option
35   :salt_do_not_supply
36 end
audit_log_ds() click to toggle source
   # File lib/rodauth/features/audit_logging.rb
83 def audit_log_ds
84   ds = db[audit_logging_table]
85   # :nocov:
86   if db.database_type == :postgres
87   # :nocov:
88     # For PostgreSQL, use RETURNING NULL. This allows the feature
89     # to be used with INSERT but not SELECT permissions on the
90     # table, useful for audit logging where the database user
91     # the application is running as should not need to read the
92     # logs.
93     ds = ds.returning(nil)
94   end
95   ds
96 end
audit_log_insert_hash(account_id, action) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
45 def audit_log_insert_hash(account_id, action)
46   if message = audit_log_message(action)
47     {
48       audit_logging_account_id_column => account_id,
49       audit_logging_message_column => message,
50       audit_logging_metadata_column => serialize_audit_log_metadata(audit_log_metadata(action))
51     }
52   end
53 end
audit_log_message(action) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
63 def audit_log_message(action)
64   meth = :"audit_log_message_for_#{action}"
65   if respond_to?(meth, true)
66     send(meth)
67   else
68     audit_log_message_default(action)
69   end
70 end
audit_log_message_default(action) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
59 def audit_log_message_default(action)
60   action.to_s
61 end
audit_log_metadata(action) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
72 def audit_log_metadata(action)
73   meth = :"audit_log_metadata_for_#{action}"
74   if respond_to?(meth, true)
75     send(meth)
76   else
77     audit_log_metadata_default
78   end
79 end
auth_class_eval(&block) click to toggle source
    # File lib/rodauth/features/base.rb
134 def auth_class_eval(&block)
135   auth.class_eval(&block)
136 end
authenticated?() click to toggle source
    # File lib/rodauth/features/base.rb
364 def authenticated?
365   logged_in?
366 end
authenticated_by() click to toggle source
    # File lib/rodauth/features/base.rb
467 def authenticated_by
468   session[authenticated_by_session_key]
469 end
authenticated_webauthn_id() click to toggle source
    # File lib/rodauth/features/webauthn.rb
251 def authenticated_webauthn_id
252   session[authenticated_webauthn_id_session_key]
253 end
auto_add_missing_recovery_codes() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
248 def auto_add_missing_recovery_codes
249   if auto_add_recovery_codes?
250     add_recovery_codes(recovery_codes_limit - recovery_codes.length)
251   end
252 end
auto_remove_recovery_codes() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
254 def auto_remove_recovery_codes
255   if auto_remove_recovery_codes? && (%w'totp webauthn sms_code' & possible_authentication_methods).empty?
256     recovery_codes_remove
257   end
258 end
autocomplete_for_field?(_param) click to toggle source
    # File lib/rodauth/features/base.rb
214 def autocomplete_for_field?(_param)
215   mark_input_fields_with_autocomplete?
216 end
autologin_session(autologin_type) click to toggle source
    # File lib/rodauth/features/base.rb
480 def autologin_session(autologin_type)
481   login_session('autologin')
482   set_session_value(autologin_type_session_key, autologin_type)
483 end
autologin_type() click to toggle source
    # File lib/rodauth/features/base.rb
476 def autologin_type
477   session[autologin_type_session_key]
478 end
base32_encode(data, length) click to toggle source
    # File lib/rodauth/features/otp.rb
412 def base32_encode(data, length)
413   chars = 'abcdefghijklmnopqrstuvwxyz234567'
414   length.times.map{|i|chars[data[i].ord % 32]}.join
415 end
base_url() click to toggle source
    # File lib/rodauth/features/base.rb
517 def base_url
518   url = String.new("#{request.scheme}://#{domain}")
519   url << ":#{request.port}" if request.port != Rack::Request::DEFAULT_PORTS[request.scheme]
520   url
521 end
before_change_login_route() click to toggle source
Calls superclass method
   # File lib/rodauth/features/verify_account_grace_period.rb
58 def before_change_login_route
59   unless verified_account?
60     set_redirect_error_flash unverified_change_login_error_flash
61     redirect unverified_change_login_redirect
62   end
63   super if defined?(super)
64 end
before_change_password_route() click to toggle source
Calls superclass method
   # File lib/rodauth/features/password_expiration.rb
90 def before_change_password_route
91   check_password_change_allowed
92   super
93 end
before_create_account_route() click to toggle source
Calls superclass method
   # File lib/rodauth/features/disallow_password_reuse.rb
77 def before_create_account_route
78   super if defined?(super)
79   @dont_check_previous_password = true
80 end
before_login_attempt() click to toggle source
Calls superclass method
    # File lib/rodauth/features/lockout.rb
244 def before_login_attempt
245   if locked_out?
246     show_lockout_page
247   end
248   super
249 end
before_logout() click to toggle source
Calls superclass method
    # File lib/rodauth/features/active_sessions.rb
146 def before_logout
147   if param_or_nil(global_logout_param)
148     remove_remember_key(session_value) if respond_to?(:remove_remember_key)
149     remove_all_active_sessions
150   else
151     remove_current_session
152   end
153   super
154 end
before_otp_setup_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
165 def before_otp_setup_route
166   super if defined?(super)
167   if use_json? && otp_keys_use_hmac? && !param_or_nil(otp_setup_raw_param)
168     _otp_tmp_key(otp_new_secret)
169     json_response[otp_setup_param] = otp_user_key
170     json_response[otp_setup_raw_param] = otp_key
171   end
172 end
before_reset_password() click to toggle source
Calls superclass method
   # File lib/rodauth/features/account_expiration.rb
79 def before_reset_password
80   check_account_expiration
81   super if defined?(super)
82 end
before_reset_password_request() click to toggle source
Calls superclass method
   # File lib/rodauth/features/account_expiration.rb
84 def before_reset_password_request
85   check_account_expiration
86   super if defined?(super)
87 end
before_rodauth() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
174 def before_rodauth
175   if json_request?
176     if json_check_accept? && (accept = request.env['HTTP_ACCEPT']) && accept !~ json_accept_regexp
177       response.status = 406
178       json_response[json_response_error_key] = json_not_accepted_error_message
179       _return_json_response
180     end
181 
182     unless request.post?
183       response.status = 405
184       response.headers['Allow'] = 'POST'
185       json_response[json_response_error_key] = json_non_post_error_message
186       return_json_response
187     end
188   elsif only_json?
189     response.status = json_response_error_status
190     return_response non_json_request_error_message
191   end
192 
193   super
194 end
before_two_factor_auth_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
111 def before_two_factor_auth_route
112   super if defined?(super)
113   if use_json?
114     json_response[:auth_links] = two_factor_auth_links.sort.map{|_,link| link}
115     json_response[json_response_success_key] ||= "" if include_success_messages?
116     return_json_response
117   end
118 end
before_two_factor_manage_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
101 def before_two_factor_manage_route
102   super if defined?(super)
103   if use_json?
104     json_response[:setup_links] = two_factor_setup_links.sort.map{|_,link| link}
105     json_response[:remove_links] = two_factor_remove_links.sort.map{|_,link| link}
106     json_response[json_response_success_key] ||= "" if include_success_messages?
107     return_json_response
108   end
109 end
before_unlock_account() click to toggle source
Calls superclass method
   # File lib/rodauth/features/account_expiration.rb
89 def before_unlock_account
90   check_account_expiration
91   super if defined?(super)
92 end
before_unlock_account_request() click to toggle source
Calls superclass method
   # File lib/rodauth/features/account_expiration.rb
94 def before_unlock_account_request
95   check_account_expiration
96   super if defined?(super)
97 end
before_verify_account() click to toggle source
Calls superclass method
   # File lib/rodauth/features/webauthn_verify_account.rb
30 def before_verify_account
31   super
32   if features.include?(:json) && use_json? && !param_or_nil(webauthn_setup_param)
33     cred = new_webauthn_credential
34     json_response[webauthn_setup_param] = cred.as_json
35     json_response[webauthn_setup_challenge_param] = cred.challenge
36     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
37   end
38   @webauthn_credential = webauthn_setup_credential_from_form_submission
39   add_webauthn_credential(@webauthn_credential)
40 end
before_verify_account_route() click to toggle source
Calls superclass method
   # File lib/rodauth/features/disallow_password_reuse.rb
82 def before_verify_account_route
83   super if defined?(super)
84   @dont_check_previous_password = true
85 end
before_view_recovery_codes() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
120 def before_view_recovery_codes
121   super if defined?(super)
122   if use_json?
123     json_response[:codes] = recovery_codes
124     json_response[json_response_success_key] ||= "" if include_success_messages?
125   end
126 end
before_webauthn_auth_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
138 def before_webauthn_auth_route
139   super if defined?(super)
140   if use_json? && !param_or_nil(webauthn_auth_param)
141     cred = webauthn_credential_options_for_get
142     json_response[webauthn_auth_param] = cred.as_json
143     json_response[webauthn_auth_challenge_param] = cred.challenge
144     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
145   end
146 end
before_webauthn_login_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
148 def before_webauthn_login_route
149   super if defined?(super)
150   if use_json? && !param_or_nil(webauthn_auth_param) && webauthn_login_options?
151     cred = webauthn_credential_options_for_get
152     json_response[webauthn_auth_param] = cred.as_json
153     json_response[webauthn_auth_challenge_param] = cred.challenge
154     json_response[webauthn_auth_challenge_hmac_param] = compute_hmac(cred.challenge)
155   end
156 end
before_webauthn_remove_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
158 def before_webauthn_remove_route
159   super if defined?(super)
160   if use_json? && !param_or_nil(webauthn_remove_param)
161     json_response[webauthn_remove_param] = account_webauthn_usage
162   end
163 end
before_webauthn_setup_route() click to toggle source
Calls superclass method
    # File lib/rodauth/features/json.rb
128 def before_webauthn_setup_route
129   super if defined?(super)
130   if use_json? && !param_or_nil(webauthn_setup_param)
131     cred = new_webauthn_credential
132     json_response[webauthn_setup_param] = cred.as_json
133     json_response[webauthn_setup_challenge_param] = cred.challenge
134     json_response[webauthn_setup_challenge_hmac_param] = compute_hmac(cred.challenge)
135   end
136 end
button(value, opts={}) click to toggle source
    # File lib/rodauth/features/base.rb
417 def button(value, opts={})
418   scope.render(button_opts(value, opts))
419 end
button_opts(value, opts) click to toggle source
    # File lib/rodauth/features/base.rb
409 def button_opts(value, opts)
410   opts = Hash[template_opts].merge!(opts)
411   opts[:locals] = {:value=>value, :opts=>opts}
412   opts[:cache] = cache_templates
413   opts[:cache_key] = :rodauth_button
414   _template_opts(opts, 'button')
415 end
can_add_recovery_codes?() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
173 def can_add_recovery_codes?
174   recovery_codes.length < recovery_codes_limit
175 end
catch_error(&block) click to toggle source
    # File lib/rodauth/features/base.rb
635 def catch_error(&block)
636   catch(:rodauth_error, &block)
637 end
change_login(login) click to toggle source
   # File lib/rodauth/features/change_login.rb
68 def change_login(login)
69   if account_ds.get(login_column).downcase == login.downcase
70     set_login_requirement_error_message(:same_as_current_login, same_as_current_login_message)
71     return false
72   end
73 
74   update_login(login)
75 end
change_login_notice_flash() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
136 def change_login_notice_flash
137   change_login_needs_verification_notice_flash
138 end
change_login_requires_password?() click to toggle source
   # File lib/rodauth/features/change_login.rb
64 def change_login_requires_password?
65   modifications_require_password?
66 end
change_password_requires_password?() click to toggle source
   # File lib/rodauth/features/change_password.rb
68 def change_password_requires_password?
69   modifications_require_password?
70 end
check_account_expiration() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
63 def check_account_expiration
64   if account_expired?
65     set_expired unless account_expired_at
66     set_redirect_error_flash account_expiration_error_flash
67     redirect account_expiration_redirect
68   end
69   update_last_login
70 end
check_active_session() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
54 def check_active_session
55   if logged_in? && !currently_active_session?
56     no_longer_active_session
57   end
58 end
check_already_logged_in() click to toggle source
    # File lib/rodauth/features/base.rb
307 def check_already_logged_in
308   already_logged_in if logged_in?
309 end
check_csrf() click to toggle source
    # File lib/rodauth/features/base.rb
393 def check_csrf
394   scope.check_csrf!(check_csrf_opts, &check_csrf_block)
395 end
check_csrf?() click to toggle source
    # File lib/rodauth/features/base.rb
697 def check_csrf?
698   scope.opts[:rodauth_route_csrf]
699 end
check_password_change_allowed() click to toggle source
   # File lib/rodauth/features/password_expiration.rb
30 def check_password_change_allowed
31   if password_changed_at = get_password_changed_at
32     if password_changed_at > Time.now - allow_password_change_after
33       set_redirect_error_flash password_not_changeable_yet_error_flash
34       redirect password_not_changeable_yet_redirect
35     end
36   end
37 end
check_session_expiration() click to toggle source
   # File lib/rodauth/features/session_expiration.rb
15 def check_session_expiration
16   return unless logged_in?
17 
18   unless session.has_key?(session_last_activity_session_key) && session.has_key?(session_created_session_key)
19     if session_expiration_default
20       expire_session
21     end
22 
23     return
24   end
25 
26   time = Time.now.to_i
27 
28   if session[session_last_activity_session_key] + session_inactivity_timeout < time
29     expire_session
30   end
31   set_session_value(session_last_activity_session_key, time)
32 
33   if session[session_created_session_key] + max_session_lifetime < time
34     expire_session
35   end
36 end
check_single_session() click to toggle source
   # File lib/rodauth/features/single_session.rb
52 def check_single_session
53   if logged_in? && !currently_active_session?
54     no_longer_active_session
55   end
56 end
clear_cached_otp() click to toggle source
    # File lib/rodauth/features/otp.rb
370 def clear_cached_otp
371   remove_instance_variable(:@otp) if defined?(@otp)
372 end
clear_invalid_login_attempts() click to toggle source
    # File lib/rodauth/features/lockout.rb
165 def clear_invalid_login_attempts
166   unlock_account
167 end
clear_session() click to toggle source
    # File lib/rodauth/features/base.rb
323 def clear_session
324   if scope.respond_to?(:clear_session)
325     scope.clear_session
326   else
327     session.clear
328   end
329 end
close_account() click to toggle source
   # File lib/rodauth/features/close_account.rb
66 def close_account
67   unless skip_status_checks?
68     update_account(account_status_column=>account_closed_status_value)
69   end
70 
71   unless account_password_hash_column
72     password_hash_ds.delete
73   end
74 end
close_account_requires_password?() click to toggle source
   # File lib/rodauth/features/close_account.rb
62 def close_account_requires_password?
63   modifications_require_password?
64 end
compute_hmac(data) click to toggle source

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

    # File lib/rodauth/features/base.rb
248 def compute_hmac(data)
249   _process_raw_hmac(compute_raw_hmac(data))
250 end
compute_hmacs(data) click to toggle source

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

    # File lib/rodauth/features/base.rb
259 def compute_hmacs(data)
260   hmacs = [compute_hmac(data)]
261 
262   if hmac_old_secret
263     hmacs << compute_old_hmac(data)
264   end
265 
266   hmacs
267 end
compute_old_hmac(data) click to toggle source

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

    # File lib/rodauth/features/base.rb
253 def compute_old_hmac(data)
254   _process_raw_hmac(compute_raw_hmac_with_secret(data, hmac_old_secret))
255 end
compute_raw_hmac(data) click to toggle source
    # File lib/rodauth/features/base.rb
758 def compute_raw_hmac(data)
759   raise ArgumentError, "hmac_secret not set" unless hmac_secret
760   compute_raw_hmac_with_secret(data, hmac_secret)
761 end
compute_raw_hmac_with_secret(data, secret) click to toggle source
    # File lib/rodauth/features/base.rb
763 def compute_raw_hmac_with_secret(data, secret)
764   OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, secret, data)
765 end
confirm_password() click to toggle source
   # File lib/rodauth/features/confirm_password.rb
63 def confirm_password
64   authenticated_by.delete('autologin')
65   authenticated_by.delete('remember')
66   authenticated_by.delete('email_auth')
67   authenticated_by.delete('password')
68   authenticated_by.unshift("password")
69   remove_session_value(autologin_type_session_key)
70   nil
71 end
confirm_password_redirect() click to toggle source
   # File lib/rodauth/features/confirm_password.rb
73 def confirm_password_redirect
74   remove_session_value(confirm_password_redirect_session_key) || default_redirect
75 end
convert_email_token_key(key) click to toggle source
   # File lib/rodauth/features/email_base.rb
61 def convert_email_token_key(key)
62   convert_token_key(key)
63 end
convert_session_key(key) click to toggle source
    # File lib/rodauth/features/base.rb
614 def convert_session_key(key)
615   key = :"#{session_key_prefix}#{key}" if session_key_prefix
616   normalize_session_or_flash_key(key)
617 end
convert_timestamp(timestamp) click to toggle source

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

    # File lib/rodauth/features/base.rb
803 def convert_timestamp(timestamp)
804   timestamp = db.to_application_timestamp(timestamp) if timestamp.is_a?(String)
805   timestamp
806 end
convert_token_id(id) click to toggle source
    # File lib/rodauth/features/base.rb
568 def convert_token_id(id)
569   if convert_token_id_to_integer?
570     convert_token_id_to_integer(id)
571   else
572     id
573   end
574 end
convert_token_id_to_integer(id) click to toggle source
    # File lib/rodauth/features/base.rb
576 def convert_token_id_to_integer(id)
577   if id = (Integer(id, 10) rescue nil)
578     if id > 9223372036854775807 || id < -9223372036854775808
579       # Only allow 64-bit signed integer range to avoid problems on PostgreSQL
580       id = nil
581     end
582   end
583 
584   id
585 end
convert_token_key(key) click to toggle source
    # File lib/rodauth/features/base.rb
556 def convert_token_key(key)
557   if key && hmac_secret
558     compute_hmac(key)
559   else
560     key
561   end
562 end
create_account_autologin?() click to toggle source
    # File lib/rodauth/features/verify_account.rb
216 def create_account_autologin?
217   false
218 end
create_account_notice_flash() click to toggle source
    # File lib/rodauth/features/verify_account.rb
183 def create_account_notice_flash
184   verify_account_email_sent_notice_flash
185 end
create_account_set_password?() click to toggle source
Calls superclass method
    # File lib/rodauth/features/verify_account.rb
220 def create_account_set_password?
221   return false if verify_account_set_password?
222   super
223 end
create_email(subject, body) click to toggle source
   # File lib/rodauth/features/email_base.rb
40 def create_email(subject, body)
41   create_email_to(email_to, subject, body)
42 end
create_email_auth_key() click to toggle source
    # File lib/rodauth/features/email_auth.rb
102 def create_email_auth_key
103   transaction do
104     if email_auth_key_value = get_email_auth_key(account_id)
105       set_email_auth_email_last_sent
106       @email_auth_key_value = email_auth_key_value
107     elsif e = raised_uniqueness_violation{email_auth_ds.insert(email_auth_key_insert_hash)}
108       # If inserting into the email auth table causes a violation, we can pull the
109       # existing email auth key from the table, or reraise.
110       raise e unless @email_auth_key_value = get_email_auth_key(account_id)
111     end
112   end
113 end
create_email_to(to, subject, body) click to toggle source
   # File lib/rodauth/features/email_base.rb
44 def create_email_to(to, subject, body)
45   m = Mail.new
46   m.from = email_from
47   m.to = to
48   m.subject = "#{email_subject_prefix}#{subject}"
49   m.body = body
50   m
51 end
create_reset_password_key() click to toggle source
    # File lib/rodauth/features/reset_password.rb
164 def create_reset_password_key
165   transaction do
166     if reset_password_key_value = get_password_reset_key(account_id)
167       set_reset_password_email_last_sent
168       @reset_password_key_value = reset_password_key_value
169     elsif e = raised_uniqueness_violation{password_reset_ds.insert(reset_password_key_insert_hash)}
170       # If inserting into the reset password table causes a violation, we can pull the
171       # existing reset password key from the table, or reraise.
172       raise e unless @reset_password_key_value = get_password_reset_key(account_id)
173     end
174   end
175 end
create_verify_account_key() click to toggle source
    # File lib/rodauth/features/verify_account.rb
281 def create_verify_account_key
282   ds = verify_account_ds
283   transaction do
284     if ds.empty?
285       if e = raised_uniqueness_violation{ds.insert(verify_account_key_insert_hash)}
286         # If inserting into the verify account table causes a violation, we can pull the
287         # key from the verify account table, or reraise.
288         raise e unless @verify_account_key_value = get_verify_account_key(account_id)
289       end
290     end
291   end
292 end
create_verify_login_change_email(login) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
198 def create_verify_login_change_email(login)
199   create_email_to(login, verify_login_change_email_subject, verify_login_change_email_body)
200 end
create_verify_login_change_key(login) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
176 def create_verify_login_change_key(login)
177   ds = verify_login_change_ds
178   transaction do
179     ds.where((Sequel::CURRENT_TIMESTAMP > verify_login_change_deadline_column) | ~Sequel.expr(verify_login_change_login_column=>login)).delete
180     if e = raised_uniqueness_violation{ds.insert(verify_login_change_key_insert_hash(login))}
181       old_login, key = get_verify_login_change_login_and_key(account_id)
182       # If inserting into the verify login change table causes a violation, we can pull the
183       # key from the verify login change table if the logins match, or reraise.
184       @verify_login_change_key_value = if old_login.downcase == login.downcase
185         key
186       end
187       raise e unless @verify_login_change_key_value
188     end
189   end
190 end
csrf_tag(path=request.path) click to toggle source
    # File lib/rodauth/features/base.rb
397 def csrf_tag(path=request.path)
398   return unless scope.respond_to?(:csrf_tag)
399 
400   if use_request_specific_csrf_tokens?
401     scope.csrf_tag(path)
402   else
403     # :nocov:
404     scope.csrf_tag
405     # :nocov:
406   end
407 end
currently_active_session?() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
40 def currently_active_session?
41   return false unless session_id = session[session_id_session_key]
42 
43   remove_inactive_sessions
44   ds = active_sessions_ds.
45     where(active_sessions_session_id_column => compute_hmacs(session_id))
46 
47   if update_current_session?
48     ds.update(active_sessions_update_hash) == 1
49   else
50     ds.count == 1
51   end
52 end
database_function_password_match?(name, hash_id, password, salt) click to toggle source
Calls superclass method
    # File lib/rodauth/features/argon2.rb
119 def database_function_password_match?(name, hash_id, password, salt)
120   return true if super
121 
122   if use_argon2? && argon2_hash_algorithm?(salt) && argon2_old_secret != argon2_secret && (ret = db.get(Sequel.function(function_name(name), hash_id, argon2_password_hash_using_salt_and_secret(password, salt, argon2_old_secret))))
123     @update_password_hash = true
124   end
125 
126   !!ret
127 end
db() click to toggle source
    # File lib/rodauth/features/base.rb
287 def db
288   Sequel::DATABASES.first or raise "Sequel database connection is missing"
289 end
delete_account() click to toggle source
   # File lib/rodauth/features/close_account.rb
76 def delete_account
77   account_ds.delete
78 end
delete_account_on_close?() click to toggle source
   # File lib/rodauth/features/close_account.rb
80 def delete_account_on_close?
81   skip_status_checks?
82 end
disable_remember_login() click to toggle source
    # File lib/rodauth/features/remember.rb
155 def disable_remember_login
156   remove_remember_key
157 end
domain() click to toggle source
    # File lib/rodauth/features/base.rb
523 def domain
524   request.host
525 end
email_auth_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/email_auth.rb
232 def email_auth_ds(id=account_id)
233   db[email_auth_table].where(email_auth_id_column=>id)
234 end
email_auth_email_recently_sent?() click to toggle source
    # File lib/rodauth/features/email_auth.rb
174 def email_auth_email_recently_sent?
175   (email_last_sent = get_email_auth_email_last_sent) && (Time.now - email_last_sent < email_auth_skip_resend_email_within)
176 end
email_auth_key_insert_hash() click to toggle source
    # File lib/rodauth/features/email_auth.rb
226 def email_auth_key_insert_hash
227   hash = {email_auth_id_column=>account_id, email_auth_key_column=>email_auth_key_value}
228   set_deadline_value(hash, email_auth_deadline_column, email_auth_deadline_interval)
229   hash
230 end
email_auth_request_form() click to toggle source
    # File lib/rodauth/features/email_auth.rb
145 def email_auth_request_form
146   render('email-auth-request-form')
147 end
email_from() click to toggle source
   # File lib/rodauth/features/email_base.rb
26 def email_from
27   "webmaster@#{domain}"
28 end
email_to() click to toggle source
   # File lib/rodauth/features/email_base.rb
30 def email_to
31   account[login_column]
32 end
expire_session() click to toggle source
   # File lib/rodauth/features/session_expiration.rb
38 def expire_session
39   clear_session
40   set_redirect_error_status session_expiration_error_status
41   set_error_reason :session_expired
42   set_redirect_error_flash session_expiration_error_flash
43   redirect session_expiration_redirect
44 end
extend_remember_deadline() click to toggle source
    # File lib/rodauth/features/remember.rb
206 def extend_remember_deadline
207   active_remember_key_ds.update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
208   remember_login
209 end
extend_remember_deadline_while_logged_in?() click to toggle source
    # File lib/rodauth/features/remember.rb
194 def extend_remember_deadline_while_logged_in?
195   return false unless extend_remember_deadline?
196 
197   if extended_at = session[remember_deadline_extended_session_key]
198     extended_at + extend_remember_deadline_period < Time.now.to_i
199   elsif logged_in_via_remember_key?
200     # Handle existing sessions before the change to extend remember deadline
201     # while logged in.
202     true
203   end
204 end
extract_password_hash_cost(hash) click to toggle source
Calls superclass method
   # File lib/rodauth/features/argon2.rb
68 def extract_password_hash_cost(hash)
69   return super unless argon2_hash_algorithm?(hash)
70 
71   /\A\$argon2id\$v=\d+\$m=(\d+),t=(\d+),p=(\d+)/ =~ hash
72   { t_cost: $2.to_i, m_cost: Math.log2($1.to_i).to_i, p_cost: $3.to_i }
73 end
features() click to toggle source
    # File lib/rodauth/features/base.rb
147 def features
148   self.class.features
149 end
field_attributes(field) click to toggle source
    # File lib/rodauth/features/base.rb
222 def field_attributes(field)
223   _field_attributes(field) || default_field_attributes
224 end
field_error(field) click to toggle source
    # File lib/rodauth/features/base.rb
179 def field_error(field)
180   return nil unless @field_errors
181   @field_errors[field]
182 end
field_error_attributes(field) click to toggle source
    # File lib/rodauth/features/base.rb
226 def field_error_attributes(field)
227   if field_error(field)
228     _field_error_attributes(field)
229   end
230 end
flash() click to toggle source
    # File lib/rodauth/features/base.rb
163 def flash
164   scope.flash
165 end
forget_login() click to toggle source
    # File lib/rodauth/features/remember.rb
138 def forget_login
139   opts = Hash[remember_cookie_options]
140   opts[:path] = "/" unless opts.key?(:path)
141   ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, opts)
142 end
formatted_field_error(field) click to toggle source
    # File lib/rodauth/features/base.rb
232 def formatted_field_error(field)
233   if error = field_error(field)
234     _formatted_field_error(field, error)
235   end
236 end
function_name(name) click to toggle source
    # File lib/rodauth/features/base.rb
701 def function_name(name)
702   if db.database_type == :mssql
703     # :nocov:
704     "dbo.#{name}"
705     # :nocov:
706   else
707     name
708   end
709 end
generate_active_sessions_key() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
158 def generate_active_sessions_key
159   @active_sessions_key = random_key
160 end
generate_email_auth_key_value() click to toggle source
    # File lib/rodauth/features/email_auth.rb
218 def generate_email_auth_key_value
219   @email_auth_key_value = random_key
220 end
generate_refresh_token() click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
185 def generate_refresh_token
186   hash = jwt_refresh_token_insert_hash
187   [account_id, jwt_refresh_token_ds.insert(hash), convert_token_key(hash[jwt_refresh_token_key_column])].join(token_separator)
188 end
generate_remember_key_value() click to toggle source
    # File lib/rodauth/features/remember.rb
247 def generate_remember_key_value
248   @remember_key_value = random_key
249 end
generate_reset_password_key_value() click to toggle source
    # File lib/rodauth/features/reset_password.rb
231 def generate_reset_password_key_value
232   @reset_password_key_value = random_key
233 end
generate_unlock_account_key() click to toggle source
    # File lib/rodauth/features/lockout.rb
266 def generate_unlock_account_key
267   random_key
268 end
generate_verify_account_key_value() click to toggle source
    # File lib/rodauth/features/verify_account.rb
277 def generate_verify_account_key_value
278   @verify_account_key_value = random_key
279 end
generate_verify_login_change_key_value() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
172 def generate_verify_login_change_key_value
173   @verify_login_change_key_value = random_key
174 end
get_active_refresh_token(account_id, token_id) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
158 def get_active_refresh_token(account_id, token_id)
159   jwt_refresh_token_account_ds(account_id).
160     where(Sequel::CURRENT_TIMESTAMP > jwt_refresh_token_deadline_column).
161     delete
162 
163   jwt_refresh_token_account_token_ds(account_id, token_id).
164     get(jwt_refresh_token_key_column)
165 end
get_activity_timestamp(account_id, column) click to toggle source
    # File lib/rodauth/features/account_expiration.rb
109 def get_activity_timestamp(account_id, column)
110   convert_timestamp(account_activity_ds(account_id).get(column))
111 end
get_email_auth_email_last_sent() click to toggle source
    # File lib/rodauth/features/email_auth.rb
119 def get_email_auth_email_last_sent
120   if column = email_auth_email_last_sent_column
121     if ts = email_auth_ds.get(column)
122       convert_timestamp(ts)
123     end
124   end
125 end
get_email_auth_key(id) click to toggle source
    # File lib/rodauth/features/email_auth.rb
139 def get_email_auth_key(id)
140   ds = email_auth_ds(id)
141   ds.where(Sequel::CURRENT_TIMESTAMP > email_auth_deadline_column).delete
142   ds.get(email_auth_key_column)
143 end
get_password_changed_at() click to toggle source
   # File lib/rodauth/features/password_expiration.rb
26 def get_password_changed_at
27   convert_timestamp(password_expiration_ds.get(password_expiration_changed_at_column))
28 end
get_password_hash() click to toggle source

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

    # File lib/rodauth/features/base.rb
723 def get_password_hash
724   if account_password_hash_column
725     account[account_password_hash_column] if account!
726   elsif use_database_authentication_functions?
727     db.get(Sequel.function(function_name(:rodauth_get_salt), account ? account_id : session_value))
728   else
729     # :nocov:
730     password_hash_ds.get(password_hash_column)
731     # :nocov:
732   end
733 end
get_password_reset_key(id) click to toggle source
    # File lib/rodauth/features/reset_password.rb
189 def get_password_reset_key(id)
190   ds = password_reset_ds(id)
191   ds.where(Sequel::CURRENT_TIMESTAMP > reset_password_deadline_column).delete
192   ds.get(reset_password_key_column)
193 end
get_remember_key() click to toggle source
    # File lib/rodauth/features/remember.rb
144 def get_remember_key
145   unless @remember_key_value = active_remember_key_ds.get(remember_key_column)
146    generate_remember_key_value
147    transaction do
148      remove_remember_key
149      add_remember_key
150    end
151   end
152   nil
153 end
get_reset_password_email_last_sent() click to toggle source
    # File lib/rodauth/features/reset_password.rb
199 def get_reset_password_email_last_sent
200   if column = reset_password_email_last_sent_column
201     if ts = password_reset_ds.get(column)
202       convert_timestamp(ts)
203     end
204   end
205 end
get_unlock_account_email_last_sent() click to toggle source
    # File lib/rodauth/features/lockout.rb
228 def get_unlock_account_email_last_sent
229   if column = account_lockouts_email_last_sent_column
230     if ts = account_lockouts_ds.get(column)
231       convert_timestamp(ts)
232     end
233   end
234 end
get_unlock_account_key() click to toggle source
    # File lib/rodauth/features/lockout.rb
216 def get_unlock_account_key
217   account_lockouts_ds.get(account_lockouts_key_column)
218 end
get_verify_account_email_last_sent() click to toggle source
    # File lib/rodauth/features/verify_account.rb
229 def get_verify_account_email_last_sent
230   if column = verify_account_email_last_sent_column
231     if ts = verify_account_ds.get(column)
232       convert_timestamp(ts)
233     end
234   end
235 end
get_verify_account_key(id) click to toggle source
    # File lib/rodauth/features/verify_account.rb
208 def get_verify_account_key(id)
209   verify_account_ds(id).get(verify_account_key_column)
210 end
get_verify_login_change_login_and_key(id) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
132 def get_verify_login_change_login_and_key(id)
133   verify_login_change_ds(id).get([verify_login_change_login_column, verify_login_change_key_column])
134 end
handle_duplicate_active_session_id(_e) click to toggle source
   # File lib/rodauth/features/active_sessions.rb
77 def handle_duplicate_active_session_id(_e)
78   # Do nothing by default as session is already tracked.  This will result in
79   # the current session and the existing session with the same id
80   # being tracked together, so that a logout of one will logout
81   # the other, and updating the last use on one will update the other,
82   # but this should be acceptable.  However, this can be overridden if different
83   # behavior is desired.
84 end
handle_webauthn_sign_count_verification_error() click to toggle source
    # File lib/rodauth/features/webauthn.rb
352 def handle_webauthn_sign_count_verification_error
353   throw_error_reason(:invalid_webauthn_sign_count, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_sign_count_message) 
354 end
has_password?() click to toggle source
    # File lib/rodauth/features/base.rb
711 def has_password?
712   return @has_password if defined?(@has_password)
713   return false unless account || session_value
714   @has_password = !!get_password_hash
715 end
hmac_secret_rotation?() click to toggle source
    # File lib/rodauth/features/base.rb
754 def hmac_secret_rotation?
755   hmac_secret && hmac_old_secret && hmac_secret != hmac_old_secret
756 end
hook_action(hook_type, action) click to toggle source
Calls superclass method
   # File lib/rodauth/features/audit_logging.rb
31 def hook_action(hook_type, action)
32   super
33   # In after_logout, session is already cleared, so use before_logout in that case
34   if (hook_type == :after || action == :logout) && (id = account ? account_id : session_value)
35     add_audit_log(id, action)
36   end
37 end
http_basic_auth() click to toggle source
   # File lib/rodauth/features/http_basic_auth.rb
34 def http_basic_auth
35   return @checked_http_basic_auth if defined?(@checked_http_basic_auth)
36 
37   @checked_http_basic_auth = nil
38   return unless token = ((v = request.env['HTTP_AUTHORIZATION']) && v[/\A *Basic (.*)\Z/, 1])
39 
40   username, password = token.unpack("m*").first.split(/:/, 2)
41   return unless username && password
42 
43   catch_error do
44     unless account_from_login(username)
45       throw_basic_auth_error(login_param, no_matching_login_message)
46     end
47 
48     before_login_attempt
49 
50     unless open_account?
51       throw_basic_auth_error(login_param, no_matching_login_message)
52     end
53 
54     unless password_match?(password)
55       after_login_failure
56       throw_basic_auth_error(password_param, invalid_password_message)
57     end
58 
59     transaction do
60       before_login
61       login_session('password')
62       after_login
63     end
64 
65     @checked_http_basic_auth = true
66     return true
67   end
68 
69   nil
70 end
ignore_uniqueness_violation(&block)

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

inactive_session_cond() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
188 def inactive_session_cond
189   cond = session_inactivity_deadline_condition
190   cond2 = session_lifetime_deadline_condition
191   return false unless cond || cond2
192   Sequel.|(*[cond, cond2].compact)
193 end
include_success_messages?() click to toggle source
    # File lib/rodauth/features/json.rb
211 def include_success_messages?
212   !json_response_success_key.nil?
213 end
input_field_string(param, id, opts={}) click to toggle source
    # File lib/rodauth/features/base.rb
190 def input_field_string(param, id, opts={})
191   type = opts.fetch(:type, "text")
192 
193   unless type == "password"
194     value = opts.fetch(:value){scope.h param(param)}
195   end
196 
197   field_class = opts.fetch(:class, "form-control")
198 
199   if autocomplete_for_field?(param) && opts[:autocomplete]
200     autocomplete = "autocomplete=\"#{opts[:autocomplete]}\""
201   end
202 
203   if inputmode_for_field?(param) && opts[:inputmode]
204     inputmode = "inputmode=\"#{opts[:inputmode]}\""
205   end
206 
207   if mark_input_fields_as_required? && opts[:required] != false
208     required = "required=\"required\""
209   end
210 
211   "<input #{opts[:attr]} #{autocomplete} #{inputmode} #{required} #{field_attributes(param)} #{field_error_attributes(param)} type=\"#{type}\" class=\"#{field_class}#{add_field_error_class(param)}\" name=\"#{param}\" id=\"#{id}\" value=\"#{value}\"/> #{formatted_field_error(param) unless opts[:skip_error_message]}"
212 end
inputmode_for_field?(_param) click to toggle source
    # File lib/rodauth/features/base.rb
218 def inputmode_for_field?(_param)
219   mark_input_fields_with_inputmode?
220 end
internal_request?() click to toggle source
    # File lib/rodauth/features/base.rb
868 def internal_request?
869   false
870 end
internal_request_configuration(&block) click to toggle source
    # File lib/rodauth/features/internal_request.rb
373 def internal_request_configuration(&block)
374   @auth.instance_exec do
375     (@internal_request_configuration_blocks ||= []) << block
376   end
377 end
invalid_login_attempted() click to toggle source
    # File lib/rodauth/features/lockout.rb
175 def invalid_login_attempted
176   ds = account_login_failures_ds.
177       where(account_login_failures_id_column=>account_id)
178 
179   number = if db.database_type == :postgres
180     ds.returning(account_login_failures_number_column).
181       with_sql(:update_sql, account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1).
182       single_value
183   else
184     # :nocov:
185     if ds.update(account_login_failures_number_column=>Sequel.expr(account_login_failures_number_column)+1) > 0
186       ds.get(account_login_failures_number_column)
187     end
188     # :nocov:
189   end
190 
191   unless number
192     # Ignoring the violation is safe here.  It may allow slightly more than max_invalid_logins invalid logins before
193     # lockout, but allowing a few extra is OK if the race is lost.
194     ignore_uniqueness_violation{account_login_failures_ds.insert(account_login_failures_id_column=>account_id)}
195     number = 1
196   end
197 
198   if number >= max_invalid_logins
199     @unlock_account_key_value = generate_unlock_account_key
200     hash = _setup_account_lockouts_hash(account_id, unlock_account_key_value)
201 
202     if e = raised_uniqueness_violation{account_lockouts_ds.insert(hash)}
203       # If inserting into the lockout table raises a violation, we should just be able to pull the already inserted
204       # key out of it.  If that doesn't return a valid key, we should reraise the error.
205       raise e unless @unlock_account_key_value = account_lockouts_ds.get(account_lockouts_key_column)
206 
207       after_account_lockout
208       show_lockout_page
209     else
210       after_account_lockout
211       e
212     end
213   end
214 end
invalid_previous_password_message() click to toggle source
   # File lib/rodauth/features/change_password.rb
72 def invalid_previous_password_message
73   invalid_password_message
74 end
json_request?() click to toggle source
   # File lib/rodauth/features/json.rb
55 def json_request?
56   return @json_request if defined?(@json_request)
57   @json_request = request.content_type =~ json_request_content_type_regexp
58 end
json_response() click to toggle source
    # File lib/rodauth/features/json.rb
219 def json_response
220   @json_response ||= {}
221 end
json_response_error?() click to toggle source
   # File lib/rodauth/features/json.rb
69 def json_response_error?
70   !!json_response[json_response_error_key]
71 end
jwt_cors_allow?() click to toggle source
   # File lib/rodauth/features/jwt_cors.rb
15 def jwt_cors_allow?
16   return false unless origin = request.env['HTTP_ORIGIN']
17 
18   case allowed = jwt_cors_allow_origin
19   when String
20     timing_safe_eql?(origin, allowed)
21   when Array
22     allowed.any?{|s| timing_safe_eql?(origin, s)}
23   when Regexp
24     allowed =~ origin
25   when true
26     true
27   else
28     false
29   end
30 end
jwt_payload() click to toggle source
    # File lib/rodauth/features/jwt.rb
130 def jwt_payload
131   return @jwt_payload if defined?(@jwt_payload)
132   @jwt_payload = JWT.decode(jwt_token, _jwt_decode_secrets, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
133 rescue JWT::DecodeError => e
134   rescue_jwt_payload(e)
135 end
jwt_refresh_token_account_ds(account_id) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
167 def jwt_refresh_token_account_ds(account_id)
168   jwt_refresh_token_ds.where(jwt_refresh_token_account_id_column => account_id)
169 end
jwt_refresh_token_account_token_ds(account_id, token_id) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
171 def jwt_refresh_token_account_token_ds(account_id, token_id)
172   jwt_refresh_token_account_ds(account_id).
173     where(jwt_refresh_token_id_column=>token_id)
174 end
jwt_refresh_token_ds() click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
176 def jwt_refresh_token_ds
177   db[jwt_refresh_token_table]
178 end
jwt_refresh_token_insert_hash() click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
190 def jwt_refresh_token_insert_hash
191   hash = {jwt_refresh_token_account_id_column => account_id, jwt_refresh_token_key_column => random_key}
192   set_deadline_value(hash, jwt_refresh_token_deadline_column, jwt_refresh_token_deadline_interval)
193   hash
194 end
jwt_refresh_token_match?(key) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
147 def jwt_refresh_token_match?(key)
148   # We don't need to match tokens if we are requiring a valid current access token
149   return true unless allow_refresh_with_expired_jwt_access_token?
150 
151   # If allowing with expired jwt access token, check the expired session contains
152   # hmac matching submitted and active refresh token.
153   s = session[jwt_refresh_token_hmac_session_key].to_s
154   h = session[jwt_refresh_token_data_session_key].to_s + key
155   timing_safe_eql?(compute_hmac(h), s) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(h), s))
156 end
jwt_secret() click to toggle source
   # File lib/rodauth/features/jwt.rb
69 def jwt_secret
70   raise ArgumentError, "jwt_secret not set"
71 end
jwt_session_hash() click to toggle source
   # File lib/rodauth/features/jwt.rb
73 def jwt_session_hash
74   jwt_session_key ? {jwt_session_key=>session} : session
75 end
jwt_token() click to toggle source
   # File lib/rodauth/features/jwt.rb
81 def jwt_token
82   return @jwt_token if defined?(@jwt_token)
83 
84   if (v = request.env['HTTP_AUTHORIZATION']) && v !~ jwt_authorization_ignore
85     @jwt_token = v.sub(jwt_authorization_remove, '')
86   end
87 end
last_account_activity_at() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
27 def last_account_activity_at
28   get_activity_timestamp(session_value, account_activity_last_activity_column)
29 end
last_account_login_at() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
31 def last_account_login_at
32   get_activity_timestamp(session_value, account_activity_last_login_column)
33 end
load_memory() click to toggle source
    # File lib/rodauth/features/remember.rb
114 def load_memory
115   if logged_in?
116     if extend_remember_deadline_while_logged_in?
117       if account_from_session
118         extend_remember_deadline
119       else
120         forget_login
121         clear_session
122       end
123     end
124   elsif account_from_remember_cookie
125     before_load_memory
126     login_session('remember')
127     extend_remember_deadline if extend_remember_deadline?
128     after_load_memory
129   end
130 end
loaded_templates() click to toggle source
    # File lib/rodauth/features/base.rb
808 def loaded_templates
809   []
810 end
locked_out?() click to toggle source
    # File lib/rodauth/features/lockout.rb
146 def locked_out?
147   if t = convert_timestamp(account_lockouts_ds.get(account_lockouts_deadline_column))
148     if Time.now < t
149       true
150     else
151       unlock_account
152       false
153     end
154   else
155     false
156   end
157 end
logged_in?()
Alias for: session_value
logged_in_via_remember_key?() click to toggle source
    # File lib/rodauth/features/remember.rb
174 def logged_in_via_remember_key?
175   authenticated_by.include?('remember')
176 end
login(auth_type) { || ... } click to toggle source
   # File lib/rodauth/features/login.rb
86 def login(auth_type)
87   @saved_login_redirect = remove_session_value(login_redirect_session_key)
88   transaction do
89     before_login
90     login_session(auth_type)
91     yield if block_given?
92     after_login
93   end
94   require_response(:_login_response)
95 end
login_confirm_label() click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
46 def login_confirm_label
47   "Confirm #{login_label}"
48 end
login_does_not_meet_requirements_message() click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
108 def login_does_not_meet_requirements_message
109   "invalid login#{", #{login_requirement_message}" if login_requirement_message}"
110 end
login_failed_reset_password_request_form() click to toggle source
    # File lib/rodauth/features/reset_password.rb
235 def login_failed_reset_password_request_form
236   render("reset-password-request")
237 end
login_field_autocomplete_value() click to toggle source
    # File lib/rodauth/features/base.rb
291 def login_field_autocomplete_value
292   login_uses_email? ? "email" : "on"
293 end
login_hidden_field() click to toggle source
    # File lib/rodauth/features/login.rb
129 def login_hidden_field
130   "<input type='hidden' name=\"#{login_param}\" value=\"#{scope.h param(login_param)}\" />"
131 end
login_input_type() click to toggle source
    # File lib/rodauth/features/base.rb
315 def login_input_type
316   login_uses_email? ? 'email' : 'text'
317 end
login_meets_email_requirements?(login) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
144 def login_meets_email_requirements?(login)
145   return true unless require_email_address_logins?
146   return true if login_valid_email?(login)
147   set_login_requirement_error_message(:login_not_valid_email, login_not_valid_email_message)
148   return false
149 end
login_meets_length_requirements?(login) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
129 def login_meets_length_requirements?(login)
130   if login_minimum_length > login.length
131     set_login_requirement_error_message(:login_too_short, login_too_short_message)
132     false
133   elsif login_maximum_length < login.length
134     set_login_requirement_error_message(:login_too_long, login_too_long_message)
135     false
136   elsif login_maximum_bytes < login.bytesize
137     set_login_requirement_error_message(:login_too_many_bytes, login_too_many_bytes_message)
138     false
139   else
140     true
141   end
142 end
login_meets_requirements?(login) click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
54 def login_meets_requirements?(login)
55   login_meets_length_requirements?(login) && \
56     login_meets_email_requirements?(login)
57 end
login_required() click to toggle source
    # File lib/rodauth/features/base.rb
331 def login_required
332   set_redirect_error_status(login_required_error_status)
333   set_error_reason :login_required
334   set_redirect_error_flash require_login_error_flash
335   redirect require_login_redirect
336 end
login_return_to_requested_location_path() click to toggle source
    # File lib/rodauth/features/login.rb
104 def login_return_to_requested_location_path
105   request.fullpath if request.get?
106 end
login_session(auth_type) click to toggle source
    # File lib/rodauth/features/base.rb
471 def login_session(auth_type)
472   update_session
473   set_session_value(authenticated_by_session_key, [auth_type])
474 end
login_too_long_message() click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
112 def login_too_long_message
113   "maximum #{login_maximum_length} characters"
114 end
login_too_many_bytes_message() click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
116 def login_too_many_bytes_message
117   "maximum #{login_maximum_bytes} bytes"
118 end
login_too_short_message() click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
120 def login_too_short_message
121   "minimum #{login_minimum_length} characters"
122 end
login_uses_email?() click to toggle source
    # File lib/rodauth/features/base.rb
319 def login_uses_email?
320   login_column == :email
321 end
login_valid_email?(login) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
151 def login_valid_email?(login)
152   login =~ login_email_regexp
153 end
logout() click to toggle source
   # File lib/rodauth/features/logout.rb
34 def logout
35   clear_session
36 end
logout_additional_form_tags() click to toggle source
Calls superclass method
    # File lib/rodauth/features/active_sessions.rb
118 def logout_additional_form_tags
119   super.to_s + render('global-logout-field')
120 end
modifications_require_password?() click to toggle source
    # File lib/rodauth/features/base.rb
527 def modifications_require_password?
528   has_password?
529 end
new_account(login) click to toggle source
   # File lib/rodauth/features/create_account.rb
96 def new_account(login)
97   @account = _new_account(login)
98 end
new_recovery_code() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
240 def new_recovery_code
241   random_key
242 end
new_webauthn_credential() click to toggle source
    # File lib/rodauth/features/webauthn.rb
302 def new_webauthn_credential
303   WebAuthn::Credential.options_for_create(
304     :timeout => webauthn_setup_timeout,
305     :user => {:id=>account_webauthn_user_id, :name=>webauthn_user_name},
306     :authenticator_selection => webauthn_authenticator_selection,
307     :attestation => webauthn_attestation,
308     :extensions => webauthn_extensions,
309     :exclude => account_webauthn_ids,
310     **webauthn_create_relying_party_opts
311   )
312 end
no_longer_active_session() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
60 def no_longer_active_session
61   clear_session
62   set_redirect_error_status inactive_session_error_status
63   set_error_reason :inactive_session
64   set_redirect_error_flash active_sessions_error_flash
65   redirect active_sessions_redirect
66 end
normalize_session_or_flash_key(key) click to toggle source
    # File lib/rodauth/features/base.rb
619 def normalize_session_or_flash_key(key)
620   scope.opts[:sessions_convert_symbols] ? key.to_s : key
621 end
null_byte_parameter_value(key, value) click to toggle source

Return nil by default for values with null bytes

    # File lib/rodauth/features/base.rb
509 def null_byte_parameter_value(key, value)
510   nil
511 end
only_json?() click to toggle source
    # File lib/rodauth/features/base.rb
430 def only_json?
431   scope.class.opts[:rodauth_json] == :only
432 end
open_account?() click to toggle source
    # File lib/rodauth/features/base.rb
283 def open_account?
284   skip_status_checks? || account[account_status_column] == account_open_status_value 
285 end
otp_add_key() click to toggle source
Calls superclass method
    # File lib/rodauth/features/otp.rb
283 def otp_add_key
284   _otp_add_key(otp_key)
285   super if defined?(super)
286 end
otp_available?() click to toggle source
    # File lib/rodauth/features/otp.rb
243 def otp_available?
244   otp_exists? && !otp_locked_out?
245 end
otp_exists?() click to toggle source
    # File lib/rodauth/features/otp.rb
247 def otp_exists?
248   !otp_key.nil?
249 end
otp_hmac_old_secret(key) click to toggle source
    # File lib/rodauth/features/otp.rb
383 def otp_hmac_old_secret(key)
384   base32_encode(compute_raw_hmac_with_secret(ROTP::Base32.decode(key), hmac_old_secret), key.bytesize)
385 end
otp_hmac_secret(key) click to toggle source
    # File lib/rodauth/features/otp.rb
379 def otp_hmac_secret(key)
380   base32_encode(compute_raw_hmac(ROTP::Base32.decode(key)), key.bytesize)
381 end
otp_issuer() click to toggle source
    # File lib/rodauth/features/otp.rb
314 def otp_issuer
315   domain
316 end
otp_key_ds() click to toggle source
    # File lib/rodauth/features/otp.rb
450 def otp_key_ds
451   db[otp_keys_table].where(otp_keys_id_column=>session_value)
452 end
otp_keys_use_hmac?() click to toggle source
    # File lib/rodauth/features/otp.rb
335 def otp_keys_use_hmac?
336   !!hmac_secret
337 end
otp_last_use() click to toggle source
    # File lib/rodauth/features/otp.rb
294 def otp_last_use
295   convert_timestamp(otp_key_ds.get(otp_keys_last_use_column))
296 end
otp_locked_out?() click to toggle source
    # File lib/rodauth/features/otp.rb
306 def otp_locked_out?
307   otp_key_ds.get(otp_keys_failures_column) >= otp_auth_failures_limit
308 end
otp_lockout_redirect() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
207 def otp_lockout_redirect
208   otp_unlock_path
209 end
otp_new_secret() click to toggle source
    # File lib/rodauth/features/otp.rb
401 def otp_new_secret
402   ROTP::Base32.random_base32.downcase
403 end
otp_provisioning_name() click to toggle source
    # File lib/rodauth/features/otp.rb
318 def otp_provisioning_name
319   account[login_column]
320 end
otp_provisioning_uri() click to toggle source
    # File lib/rodauth/features/otp.rb
310 def otp_provisioning_uri
311   otp.provisioning_uri(otp_provisioning_name)
312 end
otp_qr_code() click to toggle source
    # File lib/rodauth/features/otp.rb
322 def otp_qr_code
323   svg = RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true, :use_path=>true, :fill=>"fff")
324   svg.sub(/\A<\?xml version="1\.0" standalone="yes"\?>/, '')
325 end
otp_record_authentication_failure() click to toggle source
    # File lib/rodauth/features/otp.rb
298 def otp_record_authentication_failure
299   otp_key_ds.update(otp_keys_failures_column=>Sequel.identifier(otp_keys_failures_column) + 1)
300 end
otp_remove() click to toggle source
    # File lib/rodauth/features/otp.rb
278 def otp_remove
279   otp_key_ds.delete
280   @otp_key = nil
281 end
otp_remove_auth_failures() click to toggle source
    # File lib/rodauth/features/otp.rb
302 def otp_remove_auth_failures
303   otp_key_ds.update(otp_keys_failures_column=>0)
304 end
otp_tmp_key(secret) click to toggle source
    # File lib/rodauth/features/otp.rb
374 def otp_tmp_key(secret)
375   _otp_tmp_key(secret)
376   clear_cached_otp
377 end
otp_unlock_auth_failure() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
143 def otp_unlock_auth_failure
144   h = {
145     otp_unlock_num_successes_column=>0,
146     otp_unlock_next_auth_attempt_after_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, :seconds=>otp_unlock_auth_failure_cooldown_seconds)
147   }
148 
149   if otp_unlock_ds.update(h) == 0
150     h[otp_unlock_id_column] = session_value
151 
152     # If row already exists when inserting, no need to do anything
153     raises_uniqueness_violation?{otp_unlock_ds.insert(h)}
154   end
155 end
otp_unlock_auth_success() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
157 def otp_unlock_auth_success
158   deadline = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, :seconds=>otp_unlock_success_cooldown_seconds)
159 
160   # Add WHERE to avoid possible race condition when multiple unlock auth requests
161   # are sent at the same time (only the first should increment num successes).
162   if otp_unlock_ds.
163       where(Sequel[otp_unlock_next_auth_attempt_after_column] < Sequel::CURRENT_TIMESTAMP).
164       update(
165         otp_unlock_num_successes_column=>Sequel[otp_unlock_num_successes_column]+1,
166         otp_unlock_next_auth_attempt_after_column=>deadline
167       ) == 0
168 
169     # Ignore uniqueness errors when inserting after a failed update,
170     # which could be caused due to the race condition mentioned above.
171     raises_uniqueness_violation? do
172       otp_unlock_ds.insert(
173         otp_unlock_id_column=>session_value,
174         otp_unlock_next_auth_attempt_after_column=>deadline
175       )
176     end
177   end
178 
179   @otp_unlock_data = nil
180   # :nocov:
181   if otp_unlock_data
182   # :nocov:
183     if otp_unlock_num_successes >= otp_unlock_auths_required
184       # At least the requisite number of consecutive successful unlock
185       # authentications. Unlock OTP authentication.
186       otp_key_ds.update(otp_keys_failures_column => 0)
187 
188       # Remove OTP unlock metadata when unlocking OTP authentication
189       otp_unlock_reset
190     # else
191     #  # Still need additional consecutive successful unlock attempts.
192     end
193   # else
194   #  # if row isn't available, probably the process was reset during this,
195   #  # and it's safe to do nothing in that case.
196   end
197 end
otp_unlock_available?() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
113 def otp_unlock_available?
114   if otp_unlock_data
115     next_auth_attempt_after = otp_unlock_next_auth_attempt_after
116     current_timestamp = Time.now
117 
118     if (next_auth_attempt_after < current_timestamp - otp_unlock_deadline_seconds)
119       # Unlock process not fully completed within deadline, reset process
120       otp_unlock_reset
121       true
122     else
123       if next_auth_attempt_after > current_timestamp
124         # If next auth attempt after timestamp is in the future, that means the next
125         # unlock attempt cannot happen until then.
126         false 
127       else
128         if otp_unlock_num_successes == 0
129           # 0 value indicates previous attempt was a failure. Since failure cooldown
130           # period has passed, reset process so user gets full deadline period
131           otp_unlock_reset
132         end
133         true
134       end
135     end
136   else
137     # No row means no unlock attempts yet (or previous attempt was more than the
138     # deadline account, so unlocking is available
139     true
140   end
141 end
otp_unlock_data() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
233 def otp_unlock_data
234   @otp_unlock_data ||= otp_unlock_ds.first
235 end
otp_unlock_deadline() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
219 def otp_unlock_deadline
220   otp_unlock_next_auth_attempt_after + otp_unlock_deadline_seconds
221 end
otp_unlock_deadline_passed?() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
199 def otp_unlock_deadline_passed?
200   otp_unlock_data ? (otp_unlock_next_auth_attempt_after < Time.now - otp_unlock_deadline_seconds) : false
201 end
otp_unlock_ds() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
246 def otp_unlock_ds
247   db[otp_unlock_table].where(otp_unlock_id_column=>session_value)
248 end
otp_unlock_next_auth_attempt_after() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
211 def otp_unlock_next_auth_attempt_after
212   if otp_unlock_data
213     convert_timestamp(otp_unlock_data[otp_unlock_next_auth_attempt_after_column])
214   else
215     Time.now
216   end
217 end
otp_unlock_num_successes() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
223 def otp_unlock_num_successes
224   otp_unlock_data ? otp_unlock_data[otp_unlock_num_successes_column] : 0
225 end
otp_unlock_refresh_tag() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
203 def otp_unlock_refresh_tag
204   "<meta http-equiv=\"refresh\" content=\"#{(otp_unlock_next_auth_attempt_after - Time.now).to_i + 1}\">"
205 end
otp_unlock_reset() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
241 def otp_unlock_reset
242   otp_unlock_ds.delete
243   @otp_unlock_data = nil
244 end
otp_unlock_success_cooldown_seconds() click to toggle source
    # File lib/rodauth/features/otp_unlock.rb
237 def otp_unlock_success_cooldown_seconds
238   (_otp_interval+(otp_drift||0))*2
239 end
otp_update_last_use() click to toggle source
    # File lib/rodauth/features/otp.rb
288 def otp_update_last_use
289   otp_key_ds.
290     where(Sequel.date_add(otp_keys_last_use_column, :seconds=>_otp_interval) < Sequel::CURRENT_TIMESTAMP).
291     update(otp_keys_last_use_column=>Sequel::CURRENT_TIMESTAMP) == 1
292 end
otp_user_key() click to toggle source
    # File lib/rodauth/features/otp.rb
327 def otp_user_key
328   @otp_user_key ||= if otp_keys_use_hmac?
329     otp_hmac_secret(otp_key)
330   else
331     otp_key
332   end
333 end
otp_valid_code?(ot_pass) click to toggle source
    # File lib/rodauth/features/otp.rb
251 def otp_valid_code?(ot_pass)
252   if _otp_valid_code?(ot_pass, otp)
253     true
254   elsif hmac_secret_rotation? && _otp_valid_code?(ot_pass, _otp_for_key(otp_hmac_old_secret(otp_key)))
255     _otp_valid_code_for_old_secret
256     true
257   else
258     false
259   end
260 end
otp_valid_key?(secret) click to toggle source
    # File lib/rodauth/features/otp.rb
387 def otp_valid_key?(secret)
388   return false unless secret =~ /\A([a-z2-7]{16}|[a-z2-7]{32})\z/
389   if otp_keys_use_hmac?
390     # Purposely do not allow creating new OTPs with old secrets,
391     # since OTP rotation is difficult.  The user will get shown
392     # the same page with an updated secret, which they can submit
393     # to setup OTP.
394     timing_safe_eql?(otp_hmac_secret(param(otp_setup_raw_param)), secret)
395   else
396     true
397   end
398 end
over_max_bytesize_param_value(key, value) click to toggle source

Return nil by default for values over maximum bytesize.

    # File lib/rodauth/features/base.rb
504 def over_max_bytesize_param_value(key, value)
505   nil
506 end
param(key) click to toggle source

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

    # File lib/rodauth/features/base.rb
487 def param(key)
488   param_or_nil(key).to_s
489 end
param_or_nil(key) click to toggle source

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

    # File lib/rodauth/features/base.rb
493 def param_or_nil(key)
494   value = raw_param(key)
495   unless value.nil?
496     value = value.to_s
497     value = over_max_bytesize_param_value(key, value) if max_param_bytesize && value.bytesize > max_param_bytesize
498     value = null_byte_parameter_value(key, value) if value && value.include?("\0")
499   end
500   value
501 end
password_confirm_label() click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
50 def password_confirm_label
51   "Confirm #{password_label}"
52 end
password_does_not_contain_null_byte?(password) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
170 def password_does_not_contain_null_byte?(password)
171   return true unless password.include?("\0")
172   set_password_requirement_error_message(:password_contains_null_byte, contains_null_byte_message)
173   false
174 end
password_does_not_meet_requirements_message() click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
87 def password_does_not_meet_requirements_message
88   "invalid password, does not meet requirements#{" (#{password_requirement_message})" if password_requirement_message}"
89 end
password_doesnt_match_previous_password?(password) click to toggle source
   # File lib/rodauth/features/disallow_password_reuse.rb
50 def password_doesnt_match_previous_password?(password)
51   match = if use_database_authentication_functions?
52     salts = previous_password_ds.
53       select_map([previous_password_id_column, Sequel.function(function_name(:rodauth_get_previous_salt), previous_password_id_column).as(:salt)])
54     return true if salts.empty?
55 
56     salts.any? do |hash_id, salt|
57       database_function_password_match?(:rodauth_previous_password_hash_match, hash_id, password, salt)
58     end
59   else
60     # :nocov:
61     previous_password_ds.select_map(previous_password_hash_column).any? do |hash|
62       password_hash_match?(hash, password)
63     end
64     # :nocov:
65   end
66 
67   return true unless match
68   set_password_requirement_error_message(:password_same_as_previous_password, password_same_as_previous_password_message)
69   false
70 end
password_expiration_ds() click to toggle source
    # File lib/rodauth/features/password_expiration.rb
107 def password_expiration_ds
108   db[password_expiration_table].where(password_expiration_id_column=>account_id)
109 end
password_expired?() click to toggle source
   # File lib/rodauth/features/password_expiration.rb
68 def password_expired?
69   if password_changed_at = session[password_changed_at_session_key]
70     return password_changed_at + require_password_change_after < Time.now.to_i
71   end
72 
73   account_from_session
74   if password_changed_at = get_password_changed_at
75     set_session_value(password_changed_at_session_key, password_changed_at.to_i)
76     password_changed_at + require_password_change_after < Time.now
77   else
78     set_session_value(password_changed_at_session_key, password_expiration_default ? 0 : 2147483647)
79     password_expiration_default
80   end
81 end
password_field_autocomplete_value() click to toggle source
    # File lib/rodauth/features/base.rb
295 def password_field_autocomplete_value
296   @password_field_autocomplete_value || 'current-password'
297 end
password_has_enough_character_groups?(password) click to toggle source
   # File lib/rodauth/features/password_complexity.rb
54 def password_has_enough_character_groups?(password)
55   return true if password.length > password_max_length_for_groups_check
56   return true if password_character_groups.select{|re| password =~ re}.length >= password_min_groups
57   set_password_requirement_error_message(:not_enough_character_groups_in_password, password_not_enough_character_groups_message)
58   false
59 end
password_has_no_invalid_pattern?(password) click to toggle source
   # File lib/rodauth/features/password_complexity.rb
61 def password_has_no_invalid_pattern?(password)
62   return true unless password_invalid_pattern
63   return true if password !~ password_invalid_pattern
64   set_password_requirement_error_message(:invalid_password_pattern, password_invalid_pattern_message)
65   false
66 end
password_hash(password) click to toggle source
Calls superclass method
   # File lib/rodauth/features/argon2.rb
19 def password_hash(password)
20   return super unless use_argon2?
21 
22   if secret = argon2_secret
23     argon2_params = Hash[password_hash_cost]
24     argon2_params[:secret] = secret
25   else
26     argon2_params = password_hash_cost
27   end
28   ::Argon2::Password.new(argon2_params).create(password)
29 end
password_hash_cost() click to toggle source
Calls superclass method
   # File lib/rodauth/features/argon2.rb
45 def password_hash_cost
46   return super unless use_argon2?
47   argon2_hash_cost
48 end
password_hash_ds() click to toggle source
    # File lib/rodauth/features/base.rb
798 def password_hash_ds
799   db[password_hash_table].where(password_hash_id_column=>account ? account_id : session_value)
800 end
password_hash_match?(hash, password) click to toggle source
Calls superclass method
   # File lib/rodauth/features/argon2.rb
50 def password_hash_match?(hash, password)
51   return super unless argon2_hash_algorithm?(hash)
52   argon2_password_hash_match?(hash, password)
53 end
password_hash_using_salt(password, salt) click to toggle source
Calls superclass method
   # File lib/rodauth/features/argon2.rb
55 def password_hash_using_salt(password, salt)
56   return super unless argon2_hash_algorithm?(salt)
57   argon2_password_hash_using_salt_and_secret(password, salt, argon2_secret)
58 end
password_match?(password) click to toggle source
    # File lib/rodauth/features/base.rb
452 def password_match?(password)
453   if hash = get_password_hash
454     if account_password_hash_column || !use_database_authentication_functions?
455       password_hash_match?(hash, password)
456     else
457       database_function_password_match?(:rodauth_valid_password_hash, account_id, password, hash)
458     end 
459   end
460 end
password_meets_length_requirements?(password) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
155 def password_meets_length_requirements?(password)
156   if password_minimum_length > password.length
157     set_password_requirement_error_message(:password_too_short, password_too_short_message)
158     false
159   elsif password_maximum_length && password_maximum_length < password.length
160     set_password_requirement_error_message(:password_too_long, password_too_long_message)
161     false
162   elsif password_maximum_bytes && password_maximum_bytes < password.bytesize
163     set_password_requirement_error_message(:password_too_many_bytes, password_too_many_bytes_message)
164     false
165   else
166     true
167   end
168 end
password_meets_requirements?(password) click to toggle source
Calls superclass method
   # File lib/rodauth/features/disallow_common_passwords.rb
13 def password_meets_requirements?(password)
14   super && password_not_one_of_the_most_common?(password)
15 end
password_not_in_dictionary?(password) click to toggle source
   # File lib/rodauth/features/password_complexity.rb
75 def password_not_in_dictionary?(password)
76   return true unless dict = password_dictionary
77   return true unless password =~ /\A(?:\d*)([A-Za-z!@$+|][A-Za-z!@$+|0134578]+[A-Za-z!@$+|])(?:\d*)\z/
78   word = $1.downcase.tr('!@$+|0134578', 'iastloleastb')
79   return true if !dict.include?(word)
80   set_password_requirement_error_message(:password_in_dictionary, password_in_dictionary_message)
81   false
82 end
password_not_one_of_the_most_common?(password) click to toggle source
   # File lib/rodauth/features/disallow_common_passwords.rb
33 def password_not_one_of_the_most_common?(password)
34   return true unless password_one_of_most_common?(password)
35   set_password_requirement_error_message(:password_is_one_of_the_most_common, password_is_one_of_the_most_common_message)
36   false
37 end
password_not_too_many_repeating_characters?(password) click to toggle source
   # File lib/rodauth/features/password_complexity.rb
68 def password_not_too_many_repeating_characters?(password)
69   return true if password_max_repeating_characters < 2
70   return true if password !~ /(.)(\1){#{password_max_repeating_characters-1}}/ 
71   set_password_requirement_error_message(:too_many_repeating_characters_in_password, password_too_many_repeating_characters_message)
72   false
73 end
password_one_of_most_common?(password) click to toggle source
   # File lib/rodauth/features/disallow_common_passwords.rb
27 def password_one_of_most_common?(password)
28   most_common_passwords.include?(password)
29 end
password_recently_entered?() click to toggle source
   # File lib/rodauth/features/password_grace_period.rb
22 def password_recently_entered?
23   return false unless last_password_entry = session[last_password_entry_session_key]
24   last_password_entry + password_grace_period > Time.now.to_i
25 end
password_reset_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/reset_password.rb
249 def password_reset_ds(id=account_id)
250   db[reset_password_table].where(reset_password_id_column=>id)
251 end
password_too_long_message() click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
91 def password_too_long_message
92   "maximum #{password_maximum_length} characters"
93 end
password_too_many_bytes_message() click to toggle source
   # File lib/rodauth/features/login_password_requirements_base.rb
95 def password_too_many_bytes_message
96   "maximum #{password_maximum_bytes} bytes"
97 end
password_too_short_message() click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
 99 def password_too_short_message
100   "minimum #{password_minimum_length} characters"
101 end
possible_authentication_methods() click to toggle source
    # File lib/rodauth/features/base.rb
531 def possible_authentication_methods
532   has_password? ? ['password'] : []
533 end
post_configure() click to toggle source
    # File lib/rodauth/features/base.rb
434 def post_configure
435   require 'bcrypt' if require_bcrypt?
436   db.extension :date_arithmetic if use_date_arithmetic?
437 
438   if method(:convert_token_id_to_integer?).owner == Rodauth::Base && (db rescue false) && db.table_exists?(accounts_table) && db.schema(accounts_table).find{|col, v| break v[:type] == :integer if col == account_id_column}
439     self.class.send(:define_method, :convert_token_id_to_integer?){true}
440   end
441 
442   route_hash= {}
443   self.class.routes.each do |meth|
444     route_meth = "#{meth.to_s.sub(/\Ahandle_/, '')}_route"
445     if route = send(route_meth)
446       route_hash["/#{route}"] = meth
447     end
448   end
449   self.class.route_hash = route_hash.freeze
450 end
previous_password_ds() click to toggle source
   # File lib/rodauth/features/disallow_password_reuse.rb
94 def previous_password_ds
95   db[previous_password_hash_table].where(previous_password_account_id_column=>account_id)
96 end
raised_uniqueness_violation(&block)

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

raises_uniqueness_violation?(&block) click to toggle source

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.

    # File lib/rodauth/features/base.rb
827 def raises_uniqueness_violation?(&block)
828   transaction(:savepoint=>:only, &block)
829   false
830 rescue unique_constraint_violation_class => e
831   e
832 end
random_key() click to toggle source
    # File lib/rodauth/features/base.rb
610 def random_key
611   SecureRandom.urlsafe_base64(32)
612 end
raw_param(key) click to toggle source
    # File lib/rodauth/features/base.rb
513 def raw_param(key)
514   request.params[key]
515 end
recovery_code_match?(code) click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
160 def recovery_code_match?(code)
161   recovery_codes.each do |s|
162     if timing_safe_eql?(code, s)
163       recovery_codes_ds.where(recovery_codes_column=>code).delete
164       if recovery_codes_primary?
165         add_recovery_code
166       end
167       return true
168     end
169   end
170   false
171 end
recovery_codes_available?() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
196 def recovery_codes_available?
197   !recovery_codes_ds.empty?
198 end
recovery_codes_ds() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
264 def recovery_codes_ds
265   db[recovery_codes_table].where(recovery_codes_id_column=>session_value)
266 end
recovery_codes_primary?() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
244 def recovery_codes_primary?
245   (features & [:otp, :sms_codes, :webauthn]).empty?
246 end
recovery_codes_remove() click to toggle source
    # File lib/rodauth/features/recovery_codes.rb
156 def recovery_codes_remove
157   recovery_codes_ds.delete
158 end
redirect(path) click to toggle source
    # File lib/rodauth/features/base.rb
587 def redirect(path)
588   request.redirect(path)
589 end
remember_key_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/remember.rb
255 def remember_key_ds(id=account_id)
256   db[remember_table].where(remember_id_column=>id)
257 end
remember_login() click to toggle source
    # File lib/rodauth/features/remember.rb
132 def remember_login
133   get_remember_key
134   set_remember_cookie
135   set_session_value(remember_deadline_extended_session_key, Time.now.to_i) if extend_remember_deadline?
136 end
remembered_session_id() click to toggle source
    # File lib/rodauth/features/remember.rb
 91 def remembered_session_id
 92   return unless cookie = _get_remember_cookie
 93   id, key = cookie.split('_', 2)
 94   return unless id && key
 95 
 96   actual, deadline = active_remember_key_ds(id).get([remember_key_column, remember_deadline_column])
 97   return unless actual
 98 
 99   if hmac_secret && !(valid = timing_safe_eql?(key, compute_hmac(actual)))
100     if hmac_secret_rotation? && (valid = timing_safe_eql?(key, compute_old_hmac(actual)))
101       _set_remember_cookie(id, actual, deadline)
102     elsif !(raw_remember_token_deadline && raw_remember_token_deadline > convert_timestamp(deadline))
103       return
104     end
105   end
106 
107   unless valid || timing_safe_eql?(key, actual)
108     return
109   end
110 
111   id
112 end
remove_active_session(session_id) click to toggle source
   # File lib/rodauth/features/active_sessions.rb
92 def remove_active_session(session_id)
93   active_sessions_ds.where(active_sessions_session_id_column=>session_id).delete
94 end
remove_all_active_sessions() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
96 def remove_all_active_sessions
97   active_sessions_ds.delete
98 end
remove_all_active_sessions_except_current() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
104 def remove_all_active_sessions_except_current 
105   if session_id = session[session_id_session_key]
106     remove_all_active_sessions_except_for(session_id)
107   else
108     remove_all_active_sessions
109   end
110 end
remove_all_active_sessions_except_for(session_id) click to toggle source
    # File lib/rodauth/features/active_sessions.rb
100 def remove_all_active_sessions_except_for(session_id)
101   active_sessions_ds.exclude(active_sessions_session_id_column=>compute_hmacs(session_id)).delete
102 end
remove_all_webauthn_keys_and_user_ids() click to toggle source
    # File lib/rodauth/features/webauthn.rb
381 def remove_all_webauthn_keys_and_user_ids
382   webauthn_user_ids_ds.delete
383   webauthn_keys_ds.delete
384 end
remove_current_session() click to toggle source
   # File lib/rodauth/features/active_sessions.rb
86 def remove_current_session
87   if session_id = session[session_id_session_key]
88     remove_active_session(compute_hmacs(session_id))
89   end
90 end
remove_email_auth_key() click to toggle source
    # File lib/rodauth/features/email_auth.rb
127 def remove_email_auth_key
128   email_auth_ds.delete
129 end
remove_inactive_sessions() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
112 def remove_inactive_sessions
113   if cond = inactive_session_cond
114     active_sessions_ds.where(cond).delete
115   end
116 end
remove_jwt_refresh_token_key(token) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
180 def remove_jwt_refresh_token_key(token)
181   account_id, token_id, _ = _account_refresh_token_split(token)
182   jwt_refresh_token_account_token_ds(account_id, token_id).delete
183 end
remove_lockout_metadata() click to toggle source
    # File lib/rodauth/features/lockout.rb
270 def remove_lockout_metadata
271   account_login_failures_ds.delete
272   account_lockouts_ds.delete
273 end
remove_remember_key(id=account_id) click to toggle source
    # File lib/rodauth/features/remember.rb
170 def remove_remember_key(id=account_id)
171   remember_key_ds(id).delete
172 end
remove_reset_password_key() click to toggle source
    # File lib/rodauth/features/reset_password.rb
177 def remove_reset_password_key
178   password_reset_ds.delete
179 end
remove_session_value(key) click to toggle source
    # File lib/rodauth/features/base.rb
881 def remove_session_value(key)
882   session.delete(key)
883 end
remove_verify_account_key() click to toggle source
    # File lib/rodauth/features/verify_account.rb
167 def remove_verify_account_key
168   verify_account_ds.delete
169 end
remove_verify_login_change_key() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
108 def remove_verify_login_change_key
109   verify_login_change_ds.delete
110 end
remove_webauthn_key(webauthn_id) click to toggle source
    # File lib/rodauth/features/webauthn.rb
377 def remove_webauthn_key(webauthn_id)
378   webauthn_keys_ds.where(webauthn_keys_webauthn_id_column=>webauthn_id).delete == 1
379 end
render(page) click to toggle source
    # File lib/rodauth/features/base.rb
426 def render(page)
427   _view(:render, page)
428 end
render_multi_phase_login_forms() click to toggle source
    # File lib/rodauth/features/login.rb
137 def render_multi_phase_login_forms
138   multi_phase_login_forms.sort.map{|_, form, _| form}.join("\n")
139 end
request() click to toggle source
    # File lib/rodauth/features/base.rb
151 def request
152   scope.request
153 end
require_account() click to toggle source
    # File lib/rodauth/features/base.rb
372 def require_account
373   require_authentication
374   require_account_session
375 end
require_account_session() click to toggle source
    # File lib/rodauth/features/base.rb
628 def require_account_session
629   unless account_from_session
630     clear_session
631     login_required
632   end
633 end
require_authentication() click to toggle source
    # File lib/rodauth/features/base.rb
368 def require_authentication
369   require_login
370 end
require_current_password() click to toggle source
   # File lib/rodauth/features/password_expiration.rb
61 def require_current_password
62   if authenticated? && password_expired? && password_change_needed_redirect != request.path_info
63     set_redirect_error_flash password_expiration_error_flash
64     redirect password_change_needed_redirect
65   end
66 end
require_http_basic_auth() click to toggle source
   # File lib/rodauth/features/http_basic_auth.rb
27 def require_http_basic_auth
28   unless http_basic_auth
29     set_http_basic_auth_error_response
30     return_response
31   end
32 end
require_login() click to toggle source
    # File lib/rodauth/features/base.rb
360 def require_login
361   login_required unless logged_in?
362 end
require_login_confirmation?() click to toggle source
    # File lib/rodauth/features/verify_account.rb
159 def require_login_confirmation?
160   false
161 end
require_login_redirect() click to toggle source
    # File lib/rodauth/features/login.rb
141 def require_login_redirect
142   login_path
143 end
require_otp_setup() click to toggle source
    # File lib/rodauth/features/otp.rb
234 def require_otp_setup
235   unless otp_exists?
236     set_redirect_error_status(two_factor_not_setup_error_status)
237     set_error_reason :two_factor_not_setup
238     set_redirect_error_flash two_factor_not_setup_error_flash
239     redirect two_factor_need_setup_redirect
240   end
241 end
require_password_authentication() click to toggle source
   # File lib/rodauth/features/confirm_password.rb
51 def require_password_authentication
52   require_login
53 
54   if require_password_authentication? && has_password?
55     set_redirect_error_status(password_authentication_required_error_status)
56     set_error_reason :password_authentication_required
57     set_redirect_error_flash password_authentication_required_error_flash
58     set_session_value(confirm_password_redirect_session_key, request.fullpath)
59     redirect password_authentication_required_redirect
60   end
61 end
require_password_authentication?() click to toggle source
Calls superclass method
   # File lib/rodauth/features/confirm_password.rb
87 def require_password_authentication?
88   return true if defined?(super) && super
89   !authenticated_by.include?('password')
90 end
require_response(meth) click to toggle source
    # File lib/rodauth/features/base.rb
872 def require_response(meth)
873   send(meth)
874   raise RuntimeError, "#{meth.to_s.sub(/\A_/, '')} overridden without returning a response (should use redirect or request.halt). This is a bug in your Rodauth configuration, not a bug in Rodauth itself."
875 end
require_sms_available() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
337 def require_sms_available
338   require_sms_setup
339 
340   if sms_locked_out?
341     set_redirect_error_status(lockout_error_status)
342     set_error_reason :sms_locked_out
343     set_redirect_error_flash sms_lockout_error_flash
344     redirect sms_lockout_redirect
345   end
346 end
require_sms_not_setup() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
328 def require_sms_not_setup
329   if sms_setup?
330     set_redirect_error_status(sms_already_setup_error_status)
331     set_error_reason :sms_already_setup
332     set_redirect_error_flash sms_already_setup_error_flash
333     redirect sms_already_setup_redirect
334   end
335 end
require_sms_setup() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
319 def require_sms_setup
320   unless sms_setup?
321     set_redirect_error_status(two_factor_not_setup_error_status)
322     set_error_reason :sms_not_setup
323     set_redirect_error_flash sms_not_setup_error_flash
324     redirect sms_needs_setup_redirect
325   end
326 end
require_two_factor_authenticated() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
167 def require_two_factor_authenticated
168   unless two_factor_authenticated?
169     if two_factor_auth_return_to_requested_location?
170       set_session_value(two_factor_auth_redirect_session_key, request.fullpath)
171     end
172     set_redirect_error_status(two_factor_need_authentication_error_status)
173     set_error_reason :two_factor_need_authentication
174     set_redirect_error_flash two_factor_need_authentication_error_flash
175     redirect two_factor_auth_required_redirect
176   end
177 end
require_two_factor_not_authenticated(auth_type = nil) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
158 def require_two_factor_not_authenticated(auth_type = nil)
159   if two_factor_authenticated? || (auth_type && two_factor_login_type_match?(auth_type))
160     set_redirect_error_status(two_factor_already_authenticated_error_status)
161     set_error_reason :two_factor_already_authenticated
162     set_redirect_error_flash two_factor_already_authenticated_error_flash
163     redirect two_factor_already_authenticated_redirect
164   end
165 end
require_two_factor_setup() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
146 def require_two_factor_setup
147   # Avoid database query if already authenticated via 2nd factor
148   return if two_factor_authenticated?
149 
150   return if uses_two_factor_authentication?
151 
152   set_redirect_error_status(two_factor_not_setup_error_status)
153   set_error_reason :two_factor_not_setup
154   set_redirect_error_flash two_factor_not_setup_error_flash
155   redirect two_factor_need_setup_redirect
156 end
require_webauthn_setup() click to toggle source
    # File lib/rodauth/features/webauthn.rb
390 def require_webauthn_setup
391   unless webauthn_setup?
392     set_redirect_error_status(webauthn_not_setup_error_status)
393     set_error_reason :webauthn_not_setup
394     set_redirect_error_flash webauthn_not_setup_error_flash
395     redirect two_factor_need_setup_redirect
396   end
397 end
rescue_jwt_payload(_) click to toggle source
    # File lib/rodauth/features/jwt.rb
137 def rescue_jwt_payload(_)
138   @jwt_payload = false
139 end
reset_password_email_recently_sent?() click to toggle source
    # File lib/rodauth/features/reset_password.rb
213 def reset_password_email_recently_sent?
214   (email_last_sent = get_reset_password_email_last_sent) && (Time.now - email_last_sent < reset_password_skip_resend_email_within)
215 end
reset_password_key_insert_hash() click to toggle source
    # File lib/rodauth/features/reset_password.rb
243 def reset_password_key_insert_hash
244   hash = {reset_password_id_column=>account_id, reset_password_key_column=>reset_password_key_value}
245   set_deadline_value(hash, reset_password_deadline_column, reset_password_deadline_interval)
246   hash
247 end
reset_single_session_key() click to toggle source
   # File lib/rodauth/features/single_session.rb
22 def reset_single_session_key
23   if logged_in?
24     single_session_ds.update(single_session_key_column=>random_key)
25   end
26 end
response() click to toggle source
    # File lib/rodauth/features/base.rb
155 def response
156   scope.response
157 end
retry_on_uniqueness_violation() { || ... } click to toggle source

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.

    # File lib/rodauth/features/base.rb
818 def retry_on_uniqueness_violation(&block)
819   if raises_uniqueness_violation?(&block)
820     yield
821   end
822 end
return_json_response() click to toggle source
    # File lib/rodauth/features/json.rb
201 def return_json_response
202   _return_json_response
203 end
return_response(body=nil) click to toggle source
    # File lib/rodauth/features/base.rb
591 def return_response(body=nil)
592   response.write(body) if body
593   request.halt
594 end
route!() click to toggle source
    # File lib/rodauth/features/base.rb
167 def route!
168   if meth = self.class.route_hash[request.remaining_path]
169     send(meth)
170   end
171 
172   nil
173 end
route_path(route, opts={}) click to toggle source
    # File lib/rodauth/features/base.rb
596 def route_path(route, opts={})
597   path  = "#{prefix}/#{route}"
598   path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
599   path
600 end
route_url(route, opts={}) click to toggle source
    # File lib/rodauth/features/base.rb
602 def route_url(route, opts={})
603   "#{base_url}#{route_path(route, opts)}"
604 end
save_account() click to toggle source
    # File lib/rodauth/features/create_account.rb
100 def save_account
101   id = nil
102   raised = raises_uniqueness_violation?{id = db[accounts_table].insert(account)}
103 
104   if raised
105     set_login_requirement_error_message(:already_an_account_with_this_login, already_an_account_with_this_login_message)
106   end
107 
108   if id
109     account[account_id_column] ||= id
110   end
111 
112   id && !raised
113 end
send_email(email) click to toggle source
   # File lib/rodauth/features/email_base.rb
36 def send_email(email)
37   email.deliver!
38 end
send_verify_login_change_email(login) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
124 def send_verify_login_change_email(login)
125   send_email(create_verify_login_change_email(login))
126 end
serialize_audit_log_metadata(metadata) click to toggle source
   # File lib/rodauth/features/audit_logging.rb
55 def serialize_audit_log_metadata(metadata)
56   metadata.to_json unless metadata.nil?
57 end
session() click to toggle source
    # File lib/rodauth/features/base.rb
159 def session
160   scope.session
161 end
session_inactivity_deadline_condition() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
176 def session_inactivity_deadline_condition
177   if deadline = session_inactivity_deadline
178     Sequel[active_sessions_last_use_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
179   end
180 end
session_jwt() click to toggle source
   # File lib/rodauth/features/jwt.rb
77 def session_jwt
78   JWT.encode(jwt_session_hash, jwt_secret, jwt_algorithm)
79 end
session_lifetime_deadline_condition() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
182 def session_lifetime_deadline_condition
183   if deadline = session_lifetime_deadline
184     Sequel[active_sessions_created_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: deadline)
185   end
186 end
session_value() click to toggle source
    # File lib/rodauth/features/base.rb
274 def session_value
275   session[session_key]
276 end
Also aliased as: logged_in?
set_deadline_value(hash, column, interval) click to toggle source

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

    # File lib/rodauth/features/base.rb
854 def set_deadline_value(hash, column, interval)
855   if set_deadline_values?
856     # :nocov:
857     hash[column] = Sequel.date_add(Sequel::CURRENT_TIMESTAMP, interval)
858     # :nocov:
859   end
860 end
set_deadline_values?() click to toggle source
    # File lib/rodauth/features/base.rb
678 def set_deadline_values?
679   db.database_type == :mysql
680 end
set_email_auth_email_last_sent() click to toggle source
    # File lib/rodauth/features/email_auth.rb
115 def set_email_auth_email_last_sent
116    email_auth_ds.update(email_auth_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if email_auth_email_last_sent_column
117 end
set_error_flash(message) click to toggle source
    # File lib/rodauth/features/base.rb
344 def set_error_flash(message)
345   flash.now[flash_error_key] = message
346 end
set_error_reason(reason) click to toggle source
    # File lib/rodauth/features/base.rb
666 def set_error_reason(reason)
667 end
set_expired() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
49 def set_expired
50   update_activity(account_id, account_activity_expired_column)
51   after_account_expiration
52 end
set_field_error(field, error) click to toggle source
    # File lib/rodauth/features/base.rb
175 def set_field_error(field, error)
176   (@field_errors ||= {})[field] = error
177 end
set_http_basic_auth_error_response() click to toggle source
   # File lib/rodauth/features/http_basic_auth.rb
74 def set_http_basic_auth_error_response
75   response.status = 401
76   response.headers["WWW-Authenticate"] = "Basic realm=\"#{http_basic_auth_realm}\""
77 end
set_jwt() click to toggle source
    # File lib/rodauth/features/jwt.rb
158 def set_jwt
159   set_jwt_token(session_jwt)
160 end
set_jwt_refresh_token_hmac_session_key(token) click to toggle source
    # File lib/rodauth/features/jwt_refresh.rb
196 def set_jwt_refresh_token_hmac_session_key(token)
197   if allow_refresh_with_expired_jwt_access_token?
198     key = _account_refresh_token_split(token).last
199     data = random_key
200     set_session_value(jwt_refresh_token_data_session_key, data)
201     set_session_value(jwt_refresh_token_hmac_session_key, compute_hmac(data + key))
202   end
203 end
set_jwt_token(token) click to toggle source
   # File lib/rodauth/features/jwt.rb
89 def set_jwt_token(token)
90   response.headers['Authorization'] = token
91 end
set_last_password_entry() click to toggle source
   # File lib/rodauth/features/password_grace_period.rb
44 def set_last_password_entry
45   set_session_value(last_password_entry_session_key, Time.now.to_i)
46 end
set_login_requirement_error_message(reason, message) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
124 def set_login_requirement_error_message(reason, message)
125   set_error_reason(reason)
126   @login_requirement_message = message
127 end
set_new_account_password(password) click to toggle source
   # File lib/rodauth/features/create_account.rb
92 def set_new_account_password(password)
93   account[account_password_hash_column] = password_hash(password)
94 end
set_notice_flash(message) click to toggle source
    # File lib/rodauth/features/base.rb
352 def set_notice_flash(message)
353   flash[flash_notice_key] = message
354 end
set_notice_now_flash(message) click to toggle source
    # File lib/rodauth/features/base.rb
356 def set_notice_now_flash(message)
357   flash.now[flash_notice_key] = message
358 end
set_password(password) click to toggle source
Calls superclass method
   # File lib/rodauth/features/disallow_password_reuse.rb
19 def set_password(password)
20   hash = super
21   add_previous_password_hash(hash)
22   hash
23 end
set_password_requirement_error_message(reason, message) click to toggle source
    # File lib/rodauth/features/login_password_requirements_base.rb
103 def set_password_requirement_error_message(reason, message)
104   set_error_reason(reason)
105   @password_requirement_message = message
106 end
set_redirect_error_flash(message) click to toggle source
    # File lib/rodauth/features/base.rb
348 def set_redirect_error_flash(message)
349   flash[flash_error_key] = message
350 end
set_redirect_error_status(status) click to toggle source

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

    # File lib/rodauth/features/base.rb
640 def set_redirect_error_status(status)
641 end
set_reset_password_email_last_sent() click to toggle source
    # File lib/rodauth/features/reset_password.rb
195 def set_reset_password_email_last_sent
196    password_reset_ds.update(reset_password_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if reset_password_email_last_sent_column
197 end
set_response_error_reason_status(reason, status) click to toggle source
    # File lib/rodauth/features/base.rb
647 def set_response_error_reason_status(reason, status)
648   set_error_reason(reason)
649   set_response_error_status(status)
650 end
set_response_error_status(status) click to toggle source
    # File lib/rodauth/features/base.rb
643 def set_response_error_status(status)
644   response.status = status
645 end
set_session_value(key, value) click to toggle source
    # File lib/rodauth/features/base.rb
877 def set_session_value(key, value)
878   session[key] = value
879 end
set_single_session_key(data) click to toggle source
   # File lib/rodauth/features/single_session.rb
94 def set_single_session_key(data)
95   data = compute_hmac(data) if hmac_secret
96   set_session_value(single_session_session_key, data)
97 end
set_title(title) click to toggle source
    # File lib/rodauth/features/base.rb
338 def set_title(title)
339   if title_instance_variable
340     scope.instance_variable_set(title_instance_variable, title)
341   end
342 end
set_unlock_account_email_last_sent() click to toggle source
    # File lib/rodauth/features/lockout.rb
236 def set_unlock_account_email_last_sent
237   account_lockouts_ds.update(account_lockouts_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if account_lockouts_email_last_sent_column
238 end
set_verify_account_email_last_sent() click to toggle source
    # File lib/rodauth/features/verify_account.rb
225 def set_verify_account_email_last_sent
226    verify_account_ds.update(verify_account_email_last_sent_column=>Sequel::CURRENT_TIMESTAMP) if verify_account_email_last_sent_column
227 end
setup_account_verification() click to toggle source
    # File lib/rodauth/features/verify_account.rb
237 def setup_account_verification
238   generate_verify_account_key_value
239   create_verify_account_key
240   send_verify_account_email
241 end
show_lockout_page() click to toggle source
    # File lib/rodauth/features/lockout.rb
275 def show_lockout_page
276   set_response_error_reason_status(:account_locked_out, lockout_error_status)
277   set_error_flash login_lockout_error_flash
278   return_response unlock_account_request_view
279 end
single_session_ds() click to toggle source
    # File lib/rodauth/features/single_session.rb
 99 def single_session_ds
100   db[single_session_table].
101     where(single_session_id_column=>session_value)
102 end
skip_login_field_on_login?() click to toggle source
    # File lib/rodauth/features/login.rb
115 def skip_login_field_on_login?
116   return false unless use_multi_phase_login?
117   valid_login_entered?
118 end
skip_password_field_on_login?() click to toggle source
    # File lib/rodauth/features/login.rb
120 def skip_password_field_on_login?
121   return false unless use_multi_phase_login?
122   !valid_login_entered?
123 end
skip_status_checks?() click to toggle source
   # File lib/rodauth/features/close_account.rb
84 def skip_status_checks?
85   false
86 end
sms_auth_message(code) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
399 def sms_auth_message(code)
400   "SMS authentication code for #{domain} is #{code}"
401 end
sms_available?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
452 def sms_available?
453   sms_setup? && !sms_locked_out?
454 end
sms_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
431 def sms_code
432   sms[sms_code_column]
433 end
sms_code_issued_at() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
435 def sms_code_issued_at
436   convert_timestamp(sms[sms_issued_at_column])
437 end
sms_code_match?(code) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
348 def sms_code_match?(code)
349   return false unless sms_current_auth?
350   timing_safe_eql?(code, sms_code)
351 end
sms_codes_primary?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
500 def sms_codes_primary?
501   (features & [:otp, :webauthn]).empty?
502 end
sms_confirm() click to toggle source
Calls superclass method
    # File lib/rodauth/features/recovery_codes.rb
146 def sms_confirm
147   super if defined?(super)
148   auto_add_missing_recovery_codes
149 end
sms_confirm_failure() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
362 def sms_confirm_failure
363   sms_ds.delete
364 end
sms_confirm_message(code) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
403 def sms_confirm_message(code)
404   "SMS confirmation code for #{domain} is #{code}"
405 end
sms_confirmation_match?(code) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
353 def sms_confirmation_match?(code)
354   sms_needs_confirmation? && sms_code_match?(code)
355 end
sms_current_auth?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
460 def sms_current_auth?
461   sms_code && sms_code_issued_at + sms_code_allowed_seconds > Time.now
462 end
sms_disable() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
357 def sms_disable
358   sms_ds.delete
359   @sms = nil
360 end
sms_ds() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
528 def sms_ds
529   db[sms_codes_table].where(sms_id_column=>session_value)
530 end
sms_failures() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
439 def sms_failures
440   sms[sms_failures_column]
441 end
sms_locked_out?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
456 def sms_locked_out?
457   sms_failures >= sms_failure_limit
458 end
sms_needs_confirmation?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
448 def sms_needs_confirmation?
449   sms && sms_failures.nil?
450 end
sms_needs_confirmation_notice_flash() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
407 def sms_needs_confirmation_notice_flash
408   sms_needs_confirmation_error_flash
409 end
sms_new_auth_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
508 def sms_new_auth_code
509   SecureRandom.random_number(10**sms_auth_code_length).to_s.rjust(sms_auth_code_length, "0")
510 end
sms_new_confirm_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
512 def sms_new_confirm_code
513   SecureRandom.random_number(10**sms_confirm_code_length).to_s.rjust(sms_confirm_code_length, "0")
514 end
sms_normalize_phone(phone) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
504 def sms_normalize_phone(phone)
505   phone.to_s.gsub(/\D+/, '')
506 end
sms_phone() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
427 def sms_phone
428   sms[sms_phone_column]
429 end
sms_record_failure() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
422 def sms_record_failure
423   update_sms(sms_failures_column=>Sequel.expr(sms_failures_column)+1)
424   sms[sms_failures_column] = sms_ds.get(sms_failures_column)
425 end
sms_remove_expired_confirm_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
415 def sms_remove_expired_confirm_code
416   db[sms_codes_table].
417     where(sms_id_column=>session_value, sms_failures_column => nil).
418     where(Sequel[sms_issued_at_column] < Sequel.date_sub(Sequel::CURRENT_TIMESTAMP, seconds: sms_confirm_deadline)).
419     delete
420 end
sms_remove_failures() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
373 def sms_remove_failures
374   return if sms_needs_confirmation?
375   update_hash_ds(sms, sms_ds.exclude(sms_failures_column => nil), sms_failures_column => 0, sms_code_column => nil)
376 end
sms_send(phone, message) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
516 def sms_send(phone, message)
517   raise NotImplementedError, "sms_send needs to be defined in the Rodauth configuration for SMS sending to work"
518 end
sms_send_auth_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
383 def sms_send_auth_code
384   code = sms_new_auth_code
385   sms_set_code(code)
386   sms_send(sms_phone, sms_auth_message(code))
387 end
sms_send_confirm_code() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
389 def sms_send_confirm_code
390   code = sms_new_confirm_code
391   sms_set_code(code)
392   sms_send(sms_phone, sms_confirm_message(code))
393 end
sms_set_code(code) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
411 def sms_set_code(code)
412  update_sms(sms_code_column=>code, sms_issued_at_column=>Sequel::CURRENT_TIMESTAMP)
413 end
sms_setup(phone_number) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
366 def sms_setup(phone_number)
367   # Cannot handle uniqueness violation here, as the phone number given may not match the
368   # one in the table.
369   sms_ds.insert(sms_id_column=>session_value, sms_phone_column=>phone_number, sms_failures_column => nil)
370   remove_instance_variable(:@sms) if instance_variable_defined?(:@sms)
371 end
sms_setup?() click to toggle source
    # File lib/rodauth/features/sms_codes.rb
443 def sms_setup?
444   return false unless sms
445   !sms_needs_confirmation?
446 end
sms_valid_phone?(phone) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
395 def sms_valid_phone?(phone)
396   phone.length >= sms_phone_min_length
397 end
split_token(token) click to toggle source
    # File lib/rodauth/features/base.rb
564 def split_token(token)
565   token.split(token_separator, 2)
566 end
template_path(page) click to toggle source
    # File lib/rodauth/features/base.rb
783 def template_path(page)
784   File.join(File.dirname(__FILE__), '../../../templates', "#{page}.str")
785 end
throw_basic_auth_error(*args) click to toggle source
   # File lib/rodauth/features/http_basic_auth.rb
79 def throw_basic_auth_error(*args)
80   set_http_basic_auth_error_response
81   throw_error(*args) 
82 end
throw_error(field, error) click to toggle source
    # File lib/rodauth/features/base.rb
656 def throw_error(field, error)
657   set_field_error(field, error)
658   throw_rodauth_error
659 end
throw_error_reason(reason, status, field, message) click to toggle source
    # File lib/rodauth/features/base.rb
669 def throw_error_reason(reason, status, field, message)
670   set_error_reason(reason)
671   throw_error_status(status, field, message)
672 end
throw_error_status(status, field, error) click to toggle source
    # File lib/rodauth/features/base.rb
661 def throw_error_status(status, field, error)
662   set_response_error_status(status)
663   throw_error(field, error)
664 end
throw_rodauth_error() click to toggle source
    # File lib/rodauth/features/base.rb
652 def throw_rodauth_error
653   throw :rodauth_error
654 end
timing_safe_eql?(provided, actual) click to toggle source
    # File lib/rodauth/features/base.rb
623 def timing_safe_eql?(provided, actual)
624   provided = provided.to_s
625   Rack::Utils.secure_compare(provided.ljust(actual.length), actual) && provided.length == actual.length
626 end
token_param_value(key) click to toggle source
   # File lib/rodauth/features/email_base.rb
57 def token_param_value(key)
58   "#{account_id}#{token_separator}#{convert_email_token_key(key)}"
59 end
transaction(opts={}, &block) click to toggle source
    # File lib/rodauth/features/base.rb
606 def transaction(opts={}, &block)
607   db.transaction(opts, &block)
608 end
translate(_key, default) click to toggle source
    # File lib/rodauth/features/base.rb
242 def translate(_key, default)
243   # do not attempt to translate by default
244   default
245 end
two_factor_authenticate(type) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
248 def two_factor_authenticate(type)
249   two_factor_update_session(type)
250   two_factor_remove_auth_failures
251   after_two_factor_authentication
252   require_response(:_two_factor_auth_response)
253 end
two_factor_authenticated?() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
191 def two_factor_authenticated?
192   authenticated_by && authenticated_by.length >= 2
193 end
two_factor_authentication_setup?() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
195 def two_factor_authentication_setup?
196   possible_authentication_methods.length >= 2
197 end
two_factor_login_type_match?(type) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
205 def two_factor_login_type_match?(type)
206   authenticated_by && authenticated_by.include?(type)
207 end
two_factor_modifications_require_password?() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
122 def two_factor_modifications_require_password?
123   modifications_require_password?
124 end
two_factor_password_match?(password) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
183 def two_factor_password_match?(password)
184   if two_factor_modifications_require_password?
185     password_match?(password)
186   else
187     true
188   end
189 end
two_factor_remove() click to toggle source
Calls superclass method
    # File lib/rodauth/features/otp.rb
224 def two_factor_remove
225   super
226   otp_remove
227 end
two_factor_remove_auth_failures() click to toggle source
Calls superclass method
    # File lib/rodauth/features/otp.rb
229 def two_factor_remove_auth_failures
230   super
231   otp_remove_auth_failures
232 end
two_factor_remove_session(type) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
261 def two_factor_remove_session(type)
262   authenticated_by.delete(type)
263   remove_session_value(two_factor_setup_session_key)
264   if authenticated_by.empty?
265     clear_session
266   end
267 end
two_factor_update_session(auth_type) click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
269 def two_factor_update_session(auth_type)
270   authenticated_by << auth_type
271   set_session_value(two_factor_setup_session_key, true)
272 end
unique_constraint_violation_class() click to toggle source

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

    # File lib/rodauth/features/base.rb
836 def unique_constraint_violation_class
837   if db.adapter_scheme == :jdbc && db.database_type == :sqlite
838     # :nocov:
839     Sequel::ConstraintViolation
840     # :nocov:
841   else
842     Sequel::UniqueConstraintViolation
843   end
844 end
unlock_account() click to toggle source
    # File lib/rodauth/features/lockout.rb
159 def unlock_account
160   transaction do
161     remove_lockout_metadata
162   end
163 end
unlock_account_email_recently_sent?() click to toggle source
    # File lib/rodauth/features/lockout.rb
281 def unlock_account_email_recently_sent?
282   (email_last_sent = get_unlock_account_email_last_sent) && (Time.now - email_last_sent < unlock_account_skip_resend_email_within)
283 end
unverified_grace_period_expired?() click to toggle source
   # File lib/rodauth/features/verify_account_grace_period.rb
92 def unverified_grace_period_expired?
93   return false unless expires_at = session[unverified_account_session_key]
94   expires_at.is_a?(Integer) && Time.now.to_i > expires_at
95 end
update_account(values, ds=account_ds) click to toggle source
    # File lib/rodauth/features/base.rb
895 def update_account(values, ds=account_ds)
896   update_hash_ds(account, ds, values)
897 end
update_activity(account_id, *columns) click to toggle source
    # File lib/rodauth/features/account_expiration.rb
113 def update_activity(account_id, *columns)
114   ds = account_activity_ds(account_id)
115   hash = {}
116   columns.each do |c|
117     hash[c] = Sequel::CURRENT_TIMESTAMP
118   end
119   if ds.update(hash) == 0
120     hash[account_activity_id_column] = account_id
121     hash[account_activity_last_activity_column] ||= Sequel::CURRENT_TIMESTAMP
122     hash[account_activity_last_login_column] ||= Sequel::CURRENT_TIMESTAMP
123     # It is safe to ignore uniqueness violations here, as a concurrent insert would also use current timestamps.
124     ignore_uniqueness_violation{ds.insert(hash)}
125   end
126 end
update_current_session?() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
195 def update_current_session?
196   !!session_inactivity_deadline
197 end
update_hash_ds(hash, ds, values) click to toggle source
    # File lib/rodauth/features/base.rb
885 def update_hash_ds(hash, ds, values)
886   num = ds.update(values)
887   if num == 1
888     values.each do |k, v|
889       hash[k] = Sequel::CURRENT_TIMESTAMP == v ? Time.now : v
890     end
891   end
892   num
893 end
update_last_activity() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
43 def update_last_activity
44   if session_value
45     update_activity(session_value, account_activity_last_activity_column)
46   end
47 end
update_last_login() click to toggle source
   # File lib/rodauth/features/account_expiration.rb
39 def update_last_login
40   update_activity(account_id, account_activity_last_login_column, account_activity_last_activity_column)
41 end
update_login(login) click to toggle source
   # File lib/rodauth/features/change_login.rb
79 def update_login(login)
80   _update_login(login)
81 end
update_password_changed_at() click to toggle source
   # File lib/rodauth/features/password_expiration.rb
52 def update_password_changed_at
53   ds = password_expiration_ds
54   if ds.update(password_expiration_changed_at_column=>Sequel::CURRENT_TIMESTAMP) == 0
55     # Ignoring the violation is safe here, since a concurrent insert would also set it to the
56     # current timestamp.
57     ignore_uniqueness_violation{ds.insert(password_expiration_id_column=>account_id)}
58   end
59 end
update_password_hash?() click to toggle source
   # File lib/rodauth/features/update_password_hash.rb
18 def update_password_hash?
19   password_hash_cost != @current_password_hash_cost || @update_password_hash
20 end
update_session() click to toggle source
Calls superclass method
   # File lib/rodauth/features/account_expiration.rb
72 def update_session
73   check_account_expiration
74   super
75 end
update_single_session_key() click to toggle source
   # File lib/rodauth/features/single_session.rb
66 def update_single_session_key
67   key = random_key
68   set_single_session_key(key)
69   if single_session_ds.update(single_session_key_column=>key) == 0
70     # Don't handle uniqueness violations here.  While we could get the stored key from the
71     # database, it could lead to two sessions sharing the same key, which this feature is
72     # designed to prevent.
73     single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key)
74   end
75 end
update_sms(values) click to toggle source
    # File lib/rodauth/features/sms_codes.rb
520 def update_sms(values)
521   update_hash_ds(sms, sms_ds, values)
522 end
use_database_authentication_functions?() click to toggle source
    # File lib/rodauth/features/base.rb
682 def use_database_authentication_functions?
683   case db.database_type
684   when :postgres, :mysql, :mssql
685     true
686   else
687     # :nocov:
688     false
689     # :nocov:
690   end
691 end
use_date_arithmetic?() click to toggle source
    # File lib/rodauth/features/active_sessions.rb
204 def use_date_arithmetic?
205   true
206 end
use_json?() click to toggle source
   # File lib/rodauth/features/json.rb
60 def use_json?
61   json_request? || only_json?
62 end
use_jwt?() click to toggle source
   # File lib/rodauth/features/jwt.rb
93 def use_jwt?
94   use_json?
95 end
use_multi_phase_login?() click to toggle source
    # File lib/rodauth/features/email_auth.rb
156 def use_multi_phase_login?
157   true
158 end
use_request_specific_csrf_tokens?() click to toggle source
    # File lib/rodauth/features/base.rb
693 def use_request_specific_csrf_tokens?
694   scope.opts[:rodauth_route_csrf] && scope.use_request_specific_csrf_tokens?
695 end
uses_two_factor_authentication?() click to toggle source
    # File lib/rodauth/features/two_factor_base.rb
199 def uses_two_factor_authentication?
200   return false unless logged_in?
201   set_session_value(two_factor_setup_session_key, two_factor_authentication_setup?) unless session.has_key?(two_factor_setup_session_key)
202   session[two_factor_setup_session_key]
203 end
valid_jwt?() click to toggle source
    # File lib/rodauth/features/jwt.rb
101 def valid_jwt?
102   !!(jwt_token && jwt_payload)
103 end
valid_login_entered?() click to toggle source
    # File lib/rodauth/features/login.rb
125 def valid_login_entered?
126   @valid_login_entered
127 end
valid_new_webauthn_credential?(webauthn_credential) click to toggle source
    # File lib/rodauth/features/webauthn.rb
314 def valid_new_webauthn_credential?(webauthn_credential)
315   _override_webauthn_credential_response_verify(webauthn_credential)
316   (challenge = param_or_nil(webauthn_setup_challenge_param)) &&
317     (hmac = param_or_nil(webauthn_setup_challenge_hmac_param)) &&
318     (timing_safe_eql?(compute_hmac(challenge), hmac) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(challenge), hmac))) &&
319     webauthn_credential.verify(challenge)
320 end
valid_webauthn_credential_auth?(webauthn_credential) click to toggle source
    # File lib/rodauth/features/webauthn.rb
362 def valid_webauthn_credential_auth?(webauthn_credential)
363   ds = webauthn_keys_ds.where(webauthn_keys_webauthn_id_column => webauthn_credential.id)
364   pub_key, sign_count = ds.get([webauthn_keys_public_key_column, webauthn_keys_sign_count_column])
365 
366   _override_webauthn_credential_response_verify(webauthn_credential)
367   (challenge = param_or_nil(webauthn_auth_challenge_param)) &&
368     (hmac = param_or_nil(webauthn_auth_challenge_hmac_param)) &&
369     (timing_safe_eql?(compute_hmac(challenge), hmac) || (hmac_secret_rotation? && timing_safe_eql?(compute_old_hmac(challenge), hmac))) &&
370     webauthn_credential.verify(challenge, public_key: pub_key, sign_count: sign_count) &&
371     ds.update(
372       webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count),
373       webauthn_keys_last_use_column => Sequel::CURRENT_TIMESTAMP
374     ) == 1
375 end
verified_account?() click to toggle source
   # File lib/rodauth/features/verify_account_grace_period.rb
17 def verified_account?
18   logged_in? && !session[unverified_account_session_key]
19 end
verify_account() click to toggle source
    # File lib/rodauth/features/verify_account.rb
171 def verify_account
172   update_account(account_status_column=>account_open_status_value) == 1
173 end
verify_account_check_already_logged_in() click to toggle source
    # File lib/rodauth/features/verify_account.rb
273 def verify_account_check_already_logged_in
274   check_already_logged_in
275 end
verify_account_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/verify_account.rb
298 def verify_account_ds(id=account_id)
299   db[verify_account_table].where(verify_account_id_column=>id)
300 end
verify_account_email_recently_sent?() click to toggle source
    # File lib/rodauth/features/verify_account.rb
253 def verify_account_email_recently_sent?
254   (email_last_sent = get_verify_account_email_last_sent) && (Time.now - email_last_sent < verify_account_skip_resend_email_within)
255 end
verify_account_email_resend() click to toggle source
    # File lib/rodauth/features/verify_account.rb
175 def verify_account_email_resend
176   if @verify_account_key_value = get_verify_account_key(account_id)
177     set_verify_account_email_last_sent
178     send_verify_account_email
179     true
180   end
181 end
verify_account_key_insert_hash() click to toggle source
    # File lib/rodauth/features/verify_account.rb
294 def verify_account_key_insert_hash
295   {verify_account_id_column=>account_id, verify_account_key_column=>verify_account_key_value}
296 end
verify_account_set_password?() click to toggle source
   # File lib/rodauth/features/verify_account_grace_period.rb
29 def verify_account_set_password?
30   false
31 end
verify_account_view() click to toggle source
  # File lib/rodauth/features/webauthn_verify_account.rb
7 def verify_account_view
8   webauthn_setup_view
9 end
verify_login_change() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
112 def verify_login_change
113   unless res = _update_login(verify_login_change_new_login)
114     remove_verify_login_change_key
115   end
116 
117   res
118 end
verify_login_change_ds(id=account_id) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
206 def verify_login_change_ds(id=account_id)
207   db[verify_login_change_table].where(verify_login_change_id_column=>id)
208 end
verify_login_change_email_body() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
202 def verify_login_change_email_body
203   render('verify-login-change-email')
204 end
verify_login_change_key_insert_hash(login) click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
192 def verify_login_change_key_insert_hash(login)
193   hash = {verify_login_change_id_column=>account_id, verify_login_change_key_column=>verify_login_change_key_value, verify_login_change_login_column=>login}
194   set_deadline_value(hash, verify_login_change_deadline_column, verify_login_change_deadline_interval)
195   hash
196 end
verify_login_change_old_login() click to toggle source
    # File lib/rodauth/features/verify_login_change.rb
140 def verify_login_change_old_login
141   account_ds.get(login_column)
142 end
view(page, title) click to toggle source
    # File lib/rodauth/features/base.rb
421 def view(page, title)
422   set_title(title)
423   _view(:view, page)
424 end
webauthn_account_id() click to toggle source
    # File lib/rodauth/features/webauthn.rb
491 def webauthn_account_id
492   session_value
493 end
webauthn_allow() click to toggle source
    # File lib/rodauth/features/webauthn.rb
340 def webauthn_allow
341   account_webauthn_ids
342 end
webauthn_auth_additional_form_tags() click to toggle source
Calls superclass method
   # File lib/rodauth/features/webauthn_login.rb
43 def webauthn_auth_additional_form_tags
44   if @webauthn_login
45     super.to_s + login_hidden_field
46   else
47     super
48   end
49 end
webauthn_auth_credential_from_form_submission() click to toggle source
    # File lib/rodauth/features/webauthn.rb
503 def webauthn_auth_credential_from_form_submission
504   begin
505     webauthn_credential = webauthn_form_submission_call(:from_get, webauthn_auth_data)
506 
507     unless valid_webauthn_credential_auth?(webauthn_credential)
508       throw_error_reason(:invalid_webauthn_auth_param, invalid_key_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
509     end
510   rescue WebAuthn::SignCountVerificationError
511     handle_webauthn_sign_count_verification_error
512   rescue WebAuthn::Error, RuntimeError, NoMethodError
513     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
514   end
515 
516   webauthn_credential
517 end
webauthn_auth_data() click to toggle source
    # File lib/rodauth/features/webauthn.rb
519 def webauthn_auth_data
520   case auth_data = raw_param(webauthn_auth_param)
521   when String
522     begin
523       JSON.parse(auth_data)
524     rescue
525       throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message) 
526     end
527   when Hash
528     auth_data
529   else
530     throw_error_reason(:invalid_webauthn_auth_param, invalid_field_error_status, webauthn_auth_param, webauthn_invalid_auth_param_message)
531   end
532 end
webauthn_auth_form_path() click to toggle source
    # File lib/rodauth/features/webauthn.rb
247 def webauthn_auth_form_path
248   webauthn_auth_path
249 end
webauthn_authenticator_selection() click to toggle source
    # File lib/rodauth/features/webauthn.rb
263 def webauthn_authenticator_selection
264   {'requireResidentKey' => false, 'userVerification' => webauthn_user_verification}
265 end
webauthn_create_relying_party_opts() click to toggle source
    # File lib/rodauth/features/webauthn.rb
422 def webauthn_create_relying_party_opts
423   { :relying_party => webauthn_relying_party }
424 end
webauthn_credential_options_for_get() click to toggle source
    # File lib/rodauth/features/webauthn.rb
322 def webauthn_credential_options_for_get
323   WebAuthn::Credential.options_for_get(
324     :allow => webauthn_allow,
325     :timeout => webauthn_auth_timeout,
326     :user_verification => webauthn_user_verification,
327     :extensions => webauthn_extensions,
328     **webauthn_get_relying_party_opts
329   )
330 end
webauthn_extensions() click to toggle source
    # File lib/rodauth/features/webauthn.rb
267 def webauthn_extensions
268   {}
269 end
webauthn_form_submission_call(meth, arg) click to toggle source
    # File lib/rodauth/features/webauthn.rb
427 def webauthn_form_submission_call(meth, arg)
428   WebAuthn::Credential.public_send(meth, arg, :relying_party => webauthn_relying_party)
429 end
webauthn_get_relying_party_opts()
webauthn_key_insert_hash(webauthn_credential) click to toggle source
    # File lib/rodauth/features/webauthn.rb
482 def webauthn_key_insert_hash(webauthn_credential)
483   {
484     webauthn_keys_account_id_column => webauthn_account_id,
485     webauthn_keys_webauthn_id_column => webauthn_credential.id,
486     webauthn_keys_public_key_column => webauthn_credential.public_key,
487     webauthn_keys_sign_count_column => Integer(webauthn_credential.sign_count)
488   }
489 end
webauthn_keys_ds() click to toggle source
    # File lib/rodauth/features/webauthn.rb
499 def webauthn_keys_ds
500   db[webauthn_keys_table].where(webauthn_keys_account_id_column => webauthn_account_id)
501 end
webauthn_login_options?() click to toggle source
Calls superclass method
   # File lib/rodauth/features/webauthn_autofill.rb
59 def webauthn_login_options?
60   return true unless param_or_nil(login_param)
61   super
62 end
webauthn_login_verification_factor?(webauthn_credential) click to toggle source
   # File lib/rodauth/features/webauthn_login.rb
70 def webauthn_login_verification_factor?(webauthn_credential)
71   webauthn_login_user_verification_additional_factor? &&
72     webauthn_credential.response.authenticator_data.user_verified? &&
73     uses_two_factor_authentication?
74 end
webauthn_origin() click to toggle source
    # File lib/rodauth/features/webauthn.rb
336 def webauthn_origin
337   base_url
338 end
webauthn_relying_party() click to toggle source
    # File lib/rodauth/features/webauthn.rb
413 def webauthn_relying_party
414   # No need to memoize, only called once per request
415   WebAuthn::RelyingParty.new(
416     origin: webauthn_origin,
417     id: webauthn_rp_id,
418     name: webauthn_rp_name,
419   )
420 end
webauthn_remove_authenticated_session() click to toggle source
    # File lib/rodauth/features/webauthn.rb
255 def webauthn_remove_authenticated_session
256   remove_session_value(authenticated_webauthn_id_session_key)
257 end
webauthn_rp_id() click to toggle source
    # File lib/rodauth/features/webauthn.rb
344 def webauthn_rp_id
345   webauthn_origin.sub(/\Ahttps?:\/\//, '').sub(/:\d+\z/, '')
346 end
webauthn_rp_name() click to toggle source
    # File lib/rodauth/features/webauthn.rb
348 def webauthn_rp_name
349   webauthn_rp_id
350 end
webauthn_setup?() click to toggle source
    # File lib/rodauth/features/webauthn.rb
386 def webauthn_setup?
387   !webauthn_keys_ds.empty?
388 end
webauthn_setup_credential_from_form_submission() click to toggle source
    # File lib/rodauth/features/webauthn.rb
534 def webauthn_setup_credential_from_form_submission
535   unless two_factor_password_match?(param(password_param))
536     throw_error_reason(:invalid_password, invalid_password_error_status, password_param, invalid_password_message)
537   end
538 
539   begin
540     webauthn_credential = webauthn_form_submission_call(:from_create, webauthn_setup_data)
541 
542     unless valid_new_webauthn_credential?(webauthn_credential)
543       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
544     end
545   rescue WebAuthn::Error, RuntimeError, NoMethodError
546     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
547   end
548 
549   webauthn_credential
550 end
webauthn_setup_data() click to toggle source
    # File lib/rodauth/features/webauthn.rb
552 def webauthn_setup_data
553   case setup_data = raw_param(webauthn_setup_param)
554   when String
555     begin
556       JSON.parse(setup_data)
557     rescue
558       throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message) 
559     end
560   when Hash
561     setup_data
562   else
563     throw_error_reason(:invalid_webauthn_setup_param, invalid_field_error_status, webauthn_setup_param, webauthn_invalid_setup_param_message)
564   end
565 end
webauthn_update_session(webauthn_id) click to toggle source
    # File lib/rodauth/features/webauthn.rb
259 def webauthn_update_session(webauthn_id)
260   set_session_value(authenticated_webauthn_id_session_key, webauthn_id)
261 end
webauthn_user_ids_ds() click to toggle source
    # File lib/rodauth/features/webauthn.rb
495 def webauthn_user_ids_ds
496   db[webauthn_user_ids_table].where(webauthn_user_ids_account_id_column => webauthn_account_id)
497 end
webauthn_user_name() click to toggle source
    # File lib/rodauth/features/webauthn.rb
332 def webauthn_user_name
333   account![login_column]
334 end
webauthn_user_verification() click to toggle source
   # File lib/rodauth/features/webauthn_autofill.rb
24 def webauthn_user_verification
25   'preferred'
26 end