web-console 3.7.0 → 4.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e0540ac7a81a49deaad0b10cd764ca4d02ca2e9a630ef6d775051dec6e5ef55
4
- data.tar.gz: 80352b0d87ea7718cd08597c159d67edbafb2e5f9e46f674f48d1011a7118fc1
3
+ metadata.gz: a491428cda19f89cf20ad5ef83558e948feecb7acb7f46b453c5644ad419131b
4
+ data.tar.gz: 3e3d2902466fc03684b00591b294df2c19af06db31e43f58f1f9e8de14cb731f
5
5
  SHA512:
6
- metadata.gz: e954cedb636a015d9cb86ddc60e4e97e44f61df6d7eaac89144c2b7b39207883117186c81420d2e90719f42d9acc6d397842f6750600b04681db47093c4e506a
7
- data.tar.gz: c091ef07d8462544f8f8367143a5b1ef8579a901cb1cfd88e463a2a37e3955f8c769f7a3206b2b4da442db27c3743a5e86ce9c69f82a6f954d1301d4e7629055
6
+ metadata.gz: d949e602f1056bda92b2e7e13e030a78bd856befeb52ccd89c57c27a5341bab30830e27969f3fd9bf8e3d5e4467de381cb788cd9d5809ad6f5d662b2a00b3993
7
+ data.tar.gz: a17229c83c77f2fdc2b06ca4d25674391e9318490da932de015d0d8ebc59bf652ccb010577eea9d95c357fcd703ba6b5fb8f2afc8343ad79306e80834f52d77d
data/CHANGELOG.markdown CHANGED
@@ -2,6 +2,45 @@
2
2
 
3
3
  ## master (unreleased)
4
4
 
