rodauth 2.22.0 → 2.25.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +24 -0
- data/README.rdoc +9 -3
- data/doc/guides/paths.rdoc +12 -0
- data/doc/otp.rdoc +1 -0
- data/doc/recovery_codes.rdoc +1 -0
- data/doc/release_notes/2.23.0.txt +15 -0
- data/doc/release_notes/2.24.0.txt +15 -0
- data/doc/release_notes/2.25.0.txt +8 -0
- data/lib/rodauth/features/base.rb +12 -1
- data/lib/rodauth/features/http_basic_auth.rb +1 -1
- data/lib/rodauth/features/internal_request.rb +1 -1
- data/lib/rodauth/features/json.rb +2 -4
- data/lib/rodauth/features/jwt_cors.rb +1 -1
- data/lib/rodauth/features/lockout.rb +1 -2
- data/lib/rodauth/features/otp.rb +8 -2
- data/lib/rodauth/features/recovery_codes.rb +6 -1
- data/lib/rodauth/features/remember.rb +1 -1
- data/lib/rodauth/features/reset_password.rb +4 -4
- data/lib/rodauth/features/sms_codes.rb +2 -2
- data/lib/rodauth/features/verify_account.rb +2 -4
- data/lib/rodauth/version.rb +1 -1
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 934d5c19d29c583ebc73a057ba96a1c321741a64c965b22f4a243a42f56eab81
|
4
|
+
data.tar.gz: 6398ec3d3bc1ee36a2195909b545ba5df9f0282c5a5b9136babb3538f21cb98e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 32bae60cf66d97326397f3429d74ac2e7093afae74c59191bba5013ad6c7ec46782ddfa54c0a28b9a68c38cbf52b7e5071cd9d4eb7e434e5632c70842658120c
|
7
|
+
data.tar.gz: b157ffa28b3f539c7618d747ab8cee321de6fbfdac11c603176b325ce54d10294a9b8860715a27c08e7d6128928e78d51e8f776b0201fcadec99075354c32f51
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
=== 2.25.0 (2022-06-22)
|
2
|
+
|
3
|
+
* Support disabling routes by passing nil/false to *_route methods (janko) (#245)
|
4
|
+
|
5
|
+
=== 2.24.0 (2022-05-24)
|
6
|
+
|
7
|
+
* Work around implicit null byte check added in bcrypt 3.1.18 by checking password requirements before other password checks (jeremyevans)
|
8
|
+
|
9
|
+
* Fix invalid HTML on pages with OTP QR codes (jeremyevans)
|
10
|
+
|
11
|
+
* Add recovery_codes_available? configuration method to the recovery_codes feature (janko) (#238)
|
12
|
+
|
13
|
+
* Add otp_available? configuration method to the otp feature (janko) (#238)
|
14
|
+
|
15
|
+
=== 2.23.0 (2022-04-22)
|
16
|
+
|
17
|
+
* Don't automatically set :httponly cookie option if :http_only option is set in remember feature (jeremyevans)
|
18
|
+
|
19
|
+
* Fix invalid domain check in internal_request feature when using Rack 3 (jeremyevans)
|
20
|
+
|
21
|
+
* Make removing all multifactor authentication methods mark session as not authenticated by SMS (janko) (#235)
|
22
|
+
|
23
|
+
* Use use_path option when rendering QR code to svg in the otp feature, to reduce svg size (jeremyevans)
|
24
|
+
|
1
25
|
=== 2.22.0 (2022-03-22)
|
2
26
|
|
3
27
|
* Ignore parameters where the value includes a null byte by default, add null_byte_parameter_value configuration method for customization (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -1294,6 +1294,12 @@ By setting <tt>env['rodauth'] = rodauth</tt> in the route block
|
|
1294
1294
|
inside the middleware, you can easily provide a way for your
|
1295
1295
|
application to call Rodauth methods.
|
1296
1296
|
|
1297
|
+
If you're using the remember feature with +extend_remember_deadline?+ set to
|
1298
|
+
true, you'll want to load roda's middleware plugin with
|
1299
|
+
+forward_response_headers: true+ option, so that +Set-Cookie+ header changes
|
1300
|
+
from the +load_memory+ call in the route block are propagated when the request
|
1301
|
+
is forwarded to the main app.
|
1302
|
+
|
1297
1303
|
Here are some examples of integrating Rodauth into applications that
|
1298
1304
|
don't use Roda:
|
1299
1305
|
|
@@ -1495,9 +1501,9 @@ required to run the current version of Rodauth is 1.9.2.
|
|
1495
1501
|
|
1496
1502
|
All of these are Rails-specific:
|
1497
1503
|
|
1498
|
-
* Devise
|
1499
|
-
* Authlogic
|
1500
|
-
* Sorcery
|
1504
|
+
* {Devise}[https://github.com/heartcombo/devise]
|
1505
|
+
* {Authlogic}[https://github.com/binarylogic/authlogic]
|
1506
|
+
* {Sorcery}[https://github.com/Sorcery/sorcery]
|
1501
1507
|
|
1502
1508
|
== Author
|
1503
1509
|
|
data/doc/guides/paths.rdoc
CHANGED
@@ -37,3 +37,15 @@ setting:
|
|
37
37
|
|
38
38
|
# ...
|
39
39
|
end
|
40
|
+
|
41
|
+
There are cases where you may want to disable certain routes. For example, you
|
42
|
+
may want to enable the create_account feature to allow creating admins, but
|
43
|
+
only make it possible programmatically via internal requests. In this case,
|
44
|
+
you should set the corresponding <tt>*_route</tt> method to +nil+:
|
45
|
+
|
46
|
+
plugin :rodauth, name: :admin do
|
47
|
+
enable :create_account
|
48
|
+
|
49
|
+
# disable the /create-account route
|
50
|
+
create_account_route nil
|
51
|
+
end
|
data/doc/otp.rdoc
CHANGED
@@ -70,6 +70,7 @@ before_otp_setup_route :: Run arbitrary code before handling an OTP authenticati
|
|
70
70
|
otp :: The object used for verifying OTP authentication attempts.
|
71
71
|
otp_add_key(secret) :: Add an OTP key for the current account with the given secret.
|
72
72
|
otp_auth_view :: The HTML to use for the OTP authentication form.
|
73
|
+
otp_available? :: Whether OTP authentication is ready for use.
|
73
74
|
otp_disable_view :: The HTML to use for the OTP disable form.
|
74
75
|
otp_exists? :: Whether the current account has setup OTP.
|
75
76
|
otp_key :: The stored OTP secret for the account.
|
data/doc/recovery_codes.rdoc
CHANGED
@@ -57,4 +57,5 @@ new_recovery_code :: A new recovery code to insert into the recovery codes table
|
|
57
57
|
recovery_auth_view :: The HTML to use for the form to authenticate via a recovery code.
|
58
58
|
recovery_code_match?(code) :: Whether the given code matches any of the existing recovery_codes.
|
59
59
|
recovery_codes :: An array containing all valid recovery codes for the current account.
|
60
|
+
recovery_codes_available? :: Whether authentication via recovery codes is ready for use.
|
60
61
|
recovery_codes_view :: The HTML to use for the form to view recovery codes.
|
@@ -0,0 +1,15 @@
|
|
1
|
+
= Improvements
|
2
|
+
|
3
|
+
* The otp feature now uses the :use_path option when rendering QR
|
4
|
+
codes, resulting in significantly smaller svg images.
|
5
|
+
|
6
|
+
* Removing all multifactor authentication methods now removes the fact
|
7
|
+
that the session was authenticated via SMS, if the user used SMS as
|
8
|
+
an authentication method for the current session.
|
9
|
+
|
10
|
+
* The invalid domain check in the internal_request feature now works
|
11
|
+
correctly when using the rack master branch.
|
12
|
+
|
13
|
+
* The :httponly cookie option is no longer set automatically in the
|
14
|
+
remember feature if the :http_only cookie option was provided by the
|
15
|
+
user (rack recognizes both options).
|
@@ -0,0 +1,15 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* rodauth.otp_available? has been added for checking whether the
|
4
|
+
account is allowed to authenticate with OTP. It returns true
|
5
|
+
when the account has setup OTP and OTP use is not locked out.
|
6
|
+
|
7
|
+
* rodauth.recovery_codes_available? has been added for checking
|
8
|
+
whether the account is allowed to authenticate using a recovery
|
9
|
+
code. It returns true when there are any available recovery
|
10
|
+
codes for the account to use.
|
11
|
+
|
12
|
+
= Other Improvements
|
13
|
+
|
14
|
+
* The otp feature no longer includes the <?xml> tag for svg images,
|
15
|
+
since that results in invalid HTML.
|
@@ -0,0 +1,8 @@
|
|
1
|
+
= New Features
|
2
|
+
|
3
|
+
* You can now disable routing to specific routes by calling the
|
4
|
+
related *_route configuration method with nil or false. The main
|
5
|
+
reason you would want to do this is if you want to load a feature,
|
6
|
+
but only want to use it for internal requests (using the
|
7
|
+
internal_request feature), and not have the feature's routes exposed
|
8
|
+
to users.
|
@@ -1,5 +1,8 @@
|
|
1
1
|
# frozen-string-literal: true
|
2
2
|
|
3
|
+
require 'rack/request'
|
4
|
+
require 'rack/utils'
|
5
|
+
|
3
6
|
module Rodauth
|
4
7
|
Feature.define(:base, :Base) do
|
5
8
|
after 'login'
|
@@ -399,7 +402,10 @@ module Rodauth
|
|
399
402
|
db.extension :date_arithmetic if use_date_arithmetic?
|
400
403
|
route_hash= {}
|
401
404
|
self.class.routes.each do |meth|
|
402
|
-
|
405
|
+
route_meth = "#{meth.to_s.sub(/\Ahandle_/, '')}_route"
|
406
|
+
if route = send(route_meth)
|
407
|
+
route_hash["/#{route}"] = meth
|
408
|
+
end
|
403
409
|
end
|
404
410
|
self.class.route_hash = route_hash.freeze
|
405
411
|
end
|
@@ -511,6 +517,11 @@ module Rodauth
|
|
511
517
|
request.redirect(path)
|
512
518
|
end
|
513
519
|
|
520
|
+
def return_response(body=nil)
|
521
|
+
response.write(body) if body
|
522
|
+
request.halt
|
523
|
+
end
|
524
|
+
|
514
525
|
def route_path(route, opts={})
|
515
526
|
path = "#{prefix}/#{route}"
|
516
527
|
path += "?#{Rack::Utils.build_nested_query(opts)}" unless opts.empty?
|
@@ -156,8 +156,7 @@ module Rodauth
|
|
156
156
|
end
|
157
157
|
elsif only_json?
|
158
158
|
response.status = json_response_error_status
|
159
|
-
|
160
|
-
request.halt
|
159
|
+
return_response non_json_request_error_message
|
161
160
|
end
|
162
161
|
|
163
162
|
super
|
@@ -175,8 +174,7 @@ module Rodauth
|
|
175
174
|
def _return_json_response
|
176
175
|
response.status ||= json_response_error_status if json_response[json_response_error_key]
|
177
176
|
response['Content-Type'] ||= json_response_content_type
|
178
|
-
|
179
|
-
request.halt
|
177
|
+
return_response _json_response_body(json_response)
|
180
178
|
end
|
181
179
|
|
182
180
|
def include_success_messages?
|
@@ -41,7 +41,7 @@ module Rodauth
|
|
41
41
|
response['Access-Control-Allow-Headers'] = jwt_cors_allow_headers
|
42
42
|
response['Access-Control-Max-Age'] = jwt_cors_max_age.to_s
|
43
43
|
response.status = 204
|
44
|
-
|
44
|
+
return_response
|
45
45
|
end
|
46
46
|
|
47
47
|
response['Access-Control-Expose-Headers'] = jwt_cors_expose_headers
|
@@ -277,8 +277,7 @@ module Rodauth
|
|
277
277
|
def show_lockout_page
|
278
278
|
set_response_error_reason_status(:account_locked_out, lockout_error_status)
|
279
279
|
set_error_flash login_lockout_error_flash
|
280
|
-
|
281
|
-
request.halt
|
280
|
+
return_response unlock_account_request_view
|
282
281
|
end
|
283
282
|
|
284
283
|
def unlock_account_email_recently_sent?
|
data/lib/rodauth/features/otp.rb
CHANGED
@@ -76,6 +76,7 @@ module Rodauth
|
|
76
76
|
)
|
77
77
|
|
78
78
|
auth_methods(
|
79
|
+
:otp_available?,
|
79
80
|
:otp_exists?,
|
80
81
|
:otp_last_use,
|
81
82
|
:otp_locked_out?,
|
@@ -238,6 +239,10 @@ module Rodauth
|
|
238
239
|
end
|
239
240
|
end
|
240
241
|
|
242
|
+
def otp_available?
|
243
|
+
otp_exists? && !otp_locked_out?
|
244
|
+
end
|
245
|
+
|
241
246
|
def otp_exists?
|
242
247
|
!otp_key.nil?
|
243
248
|
end
|
@@ -303,7 +308,8 @@ module Rodauth
|
|
303
308
|
end
|
304
309
|
|
305
310
|
def otp_qr_code
|
306
|
-
RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true)
|
311
|
+
svg = RQRCode::QRCode.new(otp_provisioning_uri).as_svg(:module_size=>8, :viewbox=>true, :use_path=>true)
|
312
|
+
svg.sub(/\A<\?xml version="1\.0" standalone="yes"\?>/, '')
|
307
313
|
end
|
308
314
|
|
309
315
|
def otp_user_key
|
@@ -328,7 +334,7 @@ module Rodauth
|
|
328
334
|
|
329
335
|
def _two_factor_auth_links
|
330
336
|
links = super
|
331
|
-
links << [20, otp_auth_path, otp_auth_link_text] if
|
337
|
+
links << [20, otp_auth_path, otp_auth_link_text] if otp_available?
|
332
338
|
links
|
333
339
|
end
|
334
340
|
|
@@ -57,6 +57,7 @@ module Rodauth
|
|
57
57
|
:can_add_recovery_codes?,
|
58
58
|
:new_recovery_code,
|
59
59
|
:recovery_code_match?,
|
60
|
+
:recovery_codes_available?,
|
60
61
|
)
|
61
62
|
|
62
63
|
internal_request_method :recovery_codes
|
@@ -192,6 +193,10 @@ module Rodauth
|
|
192
193
|
end
|
193
194
|
end
|
194
195
|
|
196
|
+
def recovery_codes_available?
|
197
|
+
!recovery_codes_ds.empty?
|
198
|
+
end
|
199
|
+
|
195
200
|
def possible_authentication_methods
|
196
201
|
methods = super
|
197
202
|
methods << 'recovery_code' unless recovery_codes_ds.empty?
|
@@ -202,7 +207,7 @@ module Rodauth
|
|
202
207
|
|
203
208
|
def _two_factor_auth_links
|
204
209
|
links = super
|
205
|
-
links << [40, recovery_auth_path, recovery_auth_link_text]
|
210
|
+
links << [40, recovery_auth_path, recovery_auth_link_text] if recovery_codes_available?
|
206
211
|
links
|
207
212
|
end
|
208
213
|
|
@@ -144,7 +144,7 @@ module Rodauth
|
|
144
144
|
opts[:value] = "#{account_id}_#{convert_token_key(remember_key_value)}"
|
145
145
|
opts[:expires] = convert_timestamp(active_remember_key_ds.get(remember_deadline_column))
|
146
146
|
opts[:path] = "/" unless opts.key?(:path)
|
147
|
-
opts[:httponly] = true unless opts.key?(:httponly)
|
147
|
+
opts[:httponly] = true unless opts.key?(:httponly) || opts.key?(:http_only)
|
148
148
|
opts[:secure] = true unless opts.key?(:secure) || !request.ssl?
|
149
149
|
::Rack::Utils.set_cookie_header!(response.headers, remember_cookie_key, opts)
|
150
150
|
end
|
@@ -130,6 +130,10 @@ module Rodauth
|
|
130
130
|
|
131
131
|
password = param(password_param)
|
132
132
|
catch_error do
|
133
|
+
unless password_meets_requirements?(password)
|
134
|
+
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
|
135
|
+
end
|
136
|
+
|
133
137
|
if password_match?(password)
|
134
138
|
throw_error_reason(:same_as_existing_password, invalid_field_error_status, password_param, same_as_existing_password_message)
|
135
139
|
end
|
@@ -138,10 +142,6 @@ module Rodauth
|
|
138
142
|
throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
|
139
143
|
end
|
140
144
|
|
141
|
-
unless password_meets_requirements?(password)
|
142
|
-
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
|
143
|
-
end
|
144
|
-
|
145
145
|
transaction do
|
146
146
|
before_reset_password
|
147
147
|
set_password(password)
|
@@ -430,7 +430,7 @@ module Rodauth
|
|
430
430
|
end
|
431
431
|
|
432
432
|
def sms_available?
|
433
|
-
|
433
|
+
sms_setup? && !sms_locked_out?
|
434
434
|
end
|
435
435
|
|
436
436
|
def sms_locked_out?
|
@@ -468,7 +468,7 @@ module Rodauth
|
|
468
468
|
end
|
469
469
|
|
470
470
|
def _two_factor_remove_all_from_session
|
471
|
-
two_factor_remove_session('
|
471
|
+
two_factor_remove_session('sms_code')
|
472
472
|
super
|
473
473
|
end
|
474
474
|
|
@@ -195,8 +195,7 @@ module Rodauth
|
|
195
195
|
if account_from_login(login) && allow_resending_verify_account_email?
|
196
196
|
set_response_error_reason_status(:already_an_unverified_account_with_this_login, unopen_account_error_status)
|
197
197
|
set_error_flash attempt_to_create_unverified_account_error_flash
|
198
|
-
|
199
|
-
request.halt
|
198
|
+
return_response resend_verify_account_view
|
200
199
|
end
|
201
200
|
super
|
202
201
|
end
|
@@ -268,8 +267,7 @@ module Rodauth
|
|
268
267
|
unless open_account?
|
269
268
|
set_response_error_reason_status(:unverified_account, unopen_account_error_status)
|
270
269
|
set_error_flash attempt_to_login_to_unverified_account_error_flash
|
271
|
-
|
272
|
-
request.halt
|
270
|
+
return_response resend_verify_account_view
|
273
271
|
end
|
274
272
|
super
|
275
273
|
end
|
data/lib/rodauth/version.rb
CHANGED
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.
|
4
|
+
version: 2.25.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: 2022-
|
11
|
+
date: 2022-06-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: sequel
|
@@ -338,6 +338,9 @@ extra_rdoc_files:
|
|
338
338
|
- doc/release_notes/2.20.0.txt
|
339
339
|
- doc/release_notes/2.21.0.txt
|
340
340
|
- doc/release_notes/2.22.0.txt
|
341
|
+
- doc/release_notes/2.23.0.txt
|
342
|
+
- doc/release_notes/2.24.0.txt
|
343
|
+
- doc/release_notes/2.25.0.txt
|
341
344
|
- doc/release_notes/2.3.0.txt
|
342
345
|
- doc/release_notes/2.4.0.txt
|
343
346
|
- doc/release_notes/2.5.0.txt
|
@@ -447,6 +450,9 @@ files:
|
|
447
450
|
- doc/release_notes/2.20.0.txt
|
448
451
|
- doc/release_notes/2.21.0.txt
|
449
452
|
- doc/release_notes/2.22.0.txt
|
453
|
+
- doc/release_notes/2.23.0.txt
|
454
|
+
- doc/release_notes/2.24.0.txt
|
455
|
+
- doc/release_notes/2.25.0.txt
|
450
456
|
- doc/release_notes/2.3.0.txt
|
451
457
|
- doc/release_notes/2.4.0.txt
|
452
458
|
- doc/release_notes/2.5.0.txt
|
@@ -573,13 +579,13 @@ files:
|
|
573
579
|
- templates/webauthn-auth.str
|
574
580
|
- templates/webauthn-remove.str
|
575
581
|
- templates/webauthn-setup.str
|
576
|
-
homepage: https://
|
582
|
+
homepage: https://rodauth.jeremyevans.net
|
577
583
|
licenses:
|
578
584
|
- MIT
|
579
585
|
metadata:
|
580
586
|
bug_tracker_uri: https://github.com/jeremyevans/rodauth/issues
|
581
|
-
changelog_uri:
|
582
|
-
documentation_uri:
|
587
|
+
changelog_uri: https://rodauth.jeremyevans.net/rdoc/files/CHANGELOG.html
|
588
|
+
documentation_uri: https://rodauth.jeremyevans.net/documentation.html
|
583
589
|
mailing_list_uri: https://github.com/jeremyevans/rodauth/discussions
|
584
590
|
source_code_uri: https://github.com/jeremyevans/rodauth
|
585
591
|
post_install_message:
|