roda 3.80.0 → 3.81.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 +4 -4
- data/CHANGELOG +8 -0
- data/doc/release_notes/3.81.0.txt +24 -0
- data/lib/roda/plugins/assets.rb +3 -1
- data/lib/roda/plugins/exception_page.rb +1 -1
- data/lib/roda/plugins/filter_common_logger.rb +1 -1
- data/lib/roda/plugins/hmac_paths.rb +41 -1
- data/lib/roda/plugins/indifferent_params.rb +0 -3
- data/lib/roda/plugins/not_found.rb +1 -1
- data/lib/roda/plugins/route_csrf.rb +1 -1
- data/lib/roda/plugins/sessions.rb +1 -1
- data/lib/roda/version.rb +1 -1
- metadata +4 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a9d94f31e568bd2774c3e582152f0bcdbffdf3fcd7e5a95241e73b3fd5b7ac3c
|
|
4
|
+
data.tar.gz: b9ad44642acdbaa0035cbd6ece521ca3432d2e7c23d75a331172ecd6c6288c60
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1cd64e84b47a1a7a01d9165d16e14d95d2c43287b58f2557d9492a201832c1388157152eab1fd12052c7691e3969e5ce1cb9c0ad706e73ad6de822dcc29e1590
|
|
7
|
+
data.tar.gz: 86320c603d0c9b90e2c82f16cc5229b76afe66dde5bdbccce9b28ce076e80808a35410098fe0eae5cb3f5b3180b79f4265b3d525e7861a9dd65890315d274fad
|
data/CHANGELOG
CHANGED
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
= 3.81.0 (2024-06-12)
|
|
2
|
+
|
|
3
|
+
* Make assets plugin :early_hints option follow Rack 3 SPEC if using Rack 3 (jeremyevans)
|
|
4
|
+
|
|
5
|
+
* Correctly parse Ruby 3.4 backtraces in exception_page plugin (jeremyevans)
|
|
6
|
+
|
|
7
|
+
* Support :until and :seconds option in hmac_paths plugin, for paths valid only until a specific time (jeremyevans)
|
|
8
|
+
|
|
1
9
|
= 3.80.0 (2024-05-10)
|
|
2
10
|
|
|
3
11
|
* Support :namespace option in hmac_paths plugin, allowing for easy per-user/per-group HMAC paths (jeremyevans)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
= New Features
|
|
2
|
+
|
|
3
|
+
* The hmac_paths plugin now supports :until and :seconds options for
|
|
4
|
+
hmac_path, to create a path that is only valid for a specific amount of
|
|
5
|
+
time. :until sets a specific time that the path will be valid until,
|
|
6
|
+
and :seconds makes the path only valid for the given number of seconds.
|
|
7
|
+
|
|
8
|
+
hmac_path('/widget/1', until: Time.utc(2100))
|
|
9
|
+
# => "/dc8b6e56e4cbe7815df7880d42f0e02956b2e4c49881b6060ceb0e49745a540d/t/4102444800/widget/1"
|
|
10
|
+
|
|
11
|
+
Requests for the path after the given time will not be matched by
|
|
12
|
+
r.hmac_path.
|
|
13
|
+
|
|
14
|
+
= Other Improvements
|
|
15
|
+
|
|
16
|
+
* The early_hints plugin now correctly follows the Rack 3 SPEC when
|
|
17
|
+
using Rack 3. This was not caught previously because Rack only
|
|
18
|
+
added official support for early_hints in the last month.
|
|
19
|
+
|
|
20
|
+
* Ruby 3.4 backtraces are now parsed correctly in the exception_page
|
|
21
|
+
plugin.
|
|
22
|
+
|
|
23
|
+
* Some plugins that accept a block no longer issue an unused block
|
|
24
|
+
warning on Ruby 3.4.
|
data/lib/roda/plugins/assets.rb
CHANGED
|
@@ -736,7 +736,9 @@ class Roda
|
|
|
736
736
|
paths = assets_paths(type)
|
|
737
737
|
if o[:early_hints]
|
|
738
738
|
early_hint_as = ltype == :js ? 'script' : 'style'
|
|
739
|
-
|
|
739
|
+
early_hints = paths.map{|p| "<#{p}>; rel=preload; as=#{early_hint_as}"}
|
|
740
|
+
early_hints = early_hints.join("\n") if Rack.release < '3'
|
|
741
|
+
send_early_hints(RodaResponseHeaders::LINK=>early_hints)
|
|
740
742
|
end
|
|
741
743
|
paths.map{|p| "#{tag_start}#{h(p)}#{tag_end}"}.join("\n")
|
|
742
744
|
end
|
|
@@ -245,7 +245,7 @@ END
|
|
|
245
245
|
|
|
246
246
|
frames = exception.backtrace.map.with_index do |line, i|
|
|
247
247
|
frame = {:id=>i}
|
|
248
|
-
if line =~ /\A(.*?):(\d+)(?::in `(.*)')?\Z/
|
|
248
|
+
if line =~ /\A(.*?):(\d+)(?::in [`'](.*)')?\Z/
|
|
249
249
|
filename = frame[:filename] = $1
|
|
250
250
|
lineno = frame[:lineno] = $2.to_i
|
|
251
251
|
frame[:function] = $3
|
|
@@ -112,6 +112,16 @@ class Roda
|
|
|
112
112
|
# this for POST requests (or other HTTP verbs that can have request bodies), use +r.GET+
|
|
113
113
|
# instead of +r.params+ to specifically check query string parameters.
|
|
114
114
|
#
|
|
115
|
+
# The generated paths can be timestamped, so that they are only valid until a given time
|
|
116
|
+
# or for a given number of seconds after they are generated, using the :until or :seconds
|
|
117
|
+
# options:
|
|
118
|
+
#
|
|
119
|
+
# hmac_path('/widget/1', until: Time.utc(2100))
|
|
120
|
+
# # => "/dc8b6e56e4cbe7815df7880d42f0e02956b2e4c49881b6060ceb0e49745a540d/t/4102444800/widget/1"
|
|
121
|
+
#
|
|
122
|
+
# hmac_path('/widget/1', seconds: Time.utc(2100).to_i - Time.now.to_i)
|
|
123
|
+
# # => "/dc8b6e56e4cbe7815df7880d42f0e02956b2e4c49881b6060ceb0e49745a540d/t/4102444800/widget/1"
|
|
124
|
+
#
|
|
115
125
|
# The :namespace option, if provided, should be a string, and it modifies the generated HMACs
|
|
116
126
|
# to only match those in the same namespace. This can be used to provide different paths to
|
|
117
127
|
# different users or groups of users.
|
|
@@ -190,6 +200,11 @@ class Roda
|
|
|
190
200
|
# r.hmac_path('/1', params: {k: 2})
|
|
191
201
|
# HMAC_hex(HMAC_hex(secret, ''), '/p/1?k=2')
|
|
192
202
|
#
|
|
203
|
+
# The +:until+ and +:seconds+ option include the timestamp in the HMAC:
|
|
204
|
+
#
|
|
205
|
+
# r.hmac_path('/1', until: Time.utc(2100))
|
|
206
|
+
# HMAC_hex(HMAC_hex(secret, ''), '/t/4102444800/1')
|
|
207
|
+
#
|
|
193
208
|
# If a +:namespace+ option is provided, the original secret used before the +:root+ option is
|
|
194
209
|
# an HMAC of the +:secret+ plugin option and the given namespace.
|
|
195
210
|
#
|
|
@@ -232,6 +247,8 @@ class Roda
|
|
|
232
247
|
# the already matched path of the routing tree using r.hmac_path. Defaults
|
|
233
248
|
# to the empty string, which will returns paths valid for r.hmac_path at
|
|
234
249
|
# the top level of the routing tree.
|
|
250
|
+
# :seconds :: Make the given path valid for the given integer number of seconds.
|
|
251
|
+
# :until :: Make the given path valid until the given Time.
|
|
235
252
|
def hmac_path(path, opts=OPTS)
|
|
236
253
|
unless path.is_a?(String) && path.getbyte(0) == 47
|
|
237
254
|
raise RodaError, "path must be a string starting with /"
|
|
@@ -242,6 +259,12 @@ class Roda
|
|
|
242
259
|
raise RodaError, "root must be empty string or string starting with /"
|
|
243
260
|
end
|
|
244
261
|
|
|
262
|
+
if valid_until = opts[:until]
|
|
263
|
+
valid_until = valid_until.to_i
|
|
264
|
+
elsif seconds = opts[:seconds]
|
|
265
|
+
valid_until = Time.now.to_i + seconds
|
|
266
|
+
end
|
|
267
|
+
|
|
245
268
|
flags = String.new
|
|
246
269
|
path = path.dup
|
|
247
270
|
|
|
@@ -258,6 +281,11 @@ class Roda
|
|
|
258
281
|
flags << 'n'
|
|
259
282
|
end
|
|
260
283
|
|
|
284
|
+
if valid_until
|
|
285
|
+
flags << 't'
|
|
286
|
+
path = "/#{valid_until}#{path}"
|
|
287
|
+
end
|
|
288
|
+
|
|
261
289
|
flags << '0' if flags.empty?
|
|
262
290
|
|
|
263
291
|
hmac_path = if method
|
|
@@ -335,7 +363,19 @@ class Roda
|
|
|
335
363
|
end
|
|
336
364
|
|
|
337
365
|
if hmac_path_valid?(mpath, rpath, submitted_hmac, opts)
|
|
338
|
-
|
|
366
|
+
if flags.include?('t')
|
|
367
|
+
on Integer do |int|
|
|
368
|
+
if int >= Time.now.to_i
|
|
369
|
+
always(&block)
|
|
370
|
+
else
|
|
371
|
+
# Return from method without matching
|
|
372
|
+
@remaining_path = orig_path
|
|
373
|
+
return
|
|
374
|
+
end
|
|
375
|
+
end
|
|
376
|
+
else
|
|
377
|
+
always(&block)
|
|
378
|
+
end
|
|
339
379
|
end
|
|
340
380
|
end
|
|
341
381
|
|
|
@@ -53,13 +53,10 @@ class Roda
|
|
|
53
53
|
|
|
54
54
|
class Params < Rack::QueryParser::Params
|
|
55
55
|
if Rack.release >= '3'
|
|
56
|
-
# rack main branch compatibility
|
|
57
|
-
# :nocov:
|
|
58
56
|
if Params < Hash
|
|
59
57
|
def initialize
|
|
60
58
|
super(&INDIFFERENT_PROC)
|
|
61
59
|
end
|
|
62
|
-
# :nocov:
|
|
63
60
|
else
|
|
64
61
|
def initialize
|
|
65
62
|
@size = 0
|
|
@@ -476,7 +476,7 @@ class Roda
|
|
|
476
476
|
serialized_data << json_data
|
|
477
477
|
|
|
478
478
|
cipher_secret = opts[:cipher_secret]
|
|
479
|
-
if
|
|
479
|
+
if opts[:per_cookie_cipher_secret]
|
|
480
480
|
version = "\1"
|
|
481
481
|
per_cookie_secret_base = SecureRandom.random_bytes(32)
|
|
482
482
|
cipher_secret = OpenSSL::HMAC.digest(OpenSSL::Digest::SHA256.new, cipher_secret, per_cookie_secret_base)
|
data/lib/roda/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: roda
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.81.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: 2024-
|
|
11
|
+
date: 2024-06-12 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rack
|
|
@@ -255,6 +255,7 @@ extra_rdoc_files:
|
|
|
255
255
|
- doc/release_notes/3.79.0.txt
|
|
256
256
|
- doc/release_notes/3.8.0.txt
|
|
257
257
|
- doc/release_notes/3.80.0.txt
|
|
258
|
+
- doc/release_notes/3.81.0.txt
|
|
258
259
|
- doc/release_notes/3.9.0.txt
|
|
259
260
|
files:
|
|
260
261
|
- CHANGELOG
|
|
@@ -342,6 +343,7 @@ files:
|
|
|
342
343
|
- doc/release_notes/3.79.0.txt
|
|
343
344
|
- doc/release_notes/3.8.0.txt
|
|
344
345
|
- doc/release_notes/3.80.0.txt
|
|
346
|
+
- doc/release_notes/3.81.0.txt
|
|
345
347
|
- doc/release_notes/3.9.0.txt
|
|
346
348
|
- lib/roda.rb
|
|
347
349
|
- lib/roda/cache.rb
|