5
+ ## 4.2.0
6
+
7
+ * [#308](https://github.com/rails/web-console/pull/308) Fix web-console inline templates rendering ([@voxik])
8
+ * [#306](https://github.com/rails/web-console/pull/306) Support Ruby 3.0 and above ([@ruanwood])
9
+
10
+ ## 4.1.0
11
+
12
+ * [#304](https://github.com/rails/web-console/pull/304) Add support for Rails 6.1 ([@stephannv])
13
+ * [#298](https://github.com/rails/web-console/pull/298) Prevent deprecation warnings by removing template formats ([@mikelkew])
14
+ * [#297](https://github.com/rails/web-console/pull/297) Use MutationObserver instead of Mutation Events ([@mikelkew])
15
+ * [#296](https://github.com/rails/web-console/pull/296) Add CSP nonce to injected scripts and styles ([@mikelkew])
16
+
17
+ ## 4.0.4
18
+
19
+ * [fb483743](https://github.com/rails/web-console/commit/fb483743a6a2a4168cdc0b2e03f48fc393991b73) Fix a crash on webrick with Rack 2.2.3 ([@gsamokovarov])
20
+
21
+ ## 4.0.3
22
+
23
+ * [#291](https://github.com/rails/web-console/pull/291) Deprecate config.web_console.whitelisted_ips ([@JuanitoFatas])
24
+ * [#290](https://github.com/rails/web-console/pull/290) Fix Content-Length for rack >= 2.1.0 ([@p8])
25
+
26
+ ## 4.0.2
27
+
28
+ * [#285](https://github.com/rails/web-console/pull/285) Increase timeout on paste ([@celvro])
29
+
30
+ ## 4.0.1
31
+
32
+ * [#279](https://github.com/rails/web-console/pull/279) Fix initial config.web_console.permissions value ([@patorash])
33
+
34
+ ## 4.0.0
35
+
36
+ * [61ce65b5](https://github.com/rails/web-console/commit/61ce65b599f56809de1bd8da6590a80acbd92017) Move to config.web_console.permissions ([@gsamokovarov])
37
+ * [96127ac1](https://github.com/rails/web-console/commit/96127aac143e1e653fffdc4bb65e1ce0b5ff342d) Introduce Binding#console as an alternative interface ([@gsamokovarov])
38
+ * [d4591ca5](https://github.com/rails/web-console/commit/d4591ca5396ed15a08818f3da11134852a485b27) Introduce Rails 6 support ([@gsamokovarov])
39
+ * [f97d8a88](https://github.com/rails/web-console/commit/f97d8a889a38366485e5c5e8985995c19bf61d13) Introduce Ruby 2.6 support ([@gsamokovarov])
40
+ * [d6deacd9](https://github.com/rails/web-console/commit/d6deacd9d5fcaabf3e3051d6985b53f924f86956) Drop Rails 5 support ([@gsamokovarov])
41
+ * [90fda878](https://github.com/rails/web-console/commit/90fda8789d402f05647c18f8cdf8e5c3d01692dd) Drop Ruby 2.4 support ([@gsamokovarov])
42
+ * [#265](https://github.com/rails/web-console/pull/265) Add support for nested exceptions ([@yuki24])
43
+
5
44
  ## 3.7.0
6
45
 
7
46
  * [#263](https://github.com/rails/web-console/pull/263) Show binding changes ([@causztic])
@@ -118,6 +157,8 @@ go to 3.1.0 instead.
118
157
  * [#84](https://github.com/rails/web-console/pull/84) Allow Rails 5 as dependency in gemspec ([@jonatack])
119
158
  * [#69](https://github.com/rails/web-console/pull/69) Introduce middleware for request dispatch and console rendering ([@gsamokovarov])
120
159
 
160
+ [@stephannv]: https://github.com/stephannv
161
+ [@mikelkew]: https://github.com/mikelkew
121
162
  [@jonatack]: https://github.com/jonatack
122
163
  [@ryandao]: https://github.com/ryandao
123
164
  [@jeffnv]: https://github.com/jeffnv
@@ -138,3 +179,10 @@ go to 3.1.0 instead.
138
179
  [@fl0l0u]: https://github.com/fl0l0u
139
180
  [@timomeh]: https://github.com/timomeh
140
181
  [@causztic]: https://github.com/causztic
182
+ [@yuki24]: https://github.com/yuki24
183
+ [@patorash]: https://github.com/patorash
184
+ [@celvro]: https://github.com/celvro
185
+ [@JuanitoFatas]: https://github.com/JuanitoFatas
186
+ [@p8]: https://github.com/p8
187
+ [@voxik]: https://github.com/voxik
188
+ [@ryanwood]: https://github.com/ryanwood
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright 2014-2016 Charlie Somerville, Genadi Samokovarov, Guillermo Iguaran and Ryan Dao
1
+ Copyright 2014-2016 Hailey Somerville, Genadi Samokovarov, Guillermo Iguaran and Ryan Dao
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.markdown CHANGED
@@ -1,7 +1,8 @@
1
1
  <p align=right>
2
- Documentation for:
2
+ <strong>Current version: 4.1.0</strong> | Documentation for:
3
3
  <a href=https://github.com/rails/web-console/tree/v1.0.4>v1.0.4</a>
4
4
  <a href=https://github.com/rails/web-console/tree/v2.2.1>v2.2.1</a>
5
+ <a href=https://github.com/rails/web-console/tree/v3.7.0>v3.7.0</a>
5
6
  </p>
6
7
 
7
8
  # Web Console [![Build Status](https://travis-ci.org/rails/web-console.svg?branch=master)](https://travis-ci.org/rails/web-console)
@@ -16,7 +17,7 @@ _Web Console_ is a debugging tool for your Ruby on Rails applications.
16
17
 
17
18
  ## Installation
18
19
 
19
- Add the following to your `Gemfile`.
20
+ Add the following to your `Gemfile`:
20
21
 
21
22
  ```ruby
22
23
  group :development do
@@ -27,8 +28,8 @@ end
27
28
  ## Usage
28
29
 
29
30
  The web console allows you to create an interactive Ruby session in your
30
- browser. Those sessions are launched automatically in case of an error, but
31
- they can also be launched manually in any page.
31
+ browser. Those sessions are launched automatically in case of an error and can
32
+ also be launched manually in any page.
32
33
 
33
34
  For example, calling `console` in a view will display a console in the current
34
35
  page in the context of the view binding.
@@ -56,30 +57,30 @@ have multiple ones, `WebConsole::DoubleRenderError` will be raised.
56
57
 
57
58
  ## Configuration
58
59
 
59
- _Web Console_ allows you to execute arbitrary code on the server, so you
60
- should be very careful, who you give access to.
60
+ _Web Console_ allows you to execute arbitrary code on the server. Therefore, be
61
+ very careful who you give access to.
61
62
 
62
- ### config.web_console.whitelisted_ips
63
+ ### config.web_console.permissions
63
64
 
64
65
  By default, only requests coming from IPv4 and IPv6 localhosts are allowed.
65
66
 
66
- `config.web_console.whitelisted_ips` lets you control which IP's have access to
67
+ `config.web_console.permissions` lets you control which IP's have access to
67
68
  the console.
68
69
 
69
- You can whitelist single IP's or whole networks. Say you want to share your
70
- console with `192.168.0.100`. You can do this:
70
+ You can allow single IP's or whole networks. Say you want to share your
71
+ console with `192.168.0.100`:
71
72
 
72
73
  ```ruby
73
74
  class Application < Rails::Application
74
- config.web_console.whitelisted_ips = '192.168.0.100'
75
+ config.web_console.permissions = '192.168.0.100'
75
76
  end
76
77
  ```
77
78
 
78
- If you want to whitelist the whole private network, you can do:
79
+ If you want to allow the whole private network:
79
80
 
80
81
  ```ruby
81
82
  Rails.application.configure do
82
- config.web_console.whitelisted_ips = '192.168.0.0/16'
83
+ config.web_console.permissions = '192.168.0.0/16'
83
84
  end
84
85
  ```
85
86
 
@@ -88,8 +89,8 @@ case in 2.0.
88
89
 
89
90
  ### config.web_console.whiny_requests
90
91
 
91
- When a console cannot be shown for a given IP address or content type, a
92
- messages like the following is printed in the server logs:
92
+ When a console cannot be shown for a given IP address or content type,
93
+ messages such as the following is printed in the server logs:
93
94
 
94
95
  > Cannot render console from 192.168.1.133! Allowed networks:
95
96
  > 127.0.0.0/127.255.255.255, ::1
@@ -104,7 +105,7 @@ end
104
105
 
105
106
  ### config.web_console.template_paths
106
107
 
107
- If you want to style the console yourself, you can place `style.css` at a
108
+ If you want to style the console yourself, then you can place `style.css` at a
108
109
  directory pointed by `config.web_console.template_paths`:
109
110
 
110
111
  ```ruby
@@ -119,8 +120,8 @@ may override.
119
120
  ### config.web_console.mount_point
120
121
 
121
122
  Usually the middleware of _Web Console_ is mounted at `/__web_console`.
122
- If you want to change the path for some reasons, you can specify it
123
- by `config.web_console.mount_point`:
123
+ If there is a need to change the path, then you can specify it by
124
+ `config.web_console.mount_point`:
124
125
 
125
126
  ```ruby
126
127
  Rails.application.configure do
@@ -132,7 +133,7 @@ end
132
133
 
133
134
  ### Where did /console go?
134
135
 
135
- The remote terminal emulator was extracted in its own gem that is no longer
136
+ The remote terminal emulator was extracted in its own gem which is no longer
136
137
  bundled with _Web Console_.
137
138
 
138
139
  If you miss this feature, check out [rvt].
@@ -140,11 +141,11 @@ If you miss this feature, check out [rvt].
140
141
  ### Why do I constantly get unavailable session errors?
141
142
 
142
143
  All of _Web Console_ sessions are stored in memory. If you happen to run on a
143
- multi-process server (like Unicorn) you may get unavailable session errors
144
+ multi-process server (like Unicorn), you may encounter unavailable session errors
144
145
  while the server is still running. This is because a request may hit a
145
146
  different worker (process) that doesn't have the desired session in memory.
146
147
  To avoid that, if you use such servers in development, configure them so they
147
- server requests only out of one process.
148
+ serve requests only out of one process.
148
149
 
149
150
  #### Passenger
150
151
 
@@ -174,15 +175,15 @@ Make sure your configuration lives in `config/environments/development.rb`.
174
175
 
175
176
  ## Credits
176
177
 
177
- * Shoutout to [Charlie Somerville] for [better_errors].
178
+ * Shoutout to [Hailey Somerville] for [better_errors].
178
179
  * Kudos to [John Mair] for [binding_of_caller] and [debug_inspector].
179
180
  * Thanks to [Charles Oliver Nutter] for all the _JRuby_ feedback.
180
181
  * Hugs and kisses to all of our [contributors]!
181
182
 
182
- [better_errors]: https://github.com/charliesome/better_errors
183
+ [better_errors]: https://github.com/BetterErrors/better_errors
183
184
  [debug_inspector]: https://github.com/banister/debug_inspector
184
185
  [binding_of_caller]: https://github.com/banister/binding_of_caller
185
- [Charlie Somerville]: https://github.com/charliesome
186
+ [Hailey Somerville]: https://github.com/haileys
186
187
  [John Mair]: https://github.com/banister
187
188
  [Charles Oliver Nutter]: https://github.com/headius
188
189
  [templates]: https://github.com/rails/web-console/tree/master/lib/web_console/templates
@@ -8,16 +8,23 @@ module WebConsole
8
8
  # return a string and will format exception output.
9
9
  class Evaluator
10
10
  # Cleanses exceptions raised inside #eval.
11
- cattr_reader :cleaner
12
- @@cleaner = ActiveSupport::BacktraceCleaner.new
13
- @@cleaner.add_silencer { |line| line.start_with?(File.expand_path("..", __FILE__)) }
11
+ cattr_reader :cleaner, default: begin
12
+ cleaner = ActiveSupport::BacktraceCleaner.new
13
+ cleaner.add_silencer { |line| line.start_with?(File.expand_path("..", __FILE__)) }
14
+ cleaner
15
+ end
14
16
 
15
17
  def initialize(binding = TOPLEVEL_BINDING)
16
18
  @binding = binding
17
19
  end
18
20
 
19
21
  def eval(input)
20
- "=> #{@binding.eval(input).inspect}\n"
22
+ # Binding#source_location is available since Ruby 2.6.
23
+ if @binding.respond_to? :source_location
24
+ "=> #{@binding.eval(input, *@binding.source_location).inspect}\n"
25
+ else
26
+ "=> #{@binding.eval(input).inspect}\n"
27
+ end
21
28
  rescue Exception => exc
22
29
  format_exception(exc)
23
30
  end
@@ -2,9 +2,28 @@
2
2
 
3
3
  module WebConsole
4
4
  class ExceptionMapper
5
+ attr_reader :exc
6
+
7
+ def self.follow(exc)
8
+ mappers = [new(exc)]
9
+
10
+ while cause = (cause || exc).cause
11
+ mappers << new(cause)
12
+ end
13
+
14
+ mappers
15
+ end
16
+
17
+ def self.find_binding(mappers, exception_object_id)
18
+ mappers.detect do |exception_mapper|
19
+ exception_mapper.exc.object_id == exception_object_id.to_i
20
+ end || mappers.first
21
+ end
22
+
5
23
  def initialize(exception)
6
24
  @backtrace = exception.backtrace
7
25
  @bindings = exception.bindings
26
+ @exc = exception
8
27
  end
9
28
 
10
29
  def first
@@ -22,13 +41,15 @@ module WebConsole
22
41
  line = line.to_i
23
42
 
24
43
  @bindings.find do |binding|
25
- binding.eval("__FILE__") == file && binding.eval("__LINE__") == line
44
+ source_location = SourceLocation.new(binding)
45
+ source_location.path == file && source_location.lineno == line
26
46
  end
27
47
  end
28
48
 
29
49
  def guess_the_first_application_binding
30
50
  @bindings.find do |binding|
31
- binding.eval("__FILE__").to_s.start_with?(Rails.root.to_s)
51
+ source_location = SourceLocation.new(binding)
52
+ source_location.path.to_s.start_with?(Rails.root.to_s)
32
53
  end
33
54
  end
34
55
  end
@@ -8,8 +8,8 @@ module Kernel
8
8
  # If +binding+ isn't explicitly given it will default to the binding of the
9
9
  # previous frame. E.g. the one that invoked +console+.
10
10
  #
11
- # Raises DoubleRenderError if a double +console+ invocation per request is
12
- # detected.
11
+ # Raises +DoubleRenderError+ if a more than one +console+ invocation per
12
+ # request is detected.
13
13
  def console(binding = Bindex.current_bindings.second)
14
14
  raise WebConsole::DoubleRenderError if Thread.current[:__web_console_binding]
15
15
 
@@ -22,26 +22,13 @@ module Kernel
22
22
  end
23
23
  end
24
24
 
25
- module ActionDispatch
26
- class DebugExceptions
27
- def render_exception_with_web_console(request, exception)
28
- render_exception_without_web_console(request, exception).tap do
29
- backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
30
- error = ExceptionWrapper.new(backtrace_cleaner, exception).exception
31
-
32
- # Get the original exception if ExceptionWrapper decides to follow it.
33
- Thread.current[:__web_console_exception] = error
34
-
35
- # ActionView::Template::Error bypass ExceptionWrapper original
36
- # exception following. The backtrace in the view is generated from
37
- # reaching out to original_exception in the view.
38
- if error.is_a?(ActionView::Template::Error)
39
- Thread.current[:__web_console_exception] = error.cause
40
- end
41
- end
42
- end
43
-
44
- alias_method :render_exception_without_web_console, :render_exception
45
- alias_method :render_exception, :render_exception_with_web_console
25
+ class Binding
26
+ # Instructs Web Console to render a console in the current binding, without
27
+ # the need to unroll the stack.
28
+ #
29
+ # Raises +DoubleRenderError+ if a more than one +console+ invocation per
30
+ # request is detected.
31
+ def console
32
+ Kernel.console(self)
46
33
  end
47
34
  end
@@ -13,9 +13,11 @@ module WebConsole
13
13
  end
14
14
 
15
15
  def inject(content)
16
- # Remove any previously set Content-Length header because we modify
17
- # the body. Otherwise the response will be truncated.
18
- @headers.delete("Content-Length")
16
+ # Set Content-Length header to the size of the current body
17
+ # + the extra content. Otherwise the response will be truncated.
18
+ if @headers["Content-Length"]
19
+ @headers["Content-Length"] = (@body.bytesize + content.bytesize).to_s
20
+ end
19
21
 
20
22
  [
21
23
  if position = @body.rindex("</body>")
@@ -0,0 +1,18 @@
1
+ module WebConsole
2
+ module Interceptor
3
+ def self.call(request, exception)
4
+ backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
5
+ error = ActionDispatch::ExceptionWrapper.new(backtrace_cleaner, exception).exception
6
+
7
+ # Get the original exception if ExceptionWrapper decides to follow it.
8
+ Thread.current[:__web_console_exception] = error
9
+
10
+ # ActionView::Template::Error bypass ExceptionWrapper original
11
+ # exception following. The backtrace in the view is generated from
12
+ # reaching out to original_exception in the view.
13
+ if error.is_a?(ActionView::Template::Error)
14
+ Thread.current[:__web_console_exception] = error.cause
15
+ end
16
+ end
17
+ end
18
+ end
@@ -6,11 +6,8 @@ module WebConsole
6
6
  class Middleware
7
7
  TEMPLATES_PATH = File.expand_path("../templates", __FILE__)
8
8
 
9
- cattr_accessor :mount_point
10
- @@mount_point = "/__web_console"
11
-
12
- cattr_accessor :whiny_requests
13
- @@whiny_requests = true
9
+ cattr_accessor :mount_point, default: "/__web_console"
10
+ cattr_accessor :whiny_requests, default: true
14
11
 
15
12
  def initialize(app)
16
13
  @app = app
@@ -19,7 +16,7 @@ module WebConsole
19
16
  def call(env)
20
17
  app_exception = catch :app_exception do
21
18
  request = create_regular_or_whiny_request(env)
22
- return call_app(env) unless request.from_whitelisted_ip?
19
+ return call_app(env) unless request.permitted?
23
20
 
24
21
  if id = id_for_repl_session_update(request)
25
22
  return update_repl_session(id, request)
@@ -27,6 +24,7 @@ module WebConsole
27
24
  return change_stack_trace(id, request)
28
25
  end
29
26
 
27
+
30
28
  status, headers, body = call_app(env)
31
29
 
32
30
  if (session = Session.from(Thread.current)) && acceptable_content_type?(headers)
@@ -54,7 +52,7 @@ module WebConsole
54
52
  private
55
53
 
56
54
  def acceptable_content_type?(headers)
57
- Mime::Type.parse(headers["Content-Type"].to_s).first == Mime[:html]
55
+ headers["Content-Type"].to_s.include?("html")
58
56
  end
59
57
 
60
58
  def json_response(opts = {})
@@ -66,7 +64,6 @@ module WebConsole
66
64
  end
67
65
 
68
66
  def json_response_with_session(id, request, opts = {})
69
- return respond_with_unacceptable_request unless request.acceptable?
70
67
  return respond_with_unavailable_session(id) unless session = Session.find(id)
71
68
 
72
69
  json_response(opts) { yield session }
@@ -113,7 +110,7 @@ module WebConsole
113
110
 
114
111
  def change_stack_trace(id, request)
115
112
  json_response_with_session(id, request) do |session|
116
- session.switch_binding_to(request.params[:frame_id])
113
+ session.switch_binding_to(request.params[:frame_id], request.params[:exception_object_id])
117
114
 
118
115
  { ok: true }
119
116
  end
@@ -3,20 +3,16 @@
3
3
  require "ipaddr"
4
4
 
5
5
  module WebConsole
6
- # Whitelist of allowed networks that can access Web Console.
7
- #
8
- # Networks are represented by standard IPAddr and can be either IPv4 or IPv6
9
- # networks.
10
- class Whitelist
11
- # IPv4 and IPv6 localhost should be always whitelisted.
12
- ALWAYS_WHITELISTED_NETWORKS = %w( 127.0.0.0/8 ::1 )
6
+ class Permissions
7
+ # IPv4 and IPv6 localhost should be always allowed.
8
+ ALWAYS_PERMITTED_NETWORKS = %w( 127.0.0.0/8 ::1 )
13
9
 
14
10
  def initialize(networks = nil)
15
11
  @networks = normalize_networks(networks).map(&method(:coerce_network_to_ipaddr)).uniq
16
12
  end
17
13
 
18
14
  def include?(network)
19
- @networks.any? { |whitelist| whitelist.include?(network.to_s) }
15
+ @networks.any? { |permission| permission.include?(network.to_s) }
20
16
  rescue IPAddr::InvalidAddressError
21
17
  false
22
18
  end
@@ -28,7 +24,7 @@ module WebConsole
28
24
  private
29
25
 
30
26
  def normalize_networks(networks)
31
- Array(networks).concat(ALWAYS_WHITELISTED_NETWORKS)
27
+ Array(networks).concat(ALWAYS_PERMITTED_NETWORKS)
32
28
  end
33
29
 
34
30
  def coerce_network_to_ipaddr(network)
@@ -5,11 +5,12 @@ require "rails/railtie"
5
5
  module WebConsole
6
6
  class Railtie < ::Rails::Railtie
7
7
  config.web_console = ActiveSupport::OrderedOptions.new
8
- config.web_console.whitelisted_ips = %w( 127.0.0.1 ::1 )
9
8
 
10
9
  initializer "web_console.initialize" do
11
10
  require "bindex"
12
11
  require "web_console/extensions"
12
+
13
+ ActionDispatch::DebugExceptions.register_interceptor(Interceptor)
13
14
  end
14
15
 
15
16
  initializer "web_console.development_only" do
@@ -50,9 +51,23 @@ module WebConsole
50
51
  end
51
52
  end
52
53
 
53
- initializer "web_console.whitelisted_ips" do
54
- if whitelisted_ips = config.web_console.whitelisted_ips
55
- Request.whitelisted_ips = Whitelist.new(whitelisted_ips)
54
+ initializer "web_console.permissions" do
55
+ permissions = web_console_permissions
56
+ Request.permissions = Permissions.new(permissions)
57
+ end
58
+
59
+ def web_console_permissions
60
+ case
61
+ when config.web_console.permissions
62
+ config.web_console.permissions
63
+ when config.web_console.allowed_ips
64
+ config.web_console.allowed_ips
65
+ when config.web_console.whitelisted_ips
66
+ ActiveSupport::Deprecation.warn(<<-MSG.squish)
67
+ The config.web_console.whitelisted_ips is deprecated and will be ignored in future release of web_console.
68
+ Please use config.web_console.allowed_ips instead.
69
+ MSG
70
+ config.web_console.whitelisted_ips
56
71
  end
57
72
  end
58
73
 
@@ -1,35 +1,19 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebConsole
4
- # Web Console tailored request object.
5
4
  class Request < ActionDispatch::Request
6
- # Configurable set of whitelisted networks.
7
- cattr_accessor :whitelisted_ips
8
- @@whitelisted_ips = Whitelist.new
5
+ cattr_accessor :permissions, default: Permissions.new
9
6
 
10
- # Define a vendor MIME type. We can call it using Mime[:web_console_v2].
11
- Mime::Type.register "application/vnd.web-console.v2", :web_console_v2
12
-
13
- # Returns whether a request came from a whitelisted IP.
14
- #
15
- # For a request to hit Web Console features, it needs to come from a white
16
- # listed IP.
17
- def from_whitelisted_ip?
18
- whitelisted_ips.include?(strict_remote_ip)
7
+ def permitted?
8
+ permissions.include?(strict_remote_ip)
19
9
  end
20
10
 
21
- # Determines the remote IP using our much stricter whitelist.
22
11
  def strict_remote_ip
23
- GetSecureIp.new(self, whitelisted_ips).to_s
12
+ GetSecureIp.new(self, permissions).to_s
24
13
  rescue ActionDispatch::RemoteIp::IpSpoofAttackError
25
14
  "[Spoofed]"
26
15
  end
27
16
 
28
- # Returns whether the request is acceptable.
29
- def acceptable?
30
- xhr? && accepts.any? { |mime| Mime[:web_console_v2] == mime }
31
- end
32
-
33
17
  private
34
18
 
35
19
  class GetSecureIp < ActionDispatch::RemoteIp::GetIp
@@ -11,8 +11,7 @@ module WebConsole
11
11
  # error pages only, as currently, this is the only client that needs to do
12
12
  # that.
13
13
  class Session
14
- cattr_reader :inmemory_storage
15
- @@inmemory_storage = {}
14
+ cattr_reader :inmemory_storage, default: {}
16
15
 
17
16
  class << self
18
17
  # Finds a persisted session in memory by its id.
@@ -32,9 +31,9 @@ module WebConsole
32
31
  # storage.
33
32
  def from(storage)
34
33
  if exc = storage[:__web_console_exception]
35
- new(ExceptionMapper.new(exc))
34
+ new(ExceptionMapper.follow(exc))
36
35
  elsif binding = storage[:__web_console_binding]
37
- new([binding])
36
+ new([[binding]])
38
37
  end
39
38
  end
40
39
  end
@@ -42,10 +41,11 @@ module WebConsole
42
41
  # An unique identifier for every REPL.
43
42
  attr_reader :id
44
43
 
45
- def initialize(bindings)
44
+ def initialize(exception_mappers)
46
45
  @id = SecureRandom.hex(16)
47
- @bindings = bindings
48
- @evaluator = Evaluator.new(@current_binding = bindings.first)
46
+
47
+ @exception_mappers = exception_mappers
48
+ @evaluator = Evaluator.new(@current_binding = exception_mappers.first.first)
49
49
 
50
50
  store_into_memory
51
51
  end
@@ -60,8 +60,10 @@ module WebConsole
60
60
  # Switches the current binding to the one at specified +index+.
61
61
  #
62
62
  # Returns nothing.
63
- def switch_binding_to(index)
64
- @evaluator = Evaluator.new(@current_binding = @bindings[index.to_i])
63
+ def switch_binding_to(index, exception_object_id)
64
+ bindings = ExceptionMapper.find_binding(@exception_mappers, exception_object_id)
65
+
66
+ @evaluator = Evaluator.new(@current_binding = bindings[index.to_i])
65
67
  end
66
68
 
67
69
  # Returns context of the current binding
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ class SourceLocation
4
+ def initialize(binding)
5
+ @binding = binding
6
+ end
7
+
8
+ if RUBY_VERSION >= "2.6"
9
+ def path() @binding.source_location.first end
10
+ def lineno() @binding.source_location.last end
11
+ else
12
+ def path() @binding.eval("__FILE__") end
13
+ def lineno() @binding.eval("__LINE__") end
14
+ end
15
+ end
@@ -7,8 +7,7 @@ module WebConsole
7
7
  # Rails error pages.
8
8
  class Template
9
9
  # Lets you customize the default templates folder location.
10
- cattr_accessor :template_paths
11
- @@template_paths = [ File.expand_path("../templates", __FILE__) ]
10
+ cattr_accessor :template_paths, default: [ File.expand_path("../templates", __FILE__) ]
12
11
 
13
12
  def initialize(env, session)
14
13
  @env = env
@@ -18,7 +17,7 @@ module WebConsole
18
17
 
19
18
  # Render a template (inferred from +template_paths+) as a plain string.
20
19
  def render(template)
21
- view = View.new(template_paths, instance_values)
20
+ view = View.with_empty_template_cache.with_view_paths(template_paths, instance_values)
22
21
  view.render(template: template, layout: false)
23
22
  end
24
23
  end
@@ -251,12 +251,14 @@ Autocomplete.prototype.removeView = function() {
251
251
  }
252
252
 
253
253
  // HTML strings for dynamic elements.
254
- var consoleInnerHtml = <%= render_inlined_string '_inner_console_markup.html' %>;
255
- var promptBoxHtml = <%= render_inlined_string '_prompt_box_markup.html' %>;
254
+ var consoleInnerHtml = <%= render_inlined_string '_inner_console_markup' %>;
255
+ var promptBoxHtml = <%= render_inlined_string '_prompt_box_markup' %>;
256
256
  // CSS
257
- var consoleStyleCss = <%= render_inlined_string 'style.css' %>;
257
+ var consoleStyleCss = <%= render_inlined_string 'style' %>;
258
258
  // Insert a style element with the unique ID
259
259
  var styleElementId = 'sr02459pvbvrmhco';
260
+ // Nonce to use for CSP
261
+ var styleElementNonce = '<%= @nonce %>';
260
262
 
261
263
  // REPLConsole Constructor
262
264
  function REPLConsole(config) {
@@ -380,8 +382,13 @@ REPLConsole.prototype.install = function(container) {
380
382
  var clientHeightStart = consoleOuter.clientHeight;
381
383
 
382
384
  var doDrag = function(e) {
383
- container.style.height = (startHeight + startY - e.clientY) + 'px';
385
+ var height = startHeight + startY - e.clientY;
384
386
  consoleOuter.scrollTop = scrollTopStart + (clientHeightStart - consoleOuter.clientHeight);
387
+ if (height > document.documentElement.clientHeight) {
388
+ container.style.height = document.documentElement.clientHeight;
389
+ } else {
390
+ container.style.height = height + 'px';
391
+ }
385
392
  shiftConsoleActions();
386
393
  };
387
394
 
@@ -411,6 +418,14 @@ REPLConsole.prototype.install = function(container) {
411
418
  }
412
419
  }
413
420
 
421
+ var observer = new MutationObserver(function(mutationsList) {
422
+ for (let mutation of mutationsList) {
423
+ if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
424
+ shiftConsoleActions();
425
+ }
426
+ }
427
+ });
428
+
414
429
  // Initialize
415
430
  this.container = container;
416
431
  this.outer = consoleOuter;
@@ -422,7 +437,7 @@ REPLConsole.prototype.install = function(container) {
422
437
 
423
438
  findChild(container, 'resizer').addEventListener('mousedown', resizeContainer);
424
439
  findChild(consoleActions, 'close-button').addEventListener('click', closeContainer);
425
- consoleOuter.addEventListener('DOMNodeInserted', shiftConsoleActions);
440
+ observer.observe(consoleOuter, { childList: true, subtree: true });
426
441
 
427
442
  REPLConsole.currentSession = this;
428
443
  };
@@ -436,6 +451,9 @@ REPLConsole.prototype.insertCss = function() {
436
451
  style.type = 'text/css';
437
452
  style.innerHTML = consoleStyleCss;
438
453
  style.id = styleElementId;
454
+ if (styleElementNonce.length > 0) {
455
+ style.nonce = styleElementNonce;
456
+ }
439
457
  document.getElementsByTagName('head')[0].appendChild(style);
440
458
  };
441
459
 
@@ -755,7 +773,7 @@ REPLConsole.prototype.onKeyDown = function(ev) {
755
773
  _this.addToInput(_this.clipboard.value);
756
774
  _this.clipboard.value = "";
757
775
  _this.clipboard.blur();
758
- }, 10);
776
+ }, 100);
759
777
  }
760
778
  }
761
779
 
@@ -871,10 +889,14 @@ REPLConsole.prototype.scrollToBottom = function() {
871
889
  };
872
890
 
873
891
  // Change the binding of the console.
874
- REPLConsole.prototype.switchBindingTo = function(frameId, callback) {
892
+ REPLConsole.prototype.switchBindingTo = function(frameId, exceptionObjectId, callback) {
875
893
  var url = this.getSessionUrl('trace');
876
894
  var params = "frame_id=" + encodeURIComponent(frameId);
877
895
 
896
+ if (exceptionObjectId) {
897
+ params = params + "&exception_object_id=" + encodeURIComponent(exceptionObjectId);
898
+ }
899
+
878
900
  var _this = this;
879
901
  postRequest(url, params, function() {
880
902
  var text = "Context has changed to: " + callback();
@@ -915,7 +937,6 @@ REPLConsole.request = function request(method, url, params, callback) {
915
937
  xhr.open(method, url, true);
916
938
  xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
917
939
  xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest");
918
- xhr.setRequestHeader("Accept", "<%= Mime[:web_console_v2] %>");
919
940
  xhr.send(params);
920
941
 
921
942
  xhr.onreadystatechange = function() {
@@ -8,9 +8,10 @@ for (var i = 0; i < traceFrames.length; i++) {
8
8
  e.preventDefault();
9
9
  var target = e.target;
10
10
  var frameId = target.dataset.frameId;
11
+ var exceptionObjectId = target.dataset.exceptionObjectId;
11
12
 
12
13
  // Change the binding of the console.
13
- changeBinding(frameId, function() {
14
+ changeBinding(frameId, exceptionObjectId, function() {
14
15
  // Rails already handles toggling the select class
15
16
  selectedFrame = target;
16
17
  return target.innerHTML;
@@ -22,8 +23,8 @@ for (var i = 0; i < traceFrames.length; i++) {
22
23
  }
23
24
 
24
25
  // Change the binding of the current session and prompt the user.
25
- function changeBinding(frameId, callback) {
26
- REPLConsole.currentSession.switchBindingTo(frameId, callback);
26
+ function changeBinding(frameId, exceptionObjectId, callback) {
27
+ REPLConsole.currentSession.switchBindingTo(frameId, exceptionObjectId, callback);
27
28
  }
28
29
 
29
30
  function changeSourceExtract(frameId) {
@@ -1 +1 @@
1
- "<%= j yield %>"
1
+ `<%= j yield %>`
@@ -1,4 +1,4 @@
1
- <script type="text/javascript" data-template="<%= @template %>">
1
+ <script type="text/javascript" data-template="<%= @template %>" nonce="<%= @nonce %>">
2
2
  (function() {
3
3
  <%= yield %>
4
4
  }).call(this);
@@ -1,34 +1,182 @@
1
- .console .pos-absolute { position: absolute; }
2
- .console .pos-fixed { position: fixed; }
3
- .console .pos-right { right: 0; }
4
- .console .border-box { box-sizing: border-box; }
5
- .console .layer { width: 100%; height: 100%; }
6
- .console .layer.console-outer { z-index: 1; }
7
- .console .layer.resizer { z-index: 2; }
8
- .console { position: fixed; left: 0; bottom: 0; width: 100%; height: 148px; padding: 0; margin: 0; background: none repeat scroll 0% 0% #333; z-index: 9999; }
9
- .console .console-outer { overflow: auto; padding-top: 4px; }
10
- .console .console-inner { font-family: monospace; font-size: 11px; width: 100%; height: 100%; overflow: none; background: #333; }
11
- .console .console-prompt-box { color: #FFF; }
12
- .console .console-message { color: #1AD027; margin: 0; border: 0; white-space: pre-wrap; background-color: #333; padding: 0; }
13
- .console .console-message.error-message { color: #FC9; }
14
- .console .console-message.notification-message { color: #99F; }
15
- .console .console-message.auto-complete { word-break: break-all; }
16
- .console .console-message.auto-complete .keyword { margin-right: 11px; }
17
- .console .console-message.auto-complete .keyword.selected { background: #FFF; color: #000; }
18
- .console .console-message.auto-complete .hidden { display: none; }
19
- .console .console-message.auto-complete .trimmed { display: none; }
20
- .console .console-hint { color: #096; }
21
- .console .console-focus .console-cursor { background: #FEFEFE; color: #333; font-weight: bold; }
22
- .console .resizer { background: #333; width: 100%; height: 4px; cursor: ns-resize; }
23
- .console .console-actions { padding-right: 3px; }
24
- .console .console-actions .button { float: left; }
25
- .console .button { cursor: pointer; border-radius: 1px; font-family: monospace; font-size: 13px; width: 14px; height: 14px; line-height: 14px; text-align: center; color: #CCC; }
26
- .console .button:hover { background: #666; color: #FFF; }
27
- .console .button.close-button:hover { background: #966; }
28
- .console .clipboard { height: 0px; padding: 0px; margin: 0px; width: 0px; margin-left: -1000px; }
29
- .console .console-prompt-label { display: inline; color: #FFF; background: none repeat scroll 0% 0% #333; border: 0; padding: 0; }
30
- .console .console-prompt-display { display: inline; color: #FFF; background: none repeat scroll 0% 0% #333; border: 0; padding: 0; }
31
- .console.full-screen { height: 100%; }
32
- .console.full-screen .console-outer { padding-top: 3px; }
33
- .console.full-screen .resizer { display: none; }
34
- .console.full-screen .close-button { display: none; }
1
+ .console .pos-absolute {
2
+ position: absolute;
3
+ }
4
+
5
+ .console .pos-fixed {
6
+ position: fixed;
7
+ }
8
+
9
+ .console .pos-right {
10
+ right: 0;
11
+ }
12
+
13
+ .console .border-box {
14
+ box-sizing: border-box;
15
+ }
16
+
17
+ .console .layer {
18
+ width: 100%;
19
+ height: 100%;
20
+ }
21
+
22
+ .console .layer.console-outer {
23
+ z-index: 1;
24
+ }
25
+
26
+ .console .layer.resizer {
27
+ z-index: 2;
28
+ }
29
+
30
+ .console {
31
+ position: fixed;
32
+ left: 0;
33
+ bottom: 0;
34
+ width: 100%;
35
+ height: 148px;
36
+ padding: 0;
37
+ margin: 0;
38
+ background: none repeat scroll 0% 0% #333;
39
+ z-index: 9999;
40
+ }
41
+
42
+ .console .console-outer {
43
+ overflow: auto;
44
+ padding-top: 4px;
45
+ }
46
+
47
+ .console .console-inner {
48
+ font-family: monospace;
49
+ font-size: 11px;
50
+ width: 100%;
51
+ height: 100%;
52
+ overflow: unset;
53
+ background: #333;
54
+ }
55
+
56
+ .console .console-prompt-box {
57
+ color: #fff;
58
+ }
59
+
60
+ .console .console-message {
61
+ color: #1ad027;
62
+ margin: 0;
63
+ border: 0;
64
+ white-space: pre-wrap;
65
+ background-color: #333;
66
+ padding: 0;
67
+ }
68
+
69
+ .console .console-message.error-message {
70
+ color: #fc9;
71
+ }
72
+
73
+ .console .console-message.notification-message {
74
+ color: #99f;
75
+ }
76
+
77
+ .console .console-message.auto-complete {
78
+ word-break: break-all;
79
+ }
80
+
81
+ .console .console-message.auto-complete .keyword {
82
+ margin-right: 11px;
83
+ }
84
+
85
+ .console .console-message.auto-complete .keyword.selected {
86
+ background: #fff;
87
+ color: #000;
88
+ }
89
+
90
+ .console .console-message.auto-complete .hidden {
91
+ display: none;
92
+ }
93
+
94
+ .console .console-message.auto-complete .trimmed {
95
+ display: none;
96
+ }
97
+
98
+ .console .console-hint {
99
+ color: #096;
100
+ }
101
+
102
+ .console .console-focus .console-cursor {
103
+ background: #fefefe;
104
+ color: #333;
105
+ font-weight: bold;
106
+ }
107
+
108
+ .console .resizer {
109
+ background: #333;
110
+ width: 100%;
111
+ height: 4px;
112
+ cursor: ns-resize;
113
+ }
114
+
115
+ .console .console-actions {
116
+ padding-right: 3px;
117
+ }
118
+
119
+ .console .console-actions .button {
120
+ float: left;
121
+ }
122
+
123
+ .console .button {
124
+ cursor: pointer;
125
+ border-radius: 1px;
126
+ font-family: monospace;
127
+ font-size: 13px;
128
+ width: 14px;
129
+ height: 14px;
130
+ line-height: 14px;
131
+ text-align: center;
132
+ color: #ccc;
133
+ }
134
+
135
+ .console .button:hover {
136
+ background: #666;
137
+ color: #fff;
138
+ }
139
+
140
+ .console .button.close-button:hover {
141
+ background: #966;
142
+ }
143
+
144
+ .console .clipboard {
145
+ height: 0px;
146
+ padding: 0px;
147
+ margin: 0px;
148
+ width: 0px;
149
+ margin-left: -1000px;
150
+ }
151
+
152
+ .console .console-prompt-label {
153
+ display: inline;
154
+ color: #fff;
155
+ background: none repeat scroll 0% 0% #333;
156
+ border: 0;
157
+ padding: 0;
158
+ }
159
+
160
+ .console .console-prompt-display {
161
+ display: inline;
162
+ color: #fff;
163
+ background: none repeat scroll 0% 0% #333;
164
+ border: 0;
165
+ padding: 0;
166
+ }
167
+
168
+ .console.full-screen {
169
+ height: 100%;
170
+ }
171
+
172
+ .console.full-screen .console-outer {
173
+ padding-top: 3px;
174
+ }
175
+
176
+ .console.full-screen .resizer {
177
+ display: none;
178
+ }
179
+
180
+ .console.full-screen .close-button {
181
+ display: none;
182
+ }
@@ -3,7 +3,6 @@
3
3
  require "action_view"
4
4
  require "web_console"
5
5
  require "web_console/testing/helper"
6
- Mime = { web_console_v2: "fake" }
7
6
 
8
7
  module WebConsole
9
8
  module Testing
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebConsole
4
- VERSION = "3.7.0"
4
+ VERSION = "4.2.0"
5
5
  end
@@ -22,6 +22,7 @@ module WebConsole
22
22
  # leaking globals, unless you explicitly want to.
23
23
  def render_javascript(template)
24
24
  assign(template: template)
25
+ assign(nonce: @env["action_dispatch.content_security_policy_nonce"])
25
26
  render(template: template, layout: "layouts/javascript")
26
27
  end
27
28
 
@@ -3,13 +3,13 @@
3
3
  module WebConsole
4
4
  # Noisy wrapper around +Request+.
5
5
  #
6
- # If any calls to +from_whitelisted_ip?+ and +acceptable_content_type?+
6
+ # If any calls to +permitted?+ and +acceptable_content_type?+
7
7
  # return false, an info log message will be displayed in users' logs.
8
8
  class WhinyRequest < SimpleDelegator
9
- def from_whitelisted_ip?
10
- whine_unless request.from_whitelisted_ip? do
9
+ def permitted?
10
+ whine_unless request.permitted? do
11
11
  "Cannot render console from #{request.strict_remote_ip}! " \
12
- "Allowed networks: #{request.whitelisted_ips}"
12
+ "Allowed networks: #{request.permissions}"
13
13
  end
14
14
  end
15
15
 
data/lib/web_console.rb CHANGED
@@ -11,12 +11,14 @@ module WebConsole
11
11
  autoload :ExceptionMapper
12
12
  autoload :Session
13
13
  autoload :Injector
14
+ autoload :Interceptor
14
15
  autoload :Request
15
16
  autoload :WhinyRequest
16
- autoload :Whitelist
17
+ autoload :Permissions
17
18
  autoload :Template
18
19
  autoload :Middleware
19
20
  autoload :Context
21
+ autoload :SourceLocation
20
22
 
21
23
  autoload_at "web_console/errors" do
22
24
  autoload :Error
metadata CHANGED
@@ -1,17 +1,17 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: web-console
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.7.0
4
+ version: 4.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Charlie Somerville
7
+ - Hailey Somerville
8
8
  - Genadi Samokovarov
9
9
  - Guillermo Iguaran
10
10
  - Ryan Dao
11
- autorequire:
11
+ autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2018-09-02 00:00:00.000000000 Z
14
+ date: 2021-11-17 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties
@@ -19,42 +19,42 @@ dependencies:
19
19
  requirements:
20
20
  - - ">="
21
21
  - !ruby/object:Gem::Version
22
- version: '5.0'
22
+ version: 6.0.0
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: '5.0'
29
+ version: 6.0.0
30
30
  - !ruby/object:Gem::Dependency
31
31
  name: activemodel
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  requirements:
34
34
  - - ">="
35
35
  - !ruby/object:Gem::Version
36
- version: '5.0'
36
+ version: 6.0.0
37
37
  type: :runtime
38
38
  prerelease: false
39
39
  version_requirements: !ruby/object:Gem::Requirement
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: '5.0'
43
+ version: 6.0.0
44
44
  - !ruby/object:Gem::Dependency
45
45
  name: actionview
46
46
  requirement: !ruby/object:Gem::Requirement
47
47
  requirements:
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
- version: '5.0'
50
+ version: 6.0.0
51
51
  type: :runtime
52
52
  prerelease: false
53
53
  version_requirements: !ruby/object:Gem::Requirement
54
54
  requirements:
55
55
  - - ">="
56
56
  - !ruby/object:Gem::Version
57
- version: '5.0'
57
+ version: 6.0.0
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: bindex
60
60
  requirement: !ruby/object:Gem::Requirement
@@ -69,9 +69,9 @@ dependencies:
69
69
  - - ">="
70
70
  - !ruby/object:Gem::Version
71
71
  version: 0.4.0
72
- description:
72
+ description:
73
73
  email:
74
- - charlie@charliesomerville.com
74
+ - hailey@hailey.lol
75
75
  - gsamokovarov@gmail.com
76
76
  - guilleiguaran@gmail.com
77
77
  - daoduyducduong@gmail.com
@@ -91,11 +91,14 @@ files:
91
91
  - lib/web_console/exception_mapper.rb
92
92
  - lib/web_console/extensions.rb
93
93
  - lib/web_console/injector.rb
94
+ - lib/web_console/interceptor.rb
94
95
  - lib/web_console/locales/en.yml
95
96
  - lib/web_console/middleware.rb
97
+ - lib/web_console/permissions.rb
96
98
  - lib/web_console/railtie.rb
97
99
  - lib/web_console/request.rb
98
100
  - lib/web_console/session.rb
101
+ - lib/web_console/source_location.rb
99
102
  - lib/web_console/tasks/extensions.rake
100
103
  - lib/web_console/tasks/templates.rake
101
104
  - lib/web_console/template.rb
@@ -116,12 +119,11 @@ files:
116
119
  - lib/web_console/version.rb
117
120
  - lib/web_console/view.rb
118
121
  - lib/web_console/whiny_request.rb
119
- - lib/web_console/whitelist.rb
120
122
  homepage: https://github.com/rails/web-console
121
123
  licenses:
122
124
  - MIT
123
125
  metadata: {}
124
- post_install_message:
126
+ post_install_message:
125
127
  rdoc_options: []
126
128
  require_paths:
127
129
  - lib
@@ -129,16 +131,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
129
131
  requirements:
130
132
  - - ">="
131
133
  - !ruby/object:Gem::Version
132
- version: 2.2.2
134
+ version: '2.5'
133
135
  required_rubygems_version: !ruby/object:Gem::Requirement
134
136
  requirements:
135
137
  - - ">="
136
138
  - !ruby/object:Gem::Version
137
139
  version: '0'
138
140
  requirements: []
139
- rubyforge_project:
140
- rubygems_version: 2.7.6
141
- signing_key:
141
+ rubygems_version: 3.1.6
142
+ signing_key:
142
143
  specification_version: 4
143
144
  summary: A debugging tool for your Ruby on Rails applications.
144
145
  test_files: []