i18n_proofreading 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: 6f31aa1eec6874e5a80180fbd106c1f6ea7f073241e234c8b0c9c64ae474ba45
4
- data.tar.gz: c1a02f46f915c3fd496793f9b33885026c090fb70b0fcb0474d017ac0c2bbd14
3
+ metadata.gz: 1018fa5f4f5be802e224bfc1a8bf5e93b1cff5c9122e854327792a9ffc89c0eb
4
+ data.tar.gz: 48b4c23cef0d8aac0ba47f996be007b259d3354fffa6065a1fea5f820b4802eb
5
5
  SHA512:
6
- metadata.gz: dfca53a8ba1b338b6bca4b29060c0c5f7ecb8077817d26fc6078d22b971195d7577db3ef7a433f0252213b1214bd09adbdec0daaa66938708a3556e9ca766701
7
- data.tar.gz: 9bd50ba50b9a8c43b26839a9467b43cc50c96ba18e25ed0738433d0013ce18606566c61ca3b954022281ee40266701aa2c9efd5f6414baac5e561fa5b21a5338
6
+ metadata.gz: cb442c1774c324987f44e8a347f74f061cd7ee64388df006f77b4a7d94ff6b6e57844303190f9fce36d7f556d7391160a1ef611e2424fe9a2a090d78638f16df
7
+ data.tar.gz: 3094f3c4160701c912116a499be621486b1f718168450b8030956bb43d3b1864576e7a278a95e948552444969c45835b150f7a05cd50106408bd9b3dfa381587
data/AGENTS.md CHANGED
@@ -5,7 +5,7 @@ Instructions for coding agents. Two audiences:
5
5
  - **[Installing i18n_proofreading into a Rails app](#installing-into-a-rails-app)** — you are working in a host app and were asked to add in-context translation review or a way for someone to suggest better wording.
6
6
  - **[Working on the gem itself](#working-on-the-gem-itself)** — you are working in this repository.
7
7
 
8
- Requirements: Ruby 3.2–4.0, Rails 7.1–8.1. The widget needs the CSRF token from `csrf_meta_tags`, which a standard Rails layout already has.
8
+ Requirements: Ruby >= 3.2, Rails >= 7.1 and < 9. The widget needs the CSRF token from `csrf_meta_tags`, which a standard Rails layout already has.
9
9
 
10
10
  **Read this first: the gem never writes to your locale files, and it is not a production tool.** Both are deliberate, and both are covered below.
11
11
 
@@ -137,6 +137,11 @@ The tool's own UI ships in 26 languages, RTL mirrored, and follows system light/
137
137
 
138
138
  ## Working on the gem itself
139
139
 
140
+ The development toolchain is pinned to Ruby 4.0.5 in `mise.toml`. Do not use
141
+ macOS's `/usr/bin/ruby`. In shells, hooks, or automation where mise activation
142
+ is uncertain, explicitly prepend the configured Ruby, for example
143
+ `PATH="$(mise where ruby)/bin:$PATH" bundle exec rake test`.
144
+
140
145
  ```bash
141
146
  bundle exec rake test # minitest, dummy app under test/dummy
142
147
  bundle exec rubocop # must be clean
data/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [1.0.1] - 2026-08-11
6
+
7
+ - **A failing `on_submit` hook no longer turns a saved suggestion into a 500.**
8
+ The failure is logged after persistence, so host notifications cannot make
9
+ the review submission appear lost.
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 I18nProofreading
4
6
  # Who is asking, and the gates that answer it.
5
7
  #
@@ -37,5 +39,23 @@ module I18nProofreading
37
39
 
38
40
  @current_author = I18nProofreading.config.current_user.call(request)
39
41
  end
42
+
43
+ # Browser URLs can carry password-reset tokens, signed ids, and campaign
44
+ # details in their query or fragment. Store only a bounded HTTP(S) location
45
+ # without credentials before it reaches the suggestion table.
46
+ def clean_page_url(value)
47
+ raw = value.to_s
48
+ return if raw.blank? || raw.length > 2_048
49
+
50
+ uri = URI.parse(raw)
51
+ return unless %w[http https].include?(uri.scheme&.downcase)
52
+ return if uri.host.blank? || uri.userinfo.present?
53
+
54
+ uri.query = nil
55
+ uri.fragment = nil
56
+ uri.to_s.first(255)
57
+ rescue URI::InvalidURIError
58
+ nil
59
+ end
40
60
  end
41
61
  end
@@ -37,10 +37,11 @@ module I18nProofreading
37
37
 
38
38
  def create
39
39
  suggestion = Suggestion.new(suggestion_params)
40
+ suggestion.page_url = clean_page_url(suggestion.page_url)
40
41
  attribute_author(suggestion)
41
42
 
42
43
  if suggestion.save
43
- I18nProofreading.config.on_submit.call(suggestion)
44
+ notify_host(suggestion)
44
45
  head :created
45
46
  else
46
47
  render json: { errors: suggestion.errors.full_messages }, status: :unprocessable_entity
@@ -49,6 +50,15 @@ module I18nProofreading
49
50
 
50
51
  private
51
52
 
53
+ # The host's hook must never turn a saved suggestion into a 500 — the
54
+ # suggestion is in the database; notification failures are the host's
55
+ # logs' problem.
56
+ def notify_host(suggestion)
57
+ I18nProofreading.config.on_submit.call(suggestion)
58
+ rescue StandardError => e
59
+ Rails.logger.error("i18n_proofreading: on_submit hook raised #{e.class}: #{e.message}")
60
+ end
61
+
52
62
  def attribute_author(suggestion)
53
63
  author = current_author
54
64
  return unless author
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module I18nProofreading
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: i18n_proofreading
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