rodauth 2.6.0 → 2.7.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: 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