ideasbugs 1.0.0 → 1.0.1

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: 61cbcd9d82d7ea0e24313084b45e017ec6c4448c7851d2f94c48adf7604b05b3
4
- data.tar.gz: 1fce4b379cc43bdb594cfbfef919cf37bfb485293c698106001e814fdd412dbb
3
+ metadata.gz: 76f8be375e72b7a33a5f0f5b6bc0fc895ced476aeb3b5325a950fa0a7bd01475
4
+ data.tar.gz: 565e8e8d07ea9c2604748e88774ebe67bec1473648110b97f0c797911b72127d
5
5
  SHA512:
6
- metadata.gz: c2a99f724a3f3ff162f0ffc64d8ee8fe42b37bf16a62ee24533ba0e607a6689969f45f009e34faf7ec272ffe475e8d98b1e1ea5b1af5ace6488e06ed524000fc
7
- data.tar.gz: b592e770c7f666372239c72d76a7796ef24fe62fcd4e7227ea464d70bd0421c3d7f5a233d3af113e695e24932fc4a191e9082c9d300356b1a6a7757fdb167fcb
6
+ metadata.gz: a9623c31745f085489bf222390b964324391f63396d87f3cfa32714a4cbc29180a2703350571840006cc81121e92541a06224a7d831cdb407e7027f6afa9d56a
7
+ data.tar.gz: eb8cade7b5bed11612632d95e83cc828c831351721df1dfbb43ea0c54f11dbe7d6ee5f24b79c123f6b6bfcee215a1d3d2140fbd9a3b9c17fb1bdaab883dab58e
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.0.1] - 2026-08-11
6
+
7
+ - **Screenshot responses now stream privately through the gated engine route.**
8
+ Responses are marked `private, no-store` and `nosniff`, so sensitive screen
9
+ captures are not buffered or left cacheable by the browser.
10
+ - **Stored page context is now privacy-filtered.** Only bounded HTTP(S) URLs
11
+ without credentials, query strings, or fragments are retained.
12
+
5
13
  ## [1.0.0] - 2026-08-11
6
14
 
7
15
  - **The documented integration surface is now the stable 1.x contract.**
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'uri'
4
+
3
5
  module Ideasbugs
4
6
  # Who is asking, which tenant they are in, and the gates that answer both.
5
7
  #
@@ -47,5 +49,23 @@ module Ideasbugs
47
49
  def tenant_scope
48
50
  Feedback.for_tenant(current_tenant)
49
51
  end
52
+
53
+ # Browser URLs can carry password-reset tokens, signed ids, and campaign
54
+ # details in their query or fragment. Store only a bounded HTTP(S) location
55
+ # without credentials before it reaches the feedback table.
56
+ def clean_page_url(value)
57
+ raw = value.to_s
58
+ return if raw.blank? || raw.length > 2_048
59
+
60
+ uri = URI.parse(raw)
61
+ return unless %w[http https].include?(uri.scheme&.downcase)
62
+ return if uri.host.blank? || uri.userinfo.present?
63
+
64
+ uri.query = nil
65
+ uri.fragment = nil
66
+ uri.to_s.first(255)
67
+ rescue URI::InvalidURIError
68
+ nil
69
+ end
50
70
  end
51
71
  end
@@ -7,14 +7,15 @@ module Ideasbugs
7
7
  # be reachable without passing the same gate as the dashboard — regardless of
8
8
  # how the host app configures (or doesn't configure) blob access.
9
9
  class ScreenshotsController < DashboardController
10
+ include ActiveStorage::Streaming if defined?(::ActiveStorage::Streaming)
11
+
10
12
  def show
11
13
  screenshot = Feedback.for_tenant(current_tenant)
12
14
  .find(params[:feedback_id]).screenshots.find(params[:id])
13
15
 
14
- send_data screenshot.download,
15
- filename: screenshot.filename.to_s,
16
- type: screenshot.content_type,
17
- disposition: 'inline'
16
+ response.headers['X-Content-Type-Options'] = 'nosniff'
17
+ response.headers['Cache-Control'] = 'private, no-store'
18
+ send_blob_stream screenshot.blob, disposition: 'inline'
18
19
  end
19
20
 
20
21
  private
@@ -23,6 +23,7 @@ module Ideasbugs
23
23
 
24
24
  def create
25
25
  feedback = Feedback.new(feedback_params)
26
+ feedback.page_url = clean_page_url(feedback.page_url)
26
27
  feedback.user_agent = request.user_agent
27
28
  feedback.tenant = current_tenant
28
29
  attribute_author(feedback)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ideasbugs
4
- VERSION = '1.0.0'
4
+ VERSION = '1.0.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ideasbugs
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yaroslav Shmarov