forme 2.4.1 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +8 -0
- data/README.rdoc +18 -2
- data/lib/forme/template.rb +4 -4
- data/lib/forme/transformers/formatter.rb +6 -0
- data/lib/forme/version.rb +2 -2
- data/lib/roda/plugins/forme_erubi_capture.rb +2 -2
- data/lib/roda/plugins/forme_route_csrf.rb +18 -1
- data/lib/roda/plugins/forme_set.rb +14 -1
- data/lib/sequel/plugins/forme.rb +16 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 79c0b3986af69becb74de866d9027eafb1af2b148056c60963e8c8c6af04ad3d
|
4
|
+
data.tar.gz: 8478ef6951317b7a33bf7c3b2630291bcd94bb94fcbb2820ef89d08c0addfaec
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c63cedc392288fba47d26da036ed2ad145acf4493683600cbad71238f66fd61dfeb91cadc1db68ab2211ff3cf6cd69622f17934f9ea0be4e4006a53c2baa0a07
|
7
|
+
data.tar.gz: ef4a1d7b5bfdd0dc83d5f52b87f8dbc0785f03ccdfdb8d7e1bdfe160e85636fc2165fae7916489c8d22ba082293a64b3e0a466c67e4a4fe3a90726f4d228ffb1
|
data/CHANGELOG
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
=== 2.5.0 (2024-02-13)
|
2
|
+
|
3
|
+
* Add hidden inputs to work with formaction/formmethod support in Roda 3.77+ route_csrf plugin (jeremyevans)
|
4
|
+
|
5
|
+
* Support :formaction option on buttons (jeremyevans)
|
6
|
+
|
7
|
+
* Support emit: false option for non-rails template forms allowing block based form use without appending to template (jeremyevans)
|
8
|
+
|
1
9
|
=== 2.4.1 (2023-09-19)
|
2
10
|
|
3
11
|
* Add dependency on bigdecimal, as bigdecimal is moving from standard library to bundled gem in Ruby 3.4 (jeremyevans)
|
data/README.rdoc
CHANGED
@@ -800,7 +800,7 @@ For new code, it is recommended to use forme_route_csrf, as that uses Roda's rou
|
|
800
800
|
plugin, which supports more secure request-specific CSRF tokens. In both cases, usage in ERB
|
801
801
|
templates is the same:
|
802
802
|
|
803
|
-
<% form(@obj, :
|
803
|
+
<% form(@obj, action: '/foo') do |f| %>
|
804
804
|
<%= f.input(:field) %>
|
805
805
|
<% f.tag(:fieldset) do %>
|
806
806
|
<%= f.input(:field_two) %>
|
@@ -810,6 +810,8 @@ templates is the same:
|
|
810
810
|
The forme_route_csrf plugin's +form+ method supports the following options
|
811
811
|
in addition to the default +Forme.form+ options:
|
812
812
|
|
813
|
+
:emit :: Set to false to not emit implicit tags into template. This should only be
|
814
|
+
used if you are not modifying the template inside the block.
|
813
815
|
:csrf :: Set to force whether a CSRF tag should be included. By default, a CSRF
|
814
816
|
tag is included if the form's method is one of the request methods checked
|
815
817
|
by the Roda route_csrf plugin.
|
@@ -818,6 +820,19 @@ in addition to the default +Forme.form+ options:
|
|
818
820
|
CSRF token unless the Roda route_csrf plugin has been
|
819
821
|
configured to support non-request specific tokens.
|
820
822
|
|
823
|
+
The <tt>emit: false</tt> option allows you to do:
|
824
|
+
|
825
|
+
<%= form(@obj, {action: '/foo'}, emit: false) do |f|
|
826
|
+
f.input(:field)
|
827
|
+
f.tag(:fieldset) do
|
828
|
+
f.input(:field_two)
|
829
|
+
end
|
830
|
+
end %>
|
831
|
+
|
832
|
+
This is useful if you are calling some method that calls +form+ with a block,
|
833
|
+
where the resulting entire Forme::Forme object will be literalized into the
|
834
|
+
template. The form will include the CSRF token and forme_set metadata as appropriate.
|
835
|
+
|
821
836
|
The forme plugin does not require any csrf plugin, but will transparently use
|
822
837
|
Rack::Csrf if it is available. If Rack::Csrf is available a CSRF tag if the form's
|
823
838
|
method is +POST+, with no configuration ability.
|
@@ -856,7 +871,8 @@ It allows you to use the following API in your erb templates:
|
|
856
871
|
<% end %>
|
857
872
|
|
858
873
|
In order to this to work transparently, the ERB outvar needs to be <tt>@_out_buf</tt> (this is the
|
859
|
-
default in Sinatra).
|
874
|
+
default in Sinatra). The Sinatra extension also supports the <tt>emit: false</tt> option to not
|
875
|
+
directly modify the related template (see example in the Roda section for usage).
|
860
876
|
|
861
877
|
= Rails Support
|
862
878
|
|
data/lib/forme/template.rb
CHANGED
@@ -72,9 +72,9 @@ module Forme
|
|
72
72
|
private
|
73
73
|
|
74
74
|
def _forme_form(obj, attr, opts, &block)
|
75
|
-
if
|
75
|
+
if block && opts[:emit] != false
|
76
76
|
erb_form = buffer = offset = nil
|
77
|
-
|
77
|
+
form_block = proc do
|
78
78
|
wrapped_form = erb_form.instance_variable_get(:@form)
|
79
79
|
buffer = wrapped_form.to_s
|
80
80
|
offset = buffer.length
|
@@ -83,9 +83,9 @@ module Forme
|
|
83
83
|
offset = buffer.length
|
84
84
|
end
|
85
85
|
|
86
|
-
f, attr,
|
86
|
+
f, attr, form_block = _forme_wrapped_form_class.form_args(obj, attr, opts, &form_block)
|
87
87
|
erb_form = _forme_form_class.new(f, self)
|
88
|
-
erb_form.form(attr, &
|
88
|
+
erb_form.form(attr, &form_block)
|
89
89
|
erb_form.emit(buffer[offset, buffer.length])
|
90
90
|
else
|
91
91
|
_forme_wrapped_form_class.form(obj, attr, opts, &block)
|
@@ -268,6 +268,12 @@ module Forme
|
|
268
268
|
ret
|
269
269
|
end
|
270
270
|
|
271
|
+
# Formats a submit input. Respects :formaction option.
|
272
|
+
def format_submit
|
273
|
+
copy_options_to_attributes([:formaction])
|
274
|
+
_format_input(:submit)
|
275
|
+
end
|
276
|
+
|
271
277
|
# Formats a textarea. Respects the following options:
|
272
278
|
# :value :: Sets value as the child of the textarea.
|
273
279
|
def format_textarea
|
data/lib/forme/version.rb
CHANGED
@@ -6,11 +6,11 @@ module Forme
|
|
6
6
|
MAJOR = 2
|
7
7
|
|
8
8
|
# The minor version of Forme, updated for new feature releases of Forme.
|
9
|
-
MINOR =
|
9
|
+
MINOR = 5
|
10
10
|
|
11
11
|
# The patch version of Forme, updated only for bug fixes from the last
|
12
12
|
# feature release.
|
13
|
-
TINY =
|
13
|
+
TINY = 0
|
14
14
|
|
15
15
|
# Version constant, use <tt>Forme.version</tt> instead.
|
16
16
|
VERSION = "#{MAJOR}.#{MINOR}.#{TINY}".freeze
|
@@ -36,7 +36,7 @@ class Roda
|
|
36
36
|
end
|
37
37
|
|
38
38
|
if apply_csrf
|
39
|
-
token = if opts.fetch(:use_request_specific_token){use_request_specific_csrf_tokens?}
|
39
|
+
token = if use_request_specific_token = opts.fetch(:use_request_specific_token){use_request_specific_csrf_tokens?}
|
40
40
|
csrf_token(csrf_path(attr[:action]), method)
|
41
41
|
else
|
42
42
|
csrf_token
|
@@ -46,6 +46,23 @@ class Roda
|
|
46
46
|
opts[:_before] = lambda do |form|
|
47
47
|
form.tag(:input, :type=>:hidden, :name=>csrf_field, :value=>token)
|
48
48
|
end
|
49
|
+
|
50
|
+
if use_request_specific_token && (formaction_field = csrf_options[:formaction_field])
|
51
|
+
formactions = opts[:formactions] = []
|
52
|
+
formaction_tokens = opts[:formaction_tokens] = {}
|
53
|
+
_after = opts[:_after]
|
54
|
+
opts[:formaction_csrfs] = [formaction_field, formaction_tokens]
|
55
|
+
formaction_field = csrf_options[:formaction_field]
|
56
|
+
opts[:_after] = lambda do |form|
|
57
|
+
formactions.each do |action, method|
|
58
|
+
path = csrf_path(action)
|
59
|
+
fa_token = csrf_token(path, method)
|
60
|
+
formaction_tokens[path] = fa_token
|
61
|
+
form.tag(:input, :type=>:hidden, :name=>"#{formaction_field}[#{path}]", :value=>fa_token)
|
62
|
+
end
|
63
|
+
_after.call(form) if _after
|
64
|
+
end
|
65
|
+
end
|
49
66
|
end
|
50
67
|
end
|
51
68
|
end
|
@@ -102,7 +102,9 @@ class Roda
|
|
102
102
|
def _forme_form_options(obj, attr, opts)
|
103
103
|
super
|
104
104
|
|
105
|
+
_after = opts[:_after]
|
105
106
|
opts[:_after] = lambda do |form|
|
107
|
+
_after.call(form) if _after
|
106
108
|
if (obj = form.opts[:obj]) && obj.respond_to?(:forme_inputs) && (forme_inputs = obj.forme_inputs)
|
107
109
|
columns = []
|
108
110
|
valid_values = {}
|
@@ -129,6 +131,9 @@ class Roda
|
|
129
131
|
data['columns'] = columns
|
130
132
|
data['namespaces'] = form.opts[:namespace]
|
131
133
|
data['csrf'] = form.opts[:csrf]
|
134
|
+
if (formactions = form.opts[:formaction_csrfs]) && !formactions[1].empty?
|
135
|
+
data['formaction_csrfs'] = formactions
|
136
|
+
end
|
132
137
|
data['valid_values'] = valid_values unless valid_values.empty?
|
133
138
|
data['form_version'] = form.opts[:form_version] if form.opts[:form_version]
|
134
139
|
|
@@ -154,8 +159,16 @@ class Roda
|
|
154
159
|
|
155
160
|
data = JSON.parse(data)
|
156
161
|
csrf_field, hmac_csrf_value = data['csrf']
|
162
|
+
formaction_csrf_field, formaction_values = data['formaction_csrfs']
|
163
|
+
|
157
164
|
if csrf_field
|
158
|
-
|
165
|
+
formaction_params = params[formaction_csrf_field]
|
166
|
+
if formaction_csrf_field && (formaction_params = params[formaction_csrf_field]).is_a?(Hash) && (csrf_value = formaction_params[request.path])
|
167
|
+
hmac_csrf_value = formaction_values[request.path]
|
168
|
+
else
|
169
|
+
csrf_value = params[csrf_field].to_s
|
170
|
+
end
|
171
|
+
|
159
172
|
hmac_csrf_value = hmac_csrf_value.to_s
|
160
173
|
unless Rack::Utils.secure_compare(csrf_value.ljust(hmac_csrf_value.length), hmac_csrf_value) && csrf_value.length == hmac_csrf_value.length
|
161
174
|
return _forme_parse_error(:csrf_mismatch, obj)
|
data/lib/sequel/plugins/forme.rb
CHANGED
@@ -17,6 +17,22 @@ module Sequel # :nodoc:
|
|
17
17
|
# that use a <tt>Sequel::Model</tt> instance as the form's
|
18
18
|
# +obj+.
|
19
19
|
module SequelForm
|
20
|
+
# If the form has the :formactions option and the button has the
|
21
|
+
# formaction option or attribute, append the action and method
|
22
|
+
# for this button to the formactions. This is used by the
|
23
|
+
# Roda forme_route_csrf and forme_set plugins so that formaction
|
24
|
+
# can work as expected.
|
25
|
+
def button(opts={})
|
26
|
+
if opts.is_a?(Hash) && (formactions = self.opts[:formactions]) &&
|
27
|
+
(formaction = opts[:formaction] || ((attr = opts[:attr]) && (attr[:formaction] || attr['formaction'])))
|
28
|
+
formmethod = opts[:formmethod] ||
|
29
|
+
((attr = opts[:attr]) && (attr[:formmethod] || attr['formmethod'])) ||
|
30
|
+
((attr = form_tag_attributes) && (attr[:method] || attr['method']))
|
31
|
+
formactions << [formaction, formmethod]
|
32
|
+
end
|
33
|
+
super
|
34
|
+
end
|
35
|
+
|
20
36
|
# Use the post method by default for Sequel forms, unless
|
21
37
|
# overridden with the :method attribute.
|
22
38
|
def form(attr={}, &block)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: forme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.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:
|
11
|
+
date: 2024-02-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bigdecimal
|
@@ -239,7 +239,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
239
239
|
- !ruby/object:Gem::Version
|
240
240
|
version: '0'
|
241
241
|
requirements: []
|
242
|
-
rubygems_version: 3.
|
242
|
+
rubygems_version: 3.5.3
|
243
243
|
signing_key:
|
244
244
|
specification_version: 4
|
245
245
|
summary: HTML forms library
|