hanami 2.2.1 → 2.3.0.beta1
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.md +37 -1
- data/README.md +20 -35
- data/hanami.gemspec +3 -2
- data/lib/hanami/app.rb +2 -0
- data/lib/hanami/config/actions/content_security_policy.rb +23 -0
- data/lib/hanami/config/actions.rb +21 -0
- data/lib/hanami/config/console.rb +79 -0
- data/lib/hanami/config/logger.rb +1 -1
- data/lib/hanami/config.rb +13 -0
- data/lib/hanami/constants.rb +3 -0
- data/lib/hanami/extensions/db/repo.rb +11 -6
- data/lib/hanami/extensions/view/context.rb +10 -0
- data/lib/hanami/helpers/assets_helper.rb +92 -25
- data/lib/hanami/middleware/content_security_policy_nonce.rb +53 -0
- data/lib/hanami/slice.rb +22 -6
- data/lib/hanami/slice_registrar.rb +1 -1
- data/lib/hanami/version.rb +1 -1
- data/lib/hanami.rb +10 -2
- data/spec/integration/assets/cross_slice_assets_helpers_spec.rb +0 -1
- data/spec/integration/assets/serve_static_assets_spec.rb +1 -1
- data/spec/integration/container/autoloader_spec.rb +2 -0
- data/spec/integration/db/db_spec.rb +1 -1
- data/spec/integration/db/logging_spec.rb +63 -0
- data/spec/integration/db/repo_spec.rb +87 -2
- data/spec/integration/logging/exception_logging_spec.rb +6 -1
- data/spec/integration/rack_app/middleware_spec.rb +4 -11
- data/spec/integration/view/helpers/form_helper_spec.rb +1 -1
- data/spec/integration/web/content_security_policy_nonce_spec.rb +251 -0
- data/spec/support/app_integration.rb +2 -1
- data/spec/unit/hanami/config/actions/content_security_policy_spec.rb +7 -0
- data/spec/unit/hanami/config/console_spec.rb +22 -0
- data/spec/unit/hanami/env_spec.rb +10 -13
- data/spec/unit/hanami/slice_spec.rb +18 -0
- data/spec/unit/hanami/version_spec.rb +1 -1
- data/spec/unit/hanami/web/rack_logger_spec.rb +11 -4
- metadata +27 -18
- data/spec/support/shared_examples/cli/generate/app.rb +0 -494
- data/spec/support/shared_examples/cli/generate/migration.rb +0 -32
- data/spec/support/shared_examples/cli/generate/model.rb +0 -81
- data/spec/support/shared_examples/cli/new.rb +0 -97
@@ -0,0 +1,251 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "rack/test"
|
4
|
+
|
5
|
+
RSpec.describe "Web / Content security policy nonce", :app_integration do
|
6
|
+
include Rack::Test::Methods
|
7
|
+
|
8
|
+
let(:app) { Hanami.app }
|
9
|
+
|
10
|
+
before do
|
11
|
+
with_directory(@dir = make_tmp_directory) do
|
12
|
+
write "config/routes.rb", <<~RUBY
|
13
|
+
module TestApp
|
14
|
+
class Routes < Hanami::Routes
|
15
|
+
get "index", to: "index"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
RUBY
|
19
|
+
|
20
|
+
write "app/actions/index.rb", <<~RUBY
|
21
|
+
module TestApp
|
22
|
+
module Actions
|
23
|
+
class Index < Hanami::Action
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
RUBY
|
28
|
+
|
29
|
+
write "app/views/index.rb", <<~RUBY
|
30
|
+
module TestApp
|
31
|
+
module Views
|
32
|
+
class Index < Hanami::View
|
33
|
+
config.layout = false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
RUBY
|
38
|
+
|
39
|
+
write "app/templates/index.html.erb", <<~HTML
|
40
|
+
<!DOCTYPE html>
|
41
|
+
<html lang="en">
|
42
|
+
<head>
|
43
|
+
<%= stylesheet_tag "app", class: "nonce-true", nonce: true %>
|
44
|
+
<%= stylesheet_tag "app", class: "nonce-false", nonce: false %>
|
45
|
+
<%= stylesheet_tag "app", class: "nonce-explicit", nonce: "explicit" %>
|
46
|
+
<%= stylesheet_tag "app", class: "nonce-generated" %>
|
47
|
+
<%= stylesheet_tag "https://example.com/app.css", class: "nonce-absolute" %>
|
48
|
+
</head>
|
49
|
+
<body>
|
50
|
+
<style nonce="<%= content_security_policy_nonce %>"></style>
|
51
|
+
<%= javascript_tag "app", class: "nonce-true", nonce: true %>
|
52
|
+
<%= javascript_tag "app", class: "nonce-false", nonce: false %>
|
53
|
+
<%= javascript_tag "app", class: "nonce-explicit", nonce: "explicit" %>
|
54
|
+
<%= javascript_tag "app", class: "nonce-generated" %>
|
55
|
+
<%= javascript_tag "https://example.com/app.js", class: "nonce-absolute" %>
|
56
|
+
</body>
|
57
|
+
</html>
|
58
|
+
HTML
|
59
|
+
|
60
|
+
write "package.json", <<~JSON
|
61
|
+
{
|
62
|
+
"type": "module"
|
63
|
+
}
|
64
|
+
JSON
|
65
|
+
|
66
|
+
write "config/assets.js", <<~JS
|
67
|
+
import * as assets from "hanami-assets";
|
68
|
+
await assets.run();
|
69
|
+
JS
|
70
|
+
|
71
|
+
write "app/assets/js/app.js", <<~JS
|
72
|
+
import "../css/app.css";
|
73
|
+
JS
|
74
|
+
|
75
|
+
write "app/assets/css/app.css", ""
|
76
|
+
|
77
|
+
before_prepare if respond_to?(:before_prepare)
|
78
|
+
require "hanami/prepare"
|
79
|
+
compile_assets!
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe "HTML request" do
|
84
|
+
context "CSP enabled" do
|
85
|
+
def before_prepare
|
86
|
+
write "config/app.rb", <<~RUBY
|
87
|
+
require "hanami"
|
88
|
+
|
89
|
+
module TestApp
|
90
|
+
class App < Hanami::App
|
91
|
+
config.actions.content_security_policy[:script_src] = "'self' 'nonce'"
|
92
|
+
|
93
|
+
config.logger.stream = File::NULL
|
94
|
+
end
|
95
|
+
end
|
96
|
+
RUBY
|
97
|
+
end
|
98
|
+
|
99
|
+
it "sets unique and per-request hanami.content_security_policy_nonce in Rack env" do
|
100
|
+
previous_nonces = []
|
101
|
+
3.times do
|
102
|
+
get "/index"
|
103
|
+
nonce = last_request.env["hanami.content_security_policy_nonce"]
|
104
|
+
|
105
|
+
expect(nonce).to match(/\A[A-Za-z0-9\-_]{22}\z/)
|
106
|
+
expect(previous_nonces).not_to include nonce
|
107
|
+
|
108
|
+
previous_nonces << nonce
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it "accepts custom nonce generator proc without arguments" do
|
113
|
+
Hanami.app.config.actions.content_security_policy_nonce_generator = -> { "foobar" }
|
114
|
+
|
115
|
+
get "/index"
|
116
|
+
|
117
|
+
expect(last_request.env["hanami.content_security_policy_nonce"]).to eql("foobar")
|
118
|
+
end
|
119
|
+
|
120
|
+
it "accepts custom nonce generator proc with Rack request as argument" do
|
121
|
+
Hanami.app.config.actions.content_security_policy_nonce_generator = ->(request) { request }
|
122
|
+
|
123
|
+
get "/index"
|
124
|
+
|
125
|
+
expect(last_request.env["hanami.content_security_policy_nonce"]).to be_a(Rack::Request)
|
126
|
+
end
|
127
|
+
|
128
|
+
it "substitutes 'nonce' in the CSP header" do
|
129
|
+
get "/index"
|
130
|
+
nonce = last_request.env["hanami.content_security_policy_nonce"]
|
131
|
+
|
132
|
+
expect(last_response.get_header("Content-Security-Policy")).to match(/script-src 'self' 'nonce-#{nonce}'/)
|
133
|
+
end
|
134
|
+
|
135
|
+
it "behaves the same with explicitly added middleware" do
|
136
|
+
Hanami.app.config.middleware.use Hanami::Middleware::ContentSecurityPolicyNonce
|
137
|
+
get "/index"
|
138
|
+
|
139
|
+
expect(last_request.env["hanami.content_security_policy_nonce"]).to match(/\A[A-Za-z0-9\-_]{22}\z/)
|
140
|
+
end
|
141
|
+
|
142
|
+
describe "content_security_policy_nonce" do
|
143
|
+
it "renders the current nonce" do
|
144
|
+
get "/index"
|
145
|
+
nonce = last_request.env["hanami.content_security_policy_nonce"]
|
146
|
+
|
147
|
+
expect(last_response.body).to include(%(<style nonce="#{nonce}">))
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
describe "stylesheet_tag" do
|
152
|
+
it "renders the correct nonce unless remote URL or nonce set to false" do
|
153
|
+
get "/index"
|
154
|
+
nonce = last_request.env["hanami.content_security_policy_nonce"]
|
155
|
+
|
156
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" nonce="#{nonce}" class="nonce-true">))
|
157
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" class="nonce-false">))
|
158
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" nonce="explicit" class="nonce-explicit">))
|
159
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" nonce="#{nonce}" class="nonce-generated">))
|
160
|
+
expect(last_response.body).to include(%(<link href="https://example.com/app.css" type="text/css" rel="stylesheet" class="nonce-absolute">))
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "javascript_tag" do
|
165
|
+
it "renders the correct nonce unless remote URL or nonce set to false" do
|
166
|
+
get "/index"
|
167
|
+
nonce = last_request.env["hanami.content_security_policy_nonce"]
|
168
|
+
|
169
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" nonce="#{nonce}" class="nonce-true"></script>))
|
170
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" class="nonce-false"></script>))
|
171
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" nonce="explicit" class="nonce-explicit"></script>))
|
172
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" nonce="#{nonce}" class="nonce-generated"></script>))
|
173
|
+
expect(last_response.body).to include(%(<script src="https://example.com/app.js" type="text/javascript" class="nonce-absolute"></script>))
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
context "CSP disabled" do
|
179
|
+
def before_prepare
|
180
|
+
write "config/app.rb", <<~RUBY
|
181
|
+
require "hanami"
|
182
|
+
|
183
|
+
module TestApp
|
184
|
+
class App < Hanami::App
|
185
|
+
config.actions.content_security_policy = false
|
186
|
+
|
187
|
+
config.logger.stream = File::NULL
|
188
|
+
end
|
189
|
+
end
|
190
|
+
RUBY
|
191
|
+
end
|
192
|
+
|
193
|
+
it "does not set hanami.content_security_policy_nonce in Rack env" do
|
194
|
+
get "/index"
|
195
|
+
|
196
|
+
expect(last_request.env).to_not have_key "hanami.content_security_policy_nonce"
|
197
|
+
end
|
198
|
+
|
199
|
+
it "does not produce a CSP header" do
|
200
|
+
get "/index"
|
201
|
+
|
202
|
+
expect(last_response.headers).to_not have_key "Content-Security-Policy"
|
203
|
+
end
|
204
|
+
|
205
|
+
it "disables the content_security_policy_nonce helper" do
|
206
|
+
get "/index"
|
207
|
+
|
208
|
+
expect(last_response.body).to match(/<style nonce="">/)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "behaves the same with explicitly added middleware" do
|
212
|
+
Hanami.app.config.middleware.use Hanami::Middleware::ContentSecurityPolicyNonce
|
213
|
+
get "/index"
|
214
|
+
|
215
|
+
expect(last_response.headers).to_not have_key "Content-Security-Policy"
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "content_security_policy_nonce" do
|
219
|
+
it "renders nothing" do
|
220
|
+
get "/index"
|
221
|
+
|
222
|
+
expect(last_response.body).to include(%(<style nonce="">))
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
describe "stylesheet_tag" do
|
227
|
+
it "renders the correct explicit nonce only" do
|
228
|
+
get "/index"
|
229
|
+
|
230
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" class="nonce-true">))
|
231
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" class="nonce-false">))
|
232
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" nonce="explicit" class="nonce-explicit">))
|
233
|
+
expect(last_response.body).to include(%(<link href="/assets/app-KUHJPSX7.css" type="text/css" rel="stylesheet" class="nonce-generated">))
|
234
|
+
expect(last_response.body).to include(%(<link href="https://example.com/app.css" type="text/css" rel="stylesheet" class="nonce-absolute">))
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
describe "javascript_tag" do
|
239
|
+
it "renders the correct explicit nonce only" do
|
240
|
+
get "/index"
|
241
|
+
|
242
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" class="nonce-true"></script>))
|
243
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" class="nonce-false"></script>))
|
244
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" nonce="explicit" class="nonce-explicit"></script>))
|
245
|
+
expect(last_response.body).to include(%(<script src="/assets/app-LSLFPUMX.js" type="text/javascript" class="nonce-generated"></script>))
|
246
|
+
expect(last_response.body).to include(%(<script src="https://example.com/app.js" type="text/javascript" class="nonce-absolute"></script>))
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
@@ -118,7 +118,8 @@ RSpec.configure do |config|
|
|
118
118
|
Hanami.instance_variable_set(:@_bundled, {})
|
119
119
|
Hanami.remove_instance_variable(:@_app) if Hanami.instance_variable_defined?(:@_app)
|
120
120
|
|
121
|
-
#
|
121
|
+
# Disconnect and clear cached DB gateways across slices
|
122
|
+
Hanami::Providers::DB.cache.values.map(&:disconnect)
|
122
123
|
Hanami::Providers::DB.cache.clear
|
123
124
|
|
124
125
|
$LOAD_PATH.replace(@load_paths)
|
@@ -28,6 +28,7 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
|
|
28
28
|
].join(";")
|
29
29
|
|
30
30
|
expect(content_security_policy.to_s).to eq(expected)
|
31
|
+
expect(content_security_policy.nonce?).to be(false)
|
31
32
|
end
|
32
33
|
end
|
33
34
|
|
@@ -68,6 +69,12 @@ RSpec.describe Hanami::Config::Actions, "#content_security_policy" do
|
|
68
69
|
expect(content_security_policy[:a_custom_key]).to eq("foo")
|
69
70
|
expect(content_security_policy.to_s).to match("a-custom-key foo")
|
70
71
|
end
|
72
|
+
|
73
|
+
it "uses 'nonce' in value" do
|
74
|
+
content_security_policy[:javascript_src] = "'self' 'nonce'"
|
75
|
+
|
76
|
+
expect(content_security_policy.nonce?).to be(true)
|
77
|
+
end
|
71
78
|
end
|
72
79
|
|
73
80
|
context "with CSP enabled" do
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "hanami/config"
|
4
|
+
|
5
|
+
RSpec.describe Hanami::Config, "#console" do
|
6
|
+
let(:config) { described_class.new(app_name: app_name, env: :development) }
|
7
|
+
let(:app_name) { "MyApp::App" }
|
8
|
+
|
9
|
+
subject(:console) { config.console }
|
10
|
+
|
11
|
+
it "is a full console configuration" do
|
12
|
+
is_expected.to be_an_instance_of(Hanami::Config::Console)
|
13
|
+
|
14
|
+
is_expected.to respond_to(:engine)
|
15
|
+
is_expected.to respond_to(:include)
|
16
|
+
is_expected.to respond_to(:extensions)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "can be finalized" do
|
20
|
+
is_expected.to respond_to(:finalize!)
|
21
|
+
end
|
22
|
+
end
|
@@ -3,30 +3,27 @@
|
|
3
3
|
RSpec.describe Hanami, ".env" do
|
4
4
|
subject { described_class.env(e: env) }
|
5
5
|
|
6
|
-
context "HANAMI_ENV in ENV" do
|
7
|
-
let(:env) { {"HANAMI_ENV" => "test"} }
|
6
|
+
context "HANAMI_ENV, APP_ENV and RACK_ENV in ENV" do
|
7
|
+
let(:env) { { "HANAMI_ENV" => "test", "APP_ENV" => "development", "RACK_ENV" => "production" } }
|
8
8
|
|
9
9
|
it "is the value of HANAMI_ENV" do
|
10
10
|
is_expected.to eq(:test)
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
context "RACK_ENV in ENV" do
|
15
|
-
let(:env) { {"
|
14
|
+
context "APP_ENV and RACK_ENV in ENV" do
|
15
|
+
let(:env) { {"APP_ENV" => "development", "RACK_ENV" => "production" } }
|
16
16
|
|
17
|
-
it "is the value of
|
18
|
-
is_expected.to eq(:
|
17
|
+
it "is the value of APP_ENV" do
|
18
|
+
is_expected.to eq(:development)
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
context "
|
23
|
-
let(:env)
|
24
|
-
{"HANAMI_ENV" => "test",
|
25
|
-
"RACK_ENV" => "production"}
|
26
|
-
end
|
22
|
+
context "RACK_ENV in ENV" do
|
23
|
+
let(:env) { { "RACK_ENV" => "production" } }
|
27
24
|
|
28
|
-
it "is the value of
|
29
|
-
is_expected.to eq(:
|
25
|
+
it "is the value of RACK_ENV" do
|
26
|
+
is_expected.to eq(:production)
|
30
27
|
end
|
31
28
|
end
|
32
29
|
|
@@ -65,6 +65,24 @@ RSpec.describe Hanami::Slice, :app_integration do
|
|
65
65
|
expect { Class.new(described_class).prepare }
|
66
66
|
.to raise_error Hanami::SliceLoadError, /Slice must have a class name/
|
67
67
|
end
|
68
|
+
|
69
|
+
it "does not allow special characters in slice names" do
|
70
|
+
expect { Hanami.app.register_slice(:'test_$lice') }
|
71
|
+
.to raise_error(ArgumentError, /must be lowercase alphanumeric text and underscores only/)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "does not allow uppercase characters in slice names" do
|
75
|
+
expect { Hanami.app.register_slice(:TEST_slice) }
|
76
|
+
.to raise_error(ArgumentError, /must be lowercase alphanumeric text and underscores only/)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "allows lowercase alphanumeric text and underscores only" do
|
80
|
+
expect { Hanami.app.register_slice(:test_slice) }.not_to raise_error
|
81
|
+
end
|
82
|
+
|
83
|
+
it "allows single character slice names" do
|
84
|
+
expect { Hanami.app.register_slice(:t) }.not_to raise_error
|
85
|
+
end
|
68
86
|
end
|
69
87
|
|
70
88
|
describe ".source_path" do
|
@@ -53,10 +53,17 @@ RSpec.describe Hanami::Web::RackLogger do
|
|
53
53
|
stream.rewind
|
54
54
|
actual = stream.read
|
55
55
|
|
56
|
-
|
57
|
-
|
58
|
-
{
|
59
|
-
|
56
|
+
if RUBY_VERSION < "3.4"
|
57
|
+
expect(actual).to eql(<<~LOG)
|
58
|
+
[#{app_name}] [INFO] [#{time}] #{verb} #{status} #{elapsed}µs #{ip} #{path} #{content_length}
|
59
|
+
{"user"=>{"password"=>"[FILTERED]"}}
|
60
|
+
LOG
|
61
|
+
else
|
62
|
+
expect(actual).to eql(<<~LOG)
|
63
|
+
[#{app_name}] [INFO] [#{time}] #{verb} #{status} #{elapsed}µs #{ip} #{path} #{content_length}
|
64
|
+
{"user" => {"password" => "[FILTERED]"}}
|
65
|
+
LOG
|
66
|
+
end
|
60
67
|
end
|
61
68
|
|
62
69
|
context "ip" do
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hanami
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0.beta1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luca Guidi
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: bundler
|
@@ -168,14 +167,14 @@ dependencies:
|
|
168
167
|
requirements:
|
169
168
|
- - "~>"
|
170
169
|
- !ruby/object:Gem::Version
|
171
|
-
version: 2.
|
170
|
+
version: 2.3.0.beta1
|
172
171
|
type: :runtime
|
173
172
|
prerelease: false
|
174
173
|
version_requirements: !ruby/object:Gem::Requirement
|
175
174
|
requirements:
|
176
175
|
- - "~>"
|
177
176
|
- !ruby/object:Gem::Version
|
178
|
-
version: 2.
|
177
|
+
version: 2.3.0.beta1
|
179
178
|
- !ruby/object:Gem::Dependency
|
180
179
|
name: hanami-utils
|
181
180
|
requirement: !ruby/object:Gem::Requirement
|
@@ -218,6 +217,20 @@ dependencies:
|
|
218
217
|
- - "~>"
|
219
218
|
- !ruby/object:Gem::Version
|
220
219
|
version: '2.6'
|
220
|
+
- !ruby/object:Gem::Dependency
|
221
|
+
name: rack-session
|
222
|
+
requirement: !ruby/object:Gem::Requirement
|
223
|
+
requirements:
|
224
|
+
- - ">="
|
225
|
+
- !ruby/object:Gem::Version
|
226
|
+
version: '0'
|
227
|
+
type: :runtime
|
228
|
+
prerelease: false
|
229
|
+
version_requirements: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: '0'
|
221
234
|
- !ruby/object:Gem::Dependency
|
222
235
|
name: rspec
|
223
236
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,14 +251,14 @@ dependencies:
|
|
238
251
|
requirements:
|
239
252
|
- - "~>"
|
240
253
|
- !ruby/object:Gem::Version
|
241
|
-
version: '
|
254
|
+
version: '2.0'
|
242
255
|
type: :development
|
243
256
|
prerelease: false
|
244
257
|
version_requirements: !ruby/object:Gem::Requirement
|
245
258
|
requirements:
|
246
259
|
- - "~>"
|
247
260
|
- !ruby/object:Gem::Version
|
248
|
-
version: '
|
261
|
+
version: '2.0'
|
249
262
|
- !ruby/object:Gem::Dependency
|
250
263
|
name: rake
|
251
264
|
requirement: !ruby/object:Gem::Requirement
|
@@ -282,6 +295,7 @@ files:
|
|
282
295
|
- lib/hanami/config/actions/cookies.rb
|
283
296
|
- lib/hanami/config/actions/sessions.rb
|
284
297
|
- lib/hanami/config/assets.rb
|
298
|
+
- lib/hanami/config/console.rb
|
285
299
|
- lib/hanami/config/db.rb
|
286
300
|
- lib/hanami/config/logger.rb
|
287
301
|
- lib/hanami/config/null_config.rb
|
@@ -310,6 +324,7 @@ files:
|
|
310
324
|
- lib/hanami/helpers/form_helper/form_builder.rb
|
311
325
|
- lib/hanami/helpers/form_helper/values.rb
|
312
326
|
- lib/hanami/middleware/assets.rb
|
327
|
+
- lib/hanami/middleware/content_security_policy_nonce.rb
|
313
328
|
- lib/hanami/middleware/public_errors_app.rb
|
314
329
|
- lib/hanami/middleware/render_errors.rb
|
315
330
|
- lib/hanami/port.rb
|
@@ -432,6 +447,7 @@ files:
|
|
432
447
|
- spec/integration/view/parts/default_rendering_spec.rb
|
433
448
|
- spec/integration/view/slice_configuration_spec.rb
|
434
449
|
- spec/integration/view/views_spec.rb
|
450
|
+
- spec/integration/web/content_security_policy_nonce_spec.rb
|
435
451
|
- spec/integration/web/render_detailed_errors_spec.rb
|
436
452
|
- spec/integration/web/render_errors_spec.rb
|
437
453
|
- spec/integration/web/welcome_view_spec.rb
|
@@ -440,10 +456,6 @@ files:
|
|
440
456
|
- spec/support/coverage.rb
|
441
457
|
- spec/support/matchers.rb
|
442
458
|
- spec/support/rspec.rb
|
443
|
-
- spec/support/shared_examples/cli/generate/app.rb
|
444
|
-
- spec/support/shared_examples/cli/generate/migration.rb
|
445
|
-
- spec/support/shared_examples/cli/generate/model.rb
|
446
|
-
- spec/support/shared_examples/cli/new.rb
|
447
459
|
- spec/unit/hanami/config/actions/content_security_policy_spec.rb
|
448
460
|
- spec/unit/hanami/config/actions/cookies_spec.rb
|
449
461
|
- spec/unit/hanami/config/actions/csrf_protection_spec.rb
|
@@ -451,6 +463,7 @@ files:
|
|
451
463
|
- spec/unit/hanami/config/actions/sessions_spec.rb
|
452
464
|
- spec/unit/hanami/config/actions_spec.rb
|
453
465
|
- spec/unit/hanami/config/base_url_spec.rb
|
466
|
+
- spec/unit/hanami/config/console_spec.rb
|
454
467
|
- spec/unit/hanami/config/db_spec.rb
|
455
468
|
- spec/unit/hanami/config/inflector_spec.rb
|
456
469
|
- spec/unit/hanami/config/logger_spec.rb
|
@@ -488,7 +501,6 @@ licenses:
|
|
488
501
|
metadata:
|
489
502
|
rubygems_mfa_required: 'true'
|
490
503
|
allowed_push_host: https://rubygems.org
|
491
|
-
post_install_message:
|
492
504
|
rdoc_options: []
|
493
505
|
require_paths:
|
494
506
|
- lib
|
@@ -503,8 +515,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
503
515
|
- !ruby/object:Gem::Version
|
504
516
|
version: '0'
|
505
517
|
requirements: []
|
506
|
-
rubygems_version: 3.
|
507
|
-
signing_key:
|
518
|
+
rubygems_version: 3.6.9
|
508
519
|
specification_version: 4
|
509
520
|
summary: The web, with simplicity
|
510
521
|
test_files:
|
@@ -593,6 +604,7 @@ test_files:
|
|
593
604
|
- spec/integration/view/parts/default_rendering_spec.rb
|
594
605
|
- spec/integration/view/slice_configuration_spec.rb
|
595
606
|
- spec/integration/view/views_spec.rb
|
607
|
+
- spec/integration/web/content_security_policy_nonce_spec.rb
|
596
608
|
- spec/integration/web/render_detailed_errors_spec.rb
|
597
609
|
- spec/integration/web/render_errors_spec.rb
|
598
610
|
- spec/integration/web/welcome_view_spec.rb
|
@@ -601,10 +613,6 @@ test_files:
|
|
601
613
|
- spec/support/coverage.rb
|
602
614
|
- spec/support/matchers.rb
|
603
615
|
- spec/support/rspec.rb
|
604
|
-
- spec/support/shared_examples/cli/generate/app.rb
|
605
|
-
- spec/support/shared_examples/cli/generate/migration.rb
|
606
|
-
- spec/support/shared_examples/cli/generate/model.rb
|
607
|
-
- spec/support/shared_examples/cli/new.rb
|
608
616
|
- spec/unit/hanami/config/actions/content_security_policy_spec.rb
|
609
617
|
- spec/unit/hanami/config/actions/cookies_spec.rb
|
610
618
|
- spec/unit/hanami/config/actions/csrf_protection_spec.rb
|
@@ -612,6 +620,7 @@ test_files:
|
|
612
620
|
- spec/unit/hanami/config/actions/sessions_spec.rb
|
613
621
|
- spec/unit/hanami/config/actions_spec.rb
|
614
622
|
- spec/unit/hanami/config/base_url_spec.rb
|
623
|
+
- spec/unit/hanami/config/console_spec.rb
|
615
624
|
- spec/unit/hanami/config/db_spec.rb
|
616
625
|
- spec/unit/hanami/config/inflector_spec.rb
|
617
626
|
- spec/unit/hanami/config/logger_spec.rb
|