lib/rodauth/features/single_session.rb in rodauth-1.19.1 vs lib/rodauth/features/single_session.rb in rodauth-1.20.0

- old
+ new

@@ -3,10 +3,11 @@ module Rodauth Feature.define(:single_session, :SingleSession) do error_flash 'This session has been logged out as another session has become active' redirect + auth_value_method :allow_raw_single_session_key?, false auth_value_method :single_session_id_column, :id auth_value_method :single_session_key_column, :key session_key :single_session_session_key, :single_session_key auth_value_method :single_session_table, :account_session_keys @@ -33,11 +34,18 @@ # session. update_single_session_key end true elsif current_key - timing_safe_eql?(single_session_key, current_key) + if hmac_secret + valid = timing_safe_eql?(single_session_key, compute_hmac(current_key)) + if !valid && !allow_raw_single_session_key? + return false + end + end + + valid || timing_safe_eql?(single_session_key, current_key) end end def check_single_session if logged_in? && !currently_active_session? @@ -51,11 +59,11 @@ redirect single_session_redirect end def update_single_session_key key = random_key - set_session_value(single_session_session_key, key) + set_single_session_key(key) if single_session_ds.update(single_session_key_column=>key) == 0 # Don't handle uniqueness violations here. While we could get the stored key from the # database, it could lead to two sessions sharing the same key, which this feature is # designed to prevent. single_session_ds.insert(single_session_id_column=>session_value, single_session_key_column=>key) @@ -70,9 +78,14 @@ end def before_logout reset_single_session_key if request.post? super if defined?(super) + end + + def set_single_session_key(data) + data = compute_hmac(data) if hmac_secret + set_session_value(single_session_session_key, data) end def update_session super update_single_session_key