rodauth 2.28.0 → 2.29.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 15ed571757453e13ded3557bd2736779546b2c759230f8ee9070976a0207899e
4
- data.tar.gz: 9aa5adf648fa1449a75a03d62ae4907f71d41adc49e81fde8da52097042c986c
3
+ metadata.gz: c1714e5a3a0a5bbae56f2905dd528611de3b958d505d312071148b56fdfb3d6f
4
+ data.tar.gz: 8bb57c30ced05b0825a5d1fd74efe9f6523202f1b151b591c0bbdf10ad9f12af
5
5
  SHA512:
6
- metadata.gz: bdae4bbe3d9c471f967a8b24741504494a4003edce0c265dba9026694d64c08f61bd74cdbf80bded79e3b2c163fe7d273fcf72741f986711891fea5e481c501f
7
- data.tar.gz: 5c6352c91b52012c6869a149e61887a1a6e0ace76557f2c4922eb699dc4da7f08a1265c5548bff25a3f617fa0a3b565b6d00f3472822d32812ae6261a4bcc95c
6
+ metadata.gz: 4dfc0639aaebdeacf6961122265720c992fb0d1af5d7864f5984fa902eef0ae49aea30db63681b1bdd1c598458f8ce5b035fdb3192249f3983afba15442bf990
7
+ data.tar.gz: d044a6934b3d06bee1e260de68ca5a88016b6f611da1e59dabf1e16afc63e7a82c6d16d196ed57a23558c14a0d6aecba4030ece7830a4f0a6211260b1e619b50
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ === 2.29.0 (2023-03-22)
2
+
3
+ * Support :render=>false plugin options (davekaro) (#319)
4
+
5
+ * Add remove_active_session method for removing the active session for a given session id (janko) (#317)
6
+
7
+ * Remove current active session when adding new active session (janko) (#314)
8
+
9
+ * Extend the remember cookie deadline once an hour by default while logged in (janko, jeremyevans) (#313)
10
+
11
+ * Add account! method for returning associated account or loading account based on the session value (janko) (#309)
12
+
1
13
  === 2.28.0 (2023-02-22)
2
14
 
3
15
  * Skip rendering reset password request form on invalid internal request logins (janko) (#303)
data/README.rdoc CHANGED
@@ -79,7 +79,8 @@ There are some dependencies that Rodauth uses depending on the
79
79
  features in use. These are development dependencies instead of
80
80
  runtime dependencies in the gem as it is possible to run without them:
81
81
 
82
- tilt :: Used by all features unless in JSON API only mode.
82
+ tilt :: Used by all features unless in JSON API only mode or using
83
+ :render=>false plugin option.
83
84
  rack_csrf :: Used for CSRF support if the <tt>csrf: :rack_csrf</tt> plugin
84
85
  option is given (the default is to use Roda's route_csrf
85
86
  plugin, as that allows for more secure request-specific
@@ -852,6 +853,8 @@ which configures which dependent plugins should be loaded. Options:
852
853
  :csrf :: Set to +false+ to not load a csrf plugin. Set to +:rack_csrf+
853
854
  to use the csrf plugin instead of the route_csrf plugin.
854
855
  :flash :: Set to +false+ to not load the flash plugin
856
+ :render :: Set to +false+ to not load the render plugin. This is useful
857
+ to avoid the dependency on tilt when using alternative view libaries.
855
858
  :json :: Set to +true+ to load the json and json_parser plugins. Set
856
859
  to +:only+ to only load those plugins and not any other plugins.
857
860
  Note that if you are enabling features that send email, you
@@ -1000,6 +1003,8 @@ logged_in? :: Whether the session has been logged in.
1000
1003
  authenticated? :: Similar to +logged_in?+, but if the account has setup two
1001
1004
  factor authentication, whether the session has authenticated
1002
1005
  via two factors.
1006
+ account! :: Returns the current account record if it has already been loaded,
1007
+ otherwise retrieves the account from session if logged in.
1003
1008
  authenticated_by :: An array of strings for successful authentication methods for
1004
1009
  the current session (e.g. password/remember/webauthn).
1005
1010
  possible_authentication_methods :: An array of strings for possible authentication
@@ -48,6 +48,7 @@ add_active_session :: Create a session id for the session and populate the sessi
48
48
  currently_active_session? :: Whether the session is currently active, by checking the database table.
49
49
  handle_duplicate_active_session_id(exception) :: How to handle the case where a duplicate session id for the account is inserted into the table. Does nothing by default. This should only be called if the random number generator is broken.
50
50
  no_longer_active_session :: What action to take if +rodauth.check_active_session+ is called and the session is no longer active.
51
+ remove_active_session(session_id) :: Removes the active session matching the given session ID from the database. Useful for implementing session revoking.
51
52
  remove_all_active_sessions :: Remove all active session from the database, used for global logouts and when closing accounts.
52
53
  remove_current_session :: Remove current session from the database, used for regular logouts.
53
54
  remove_inactive_sessions :: Remove inactive sessions from the database, run before checking for whether the current session is active.
data/doc/json.rdoc CHANGED
@@ -15,7 +15,7 @@ an array containing the field name and the error message for that field.
15
15
  Successful requests by default store a +success+ entry with a success
16
16
  message, though that can be disabled.
17
17
 
18
- The JSON response can be modified at any point by modifying the `json_response`
18
+ The JSON response can be modified at any point by modifying the +json_response+
19
19
  hash. The following example adds an {error reason}[rdoc-ref:doc/error_reasons.rdoc]
20
20
  to the JSON response:
21
21
 
@@ -0,0 +1,27 @@
1
+ = New Features
2
+
3
+ * When using the remember feature, by default, the remember deadline
4
+ is extended while logged in, if it hasn't been extended in the last
5
+ hour
6
+
7
+ * An account! method has been added, which will return the hash for
8
+ the account if already retrieved, or attempt to retrieve the
9
+ account hash using the currently logged in session if not.
10
+ Because of the ambiguity in the provenance of the returned account
11
+ hash, callers should be careful when using this method.
12
+
13
+ * A remove_active_session method has been added. You can call this
14
+ method with a specific session id, and it will remove the related
15
+ active session.
16
+
17
+ * A render: false plugin option is now support, which will disable
18
+ the automatic loading of the render plugin. This should only be
19
+ used if you are completely replacing Rodauth's view rendering with
20
+ your own.
21
+
22
+ = Other Improvements
23
+
24
+ * When logging in when using the active_sessions feature, if there is
25
+ a current active session, it is removed before a new active session
26
+ is created. This prevents some stale active sessions from remaining
27
+ in the database (which would eventually be cleaned up later).
data/doc/remember.rdoc CHANGED
@@ -30,13 +30,15 @@ for sessions autologged in via a remember token:
30
30
 
31
31
  == Auth Value Methods
32
32
 
33
- extend_remember_deadline? :: Whether to extend the remember token deadline when the user is autologged in via remember token.
33
+ extend_remember_deadline? :: Whether to extend the remember token deadline when the user is autologged in via remember token and every +extend_remember_deadline_period+ seconds while logged in.
34
+ extend_remember_deadline_period :: The amount of seconds to wait before extending remember token deadline when +extend_remember_deadline?+ is true (3600 by default).
34
35
  raw_remember_token_deadline :: A deadline before which to allow a raw remember token to be used. Allows for graceful transition for when +hmac_secret+ is first set.
35
36
  remember_additional_form_tags :: HTML fragment containing additional form tags to use on the change remember setting form.
36
37
  remember_button :: The text to use for the change remember settings button.
37
38
  remember_cookie_key :: The cookie name to use for the remember token.
38
39
  remember_cookie_options :: Any options to set for the remember cookie. By default, the `:path` cookie option is set to `/` and `:httponly` is set to `true`. Also, `:secure` is set to `true` by default if the current request is an HTTPS request.
39
40
  remember_deadline_column :: The column name in the +remember_table+ storing the deadline after which the token will be ignored.
41
+ remember_deadline_extended_session_key :: The session key set if the remember deadline token is being extended.
40
42
  remember_deadline_interval :: The amount of time for which to remember accounts, 14 days by default. Only used if +set_deadline_values?+ is true.
41
43
  remember_disable_label :: The label for disabling remembering.
42
44
  remember_disable_param_value :: The parameter value for disabling remembering.
@@ -29,6 +29,7 @@ module Rodauth
29
29
  :currently_active_session?,
30
30
  :handle_duplicate_active_session_id,
31
31
  :no_longer_active_session,
32
+ :remove_active_session,
32
33
  :remove_all_active_sessions,
33
34
  :remove_current_session,
34
35
  :remove_inactive_sessions,
@@ -82,10 +83,14 @@ module Rodauth
82
83
 
83
84
  def remove_current_session
84
85
  if session_id = session[session_id_session_key]
85
- active_sessions_ds.where(active_sessions_session_id_column=>compute_hmac(session_id)).delete
86
+ remove_active_session(compute_hmac(session_id))
86
87
  end
87
88
  end
88
89
 
90
+ def remove_active_session(session_id)
91
+ active_sessions_ds.where(active_sessions_session_id_column=>session_id).delete
92
+ end
93
+
89
94
  def remove_all_active_sessions
90
95
  active_sessions_ds.delete
91
96
  end
@@ -101,6 +106,7 @@ module Rodauth
101
106
  end
102
107
 
103
108
  def update_session
109
+ remove_current_session
104
110
  super
105
111
  add_active_session
106
112
  end
@@ -355,6 +355,10 @@ module Rodauth
355
355
  account_open_status_value
356
356
  end
357
357
 
358
+ def account!
359
+ account || (session_value && account_from_session)
360
+ end
361
+
358
362
  def account_from_session
359
363
  @account = _account_from_session
360
364
  end
@@ -680,7 +684,7 @@ module Rodauth
680
684
  # note that only the salt is returned.
681
685
  def get_password_hash
682
686
  if account_password_hash_column
683
- (account || account_from_session)[account_password_hash_column]
687
+ account![account_password_hash_column]
684
688
  elsif use_database_authentication_functions?
685
689
  db.get(Sequel.function(function_name(:rodauth_get_salt), account ? account_id : session_value))
686
690
  else
@@ -17,6 +17,7 @@ module Rodauth
17
17
  auth_value_method :raw_remember_token_deadline, nil
18
18
  auth_value_method :remember_cookie_options, {}.freeze
19
19
  auth_value_method :extend_remember_deadline?, false
20
+ auth_value_method :extend_remember_deadline_period, 3600
20
21
  auth_value_method :remember_period, {:days=>14}.freeze
21
22
  auth_value_method :remember_deadline_interval, {:days=>14}.freeze
22
23
  auth_value_method :remember_id_column, :id
@@ -28,6 +29,7 @@ module Rodauth
28
29
  auth_value_method :remember_remember_param_value, 'remember'
29
30
  auth_value_method :remember_forget_param_value, 'forget'
30
31
  auth_value_method :remember_disable_param_value, 'disable'
32
+ session_key :remember_deadline_extended_session_key, :remember_deadline_extended_at
31
33
  translatable_method :remember_remember_label, 'Remember Me'
32
34
  translatable_method :remember_forget_label, 'Forget Me'
33
35
  translatable_method :remember_disable_label, 'Disable Remember Me'
@@ -110,43 +112,23 @@ module Rodauth
110
112
  end
111
113
 
112
114
  def load_memory
113
- return if session[session_key]
114
-
115
- unless id = remembered_session_id
116
- # Only set expired cookie if there is already a cookie set.
117
- forget_login if _get_remember_cookie
118
- return
119
- end
120
-
121
- set_session_value(session_key, id)
122
- account = account_from_session
123
- remove_session_value(session_key)
124
-
125
- unless account
126
- remove_remember_key(id)
127
- forget_login
128
- return
129
- end
130
-
131
- before_load_memory
132
- login_session('remember')
133
-
134
- if extend_remember_deadline?
135
- active_remember_key_ds(id).update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
136
- remember_login
115
+ if logged_in?
116
+ if extend_remember_deadline_while_logged_in?
117
+ account_from_session
118
+ extend_remember_deadline
119
+ end
120
+ elsif account_from_remember_cookie
121
+ before_load_memory
122
+ login_session('remember')
123
+ extend_remember_deadline if extend_remember_deadline?
124
+ after_load_memory
137
125
  end
138
- after_load_memory
139
126
  end
140
127
 
141
128
  def remember_login
142
129
  get_remember_key
143
- opts = Hash[remember_cookie_options]
144
- opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
145
- opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
146
- opts[:path] = "/" unless opts.key?(:path)
147
- opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
148
- opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
149
- ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
130
+ set_remember_cookie
131
+ set_session_value(remember_deadline_extended_session_key, Time.now.to_i) if extend_remember_deadline?
150
132
  end
151
133
 
152
134
  def forget_login
@@ -191,6 +173,53 @@ module Rodauth
191
173
 
192
174
  private
193
175
 
176
+ def set_remember_cookie
177
+ opts = Hash[remember_cookie_options]
178
+ opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
179
+ opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
180
+ opts[:path] = "/" unless opts.key?(:path)
181
+ opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
182
+ opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
183
+ ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
184
+ end
185
+
186
+ def extend_remember_deadline_while_logged_in?
187
+ return false unless extend_remember_deadline?
188
+
189
+ if extended_at = session[remember_deadline_extended_session_key]
190
+ extended_at + extend_remember_deadline_period < Time.now.to_i
191
+ elsif logged_in_via_remember_key?
192
+ # Handle existing sessions before the change to extend remember deadline
193
+ # while logged in.
194
+ true
195
+ end
196
+ end
197
+
198
+ def extend_remember_deadline
199
+ active_remember_key_ds.update(remember_deadline_column=>Sequel.date_add(Sequel::CURRENT_TIMESTAMP, remember_period))
200
+ remember_login
201
+ end
202
+
203
+ def account_from_remember_cookie
204
+ unless id = remembered_session_id
205
+ # Only set expired cookie if there is already a cookie set.
206
+ forget_login if _get_remember_cookie
207
+ return
208
+ end
209
+
210
+ set_session_value(session_key, id)
211
+ account_from_session
212
+ remove_session_value(session_key)
213
+
214
+ unless account
215
+ remove_remember_key(id)
216
+ forget_login
217
+ return
218
+ end
219
+
220
+ account
221
+ end
222
+
194
223
  def _get_remember_cookie
195
224
  request.cookies[remember_cookie_key]
196
225
  end
@@ -83,7 +83,7 @@ module Rodauth
83
83
  end
84
84
 
85
85
  def account_in_unverified_grace_period?
86
- return false unless account || (session_value && account_from_session)
86
+ return false unless account!
87
87
  account[account_status_column] == account_unverified_status_value &&
88
88
  verify_account_grace_period &&
89
89
  !verify_account_ds.where(Sequel.date_add(verification_requested_at_column, :seconds=>verify_account_grace_period) > Sequel::CURRENT_TIMESTAMP).empty?
@@ -329,7 +329,7 @@ module Rodauth
329
329
  end
330
330
 
331
331
  def webauthn_user_name
332
- (account || account_from_session)[login_column]
332
+ account![login_column]
333
333
  end
334
334
 
335
335
  def webauthn_origin
@@ -6,7 +6,7 @@ module Rodauth
6
6
  MAJOR = 2
7
7
 
8
8
  # The minor version of Rodauth, updated for new feature releases of Rodauth.
9
- MINOR = 28
9
+ MINOR = 29
10
10
 
11
11
  # The patch version of Rodauth, updated only for bug fixes from the last
12
12
  # feature release.
data/lib/rodauth.rb CHANGED
@@ -22,8 +22,10 @@ module Rodauth
22
22
  end
23
23
 
24
24
  unless json_opt == :only
25
- require 'tilt/string'
26
- app.plugin :render
25
+ unless opts[:render] == false
26
+ require 'tilt/string'
27
+ app.plugin :render
28
+ end
27
29
 
28
30
  case opts.fetch(:csrf, app.opts[:rodauth_csrf])
29
31
  when false
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rodauth
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.28.0
4
+ version: 2.29.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jeremy Evans
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-02-22 00:00:00.000000000 Z
11
+ date: 2023-03-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -344,6 +344,7 @@ extra_rdoc_files:
344
344
  - doc/release_notes/2.26.0.txt
345
345
  - doc/release_notes/2.27.0.txt
346
346
  - doc/release_notes/2.28.0.txt
347
+ - doc/release_notes/2.29.0.txt
347
348
  - doc/release_notes/2.3.0.txt
348
349
  - doc/release_notes/2.4.0.txt
349
350
  - doc/release_notes/2.5.0.txt
@@ -459,6 +460,7 @@ files:
459
460
  - doc/release_notes/2.26.0.txt
460
461
  - doc/release_notes/2.27.0.txt
461
462
  - doc/release_notes/2.28.0.txt
463
+ - doc/release_notes/2.29.0.txt
462
464
  - doc/release_notes/2.3.0.txt
463
465
  - doc/release_notes/2.4.0.txt
464
466
  - doc/release_notes/2.5.0.txt