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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1018fa5f4f5be802e224bfc1a8bf5e93b1cff5c9122e854327792a9ffc89c0eb
|
|
4
|
+
data.tar.gz: 48b4c23cef0d8aac0ba47f996be007b259d3354fffa6065a1fea5f820b4802eb
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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
|
-
|
|
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
|