rodauth 2.6.0 → 2.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 82585797ff882cb56340e2145b05b74da1e10c428413b02e1656604fa8209c93
4
- data.tar.gz: 7148d04c255f4310a21c6373d9ab20888e8fe46d3a07c090576385890ea82858
3
+ metadata.gz: ce2af7161a7aaba17ebb25beda65f8598306b2d040986db0be215b89fb683149
4
+ data.tar.gz: cf69c788c9401485610599f0b6996f340ab315fcbceb359bccf01a78dceaadc8
5
5
  SHA512:
6
- metadata.gz: be8a3bffa982ca9730dafdefb8a8a874c2a2cb8fa62c84d4b0467928fc2164251ba28bb88948274316d7870473f0a602b8ac69eef8b48b70b27584ed7a443ded
7
- data.tar.gz: afaf45ddda1073eaba697035700ec9108bebd1fc18998af9245fd86f532f497e6723fa532624aae426dac7e1600556af7b7369b2e7203e387be26dcbdfc22e3d
6
+ metadata.gz: 8b2d72d0f9338a359653e90829618f2579afc30095bb0dd1bd0c627730c91117158ef5ebbca9a4a32bb78bd312ebbac308a68efb761cf93c4dfc707d7bdcea24
7
+ data.tar.gz: d5eb1fc01df26b8305edec707642d3192e7a5dc3507416d0e60aaf6ffd1b079ac4ddced72a85d61c4623c70df2d784307cfba60b8759741b2991f591c623b0b0
data/CHANGELOG CHANGED
@@ -1,3 +1,15 @@
1
+ === 2.7.0 (2020-12-22)
2
+
3
+ * Avoid method redefinition warnings in verbose warning mode (jeremyevans)
4
+
5
+ * Return expired access token error message in the JWT refresh feature when using an expired token when it isn't allowed (AlexyMatskevich) (#133)
6
+
7
+ * Allow Rodauth features to be preloaded, instead of always trying to require them (janko) (#136)
8
+
9
+ * Use a default remember cookie path of '/', though this may cause problem with multiple Rodauth configurations on the same domain (janko) (#134)
10
+
11
+ * Add auto_remove_recovery_codes? to the recovery_codes feature, for automatically removing the codes when disabling multifactor authentication (SilasSpet, jeremyevans) (#135)
12
+
1
13
  === 2.6.0 (2020-11-20)
2
14
 
3
15
  * Avoid loading features multiple times (janko) (#131)
@@ -30,6 +30,8 @@ This feature depends on the jwt feature.
30
30
  == Auth Value Methods
31
31
 
32
32
  allow_refresh_with_expired_jwt_access_token? :: Whether refreshing should be allowed with an expired access token. Default is +false+. You must set an +hmac_secret+ if setting this value to +true+.
33
+ expired_jwt_access_token_status :: The HTTP status code to use when a access token (JWT) is expired is submitted in the Authorization header. Default is 400 for backwards compatibility, and it is recommended to set it to 401.
34
+ expired_jwt_access_token_message :: The error message to use when a access token (JWT) is expired is submitted in the Authorization header.
33
35
  jwt_access_token_key :: Name of the key in the response json holding the access token. Default is +access_token+.
34
36
  jwt_access_token_not_before_period :: How many seconds before the current time will the jwt be considered valid (to account for inaccurate clocks). Default is 5.
35
37
  jwt_access_token_period :: Validity of an access token in seconds, default is 1800 (30 minutes).
@@ -17,7 +17,8 @@ add_recovery_codes_error_flash :: The flash error to show when adding recovery c
17
17
  add_recovery_codes_heading :: Text to use for heading above the form to add recovery codes.
18
18
  add_recovery_codes_page_title :: The page title to use on the add recovery codes form.
19
19
  add_recovery_codes_param :: The parameter name to use for adding recovery codes.
20
- auto_add_recovery_codes? :: Whether to automatically add recovery codes (or any missing recovery codes) when another multifactor authentication type is enabled (false by default).
20
+ auto_add_recovery_codes? :: Whether to automatically add recovery codes (or any missing recovery codes) when enabling otp, webauthn, or sms authentication (false by default).
21
+ auto_remove_recovery_codes? :: Whether to automatically remove recovery codes when disabling otp, webauthn, or sms authentication and not having one of the other two authentication methods enabled (false by default).
21
22
  invalid_recovery_code_error_flash :: The flash error to show when an invalid recovery code is used.
22
23
  invalid_recovery_code_message :: The error message to show when an invalid recovery code is used.
23
24
  recovery_auth_additional_form_tags :: HTML fragment containing additional form tags when authenticating via a recovery code.
@@ -0,0 +1,33 @@
1
+ = New Features
2
+
3
+ * An auto_remove_recovery_codes? configuration method has been added
4
+ to the recovery_codes feature. This will automatically remove
5
+ recovery codes when the last multifactor authentication type other
6
+ than the recovery codes has been removed.
7
+
8
+ * The jwt_access_expired_status and expired_jwt_access_token_message
9
+ configuration methods have been added to the jwt_refresh feature,
10
+ for supporting custom statuses and messages for expired tokens.
11
+
12
+ = Other Improvements
13
+
14
+ * Rodauth will no longer attempt to require a feature that has
15
+ already been required. Related to this is you can now use a
16
+ a custom Rodauth feature without a rodauth/features/*.rb file
17
+ in the Ruby library path, as long as you load the feature
18
+ manually.
19
+
20
+ * Rodauth now avoids method redefinition warnings in verbose
21
+ warning mode. As Ruby 3 is dropping uninitialized instance
22
+ variable warnings, Rodauth will be verbose warning free in
23
+ Ruby 3.
24
+
25
+ = Backwards Compatibility
26
+
27
+ * The default remember cookie path is now set to '/'. This fixes
28
+ usage in the case where rodauth is loaded under a subpath of the
29
+ application (which is not the default behavior). Unfortunately,
30
+ this change can negatively affect cases where multiple rodauth
31
+ configurations are used in separate paths on the same domain.
32
+ In these cases, you should now use remember_cookie_options and
33
+ include a :path option.
@@ -35,7 +35,7 @@ raw_remember_token_deadline :: A deadline before which to allow a raw remember t
35
35
  remember_additional_form_tags :: HTML fragment containing additional form tags to use on the change remember setting form.
36
36
  remember_button :: The text to use for the change remember settings button.
37
37
  remember_cookie_key :: The cookie name to use for the remember token.
38
- remember_cookie_options :: Any options to set for the remember cookie.
38
+ remember_cookie_options :: Any options to set for the remember cookie. By default, the `:path` cookie option is set to `/`.
39
39
  remember_deadline_column :: The column name in the +remember_table+ storing the deadline after which the token will be ignored.
40
40
  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
41
  remember_disable_label :: The label for disabling remembering.
@@ -66,6 +66,7 @@ module Rodauth
66
66
  define_method(meth) do |&block|
67
67
  @auth.send(:define_method, meth, &block)
68
68
  @auth.send(:private, meth) if priv
69
+ @auth.send(:alias_method, meth, meth)
69
70
  end
70
71
  end
71
72
 
@@ -74,6 +75,7 @@ module Rodauth
74
75
  define_method(meth) do |&block|
75
76
  @auth.send(:define_method, umeth, &block)
76
77
  @auth.send(:private, umeth)
78
+ @auth.send(:alias_method, umeth, umeth)
77
79
  end
78
80
  end
79
81
 
@@ -82,6 +84,7 @@ module Rodauth
82
84
  block ||= proc{v}
83
85
  @auth.send(:define_method, meth, &block)
84
86
  @auth.send(:private, meth) if priv
87
+ @auth.send(:alias_method, meth, meth)
85
88
  end
86
89
  end
87
90
  end
@@ -240,6 +243,7 @@ module Rodauth
240
243
  instance_variable_set(iv, send(umeth))
241
244
  end
242
245
  end
246
+ alias_method(meth, meth)
243
247
  auth_private_methods(meth)
244
248
  end
245
249
 
@@ -300,7 +304,7 @@ module Rodauth
300
304
  private
301
305
 
302
306
  def load_feature(feature_name)
303
- require "rodauth/features/#{feature_name}"
307
+ require "rodauth/features/#{feature_name}" unless FEATURES[feature_name]
304
308
  feature = FEATURES[feature_name]
305
309
  enable(*feature.dependencies)
306
310
  extend feature.configuration
@@ -102,7 +102,6 @@ module Rodauth
102
102
  :set_redirect_error_flash,
103
103
  :set_title,
104
104
  :translate,
105
- :unverified_account_message,
106
105
  :update_session
107
106
  )
108
107
 
@@ -261,6 +260,7 @@ module Rodauth
261
260
  @password_field_autocomplete_value || 'current-password'
262
261
  end
263
262
 
263
+ alias account_password_hash_column account_password_hash_column
264
264
  # If the account_password_hash_column is set, the password hash is verified in
265
265
  # ruby, it will not use a database function to do so, it will check the password
266
266
  # hash using bcrypt.
@@ -47,7 +47,7 @@ module Rodauth
47
47
  s = {}
48
48
  if jwt_token
49
49
  unless session_data = jwt_payload
50
- json_response[json_response_error_key] = invalid_jwt_format_error_message
50
+ json_response[json_response_error_key] ||= invalid_jwt_format_error_message
51
51
  response.status ||= json_response_error_status
52
52
  response['Content-Type'] ||= json_response_content_type
53
53
  response.write(_json_response_body(json_response))
@@ -236,7 +236,11 @@ module Rodauth
236
236
  def jwt_payload
237
237
  return @jwt_payload if defined?(@jwt_payload)
238
238
  @jwt_payload = JWT.decode(jwt_token, jwt_secret, true, _jwt_decode_opts.merge(:algorithm=>jwt_algorithm))[0]
239
- rescue JWT::DecodeError
239
+ rescue JWT::DecodeError => e
240
+ rescue_jwt_payload(e)
241
+ end
242
+
243
+ def rescue_jwt_payload(_)
240
244
  @jwt_payload = false
241
245
  end
242
246
 
@@ -24,6 +24,8 @@ module Rodauth
24
24
  auth_value_method :jwt_refresh_token_table, :account_jwt_refresh_keys
25
25
  translatable_method :jwt_refresh_without_access_token_message, 'no JWT access token provided during refresh'
26
26
  auth_value_method :jwt_refresh_without_access_token_status, 401
27
+ translatable_method :expired_jwt_access_token_message, "expired JWT access token"
28
+ auth_value_method :expired_jwt_access_token_status, 400
27
29
 
28
30
  auth_private_methods(
29
31
  :account_from_refresh_token
@@ -92,6 +94,23 @@ module Rodauth
92
94
 
93
95
  private
94
96
 
97
+ def rescue_jwt_payload(e)
98
+ if e.instance_of?(JWT::ExpiredSignature)
99
+ begin
100
+ # Some versions of jwt will raise JWT::ExpiredSignature even when the
101
+ # JWT is invalid for other reasons. Make sure the expiration is the
102
+ # only reason the JWT isn't valid before treating this as an expired token.
103
+ JWT.decode(jwt_token, jwt_secret, true, Hash[jwt_decode_opts].merge!(:verify_expiration=>false, :algorithm=>jwt_algorithm))[0]
104
+ rescue => e
105
+ else
106
+ json_response[json_response_error_key] = expired_jwt_access_token_message
107
+ response.status ||= expired_jwt_access_token_status
108
+ end
109
+ end
110
+
111
+ super
112
+ end
113
+
95
114
  def _account_from_refresh_token(token)
96
115
  id, token_id, key = _account_refresh_token_split(token)
97
116
 
@@ -76,9 +76,7 @@ module Rodauth
76
76
  )
77
77
 
78
78
  auth_methods(
79
- :otp,
80
79
  :otp_exists?,
81
- :otp_key,
82
80
  :otp_last_use,
83
81
  :otp_locked_out?,
84
82
  :otp_new_secret,
@@ -34,6 +34,7 @@ module Rodauth
34
34
  auth_value_method :add_recovery_codes_param, 'add'
35
35
  translatable_method :add_recovery_codes_heading, '<h2>Add Additional Recovery Codes</h2>'
36
36
  auth_value_method :auto_add_recovery_codes?, false
37
+ auth_value_method :auto_remove_recovery_codes?, false
37
38
  translatable_method :invalid_recovery_code_message, "Invalid recovery code"
38
39
  auth_value_method :recovery_codes_limit, 16
39
40
  auth_value_method :recovery_codes_column, :code
@@ -56,7 +57,6 @@ module Rodauth
56
57
  :can_add_recovery_codes?,
57
58
  :new_recovery_code,
58
59
  :recovery_code_match?,
59
- :recovery_codes
60
60
  )
61
61
 
62
62
  route(:recovery_auth) do |r|
@@ -213,6 +213,21 @@ module Rodauth
213
213
  super
214
214
  end
215
215
 
216
+ def after_otp_disable
217
+ super if defined?(super)
218
+ auto_remove_recovery_codes
219
+ end
220
+
221
+ def after_sms_disable
222
+ super if defined?(super)
223
+ auto_remove_recovery_codes
224
+ end
225
+
226
+ def after_webauthn_remove
227
+ super if defined?(super)
228
+ auto_remove_recovery_codes
229
+ end
230
+
216
231
  def new_recovery_code
217
232
  random_key
218
233
  end
@@ -227,6 +242,12 @@ module Rodauth
227
242
  end
228
243
  end
229
244
 
245
+ def auto_remove_recovery_codes
246
+ if auto_remove_recovery_codes? && (%w'totp webauthn sms_code' & possible_authentication_methods).empty?
247
+ recovery_codes_remove
248
+ end
249
+ end
250
+
230
251
  def _recovery_codes
231
252
  recovery_codes_ds.select_map(recovery_codes_column)
232
253
  end
@@ -132,11 +132,14 @@ module Rodauth
132
132
  opts = Hash[remember_cookie_options]
133
133
  opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
134
134
  opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
135
+ opts[:path] = "/" unless opts.key?(:path)
135
136
  ::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
136
137
  end
137
138
 
138
139
  def forget_login
139
- ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, remember_cookie_options)
140
+ opts = Hash[remember_cookie_options]
141
+ opts[:path] = "/" unless opts.key?(:path)
142
+ ::Rack::Utils.delete_cookie_header!(response.headers, remember_cookie_key, opts)
140
143
  end
141
144
 
142
145
  def get_remember_key
@@ -47,7 +47,6 @@ module Rodauth
47
47
  :get_verify_account_key,
48
48
  :get_verify_account_email_last_sent,
49
49
  :remove_verify_account_key,
50
- :resend_verify_account_view,
51
50
  :send_verify_account_email,
52
51
  :set_verify_account_email_last_sent,
53
52
  :verify_account,
@@ -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 = 6
9
+ MINOR = 7
10
10
 
11
11
  # The patch version of Rodauth, updated only for bug fixes from the last
12
12
  # feature release.
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.6.0
4
+ version: 2.7.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: 2020-11-20 00:00:00.000000000 Z
11
+ date: 2020-12-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: sequel
@@ -309,6 +309,7 @@ extra_rdoc_files:
309
309
  - doc/release_notes/2.4.0.txt
310
310
  - doc/release_notes/2.5.0.txt
311
311
  - doc/release_notes/2.6.0.txt
312
+ - doc/release_notes/2.7.0.txt
312
313
  files:
313
314
  - CHANGELOG
314
315
  - MIT-LICENSE
@@ -394,6 +395,7 @@ files:
394
395
  - doc/release_notes/2.4.0.txt
395
396
  - doc/release_notes/2.5.0.txt
396
397
  - doc/release_notes/2.6.0.txt
398
+ - doc/release_notes/2.7.0.txt
397
399
  - doc/remember.rdoc
398
400
  - doc/reset_password.rdoc
399
401
  - doc/session_expiration.rdoc