tina4ruby 3.13.134 → 3.13.136

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: 1d0d4c7801e0766f00041e3d004a0318d7bd4e22d9b4a4d102d05516b89ebba1
4
- data.tar.gz: 837234011a9a76e4d0733d8a05936bdb08a5bcb8681638679064b51d84dc2392
3
+ metadata.gz: 76e4848167cfc04c327d95658f37ec1e8c95448f143000eaec69218527b86b9f
4
+ data.tar.gz: 97775ba90cbd5c991b44d27af3c5a94db4288f3e70feb07147fc4fe3df672ba0
5
5
  SHA512:
6
- metadata.gz: bfd2d4b058f1366920dd46b66f1d59f504f1b30cc649b71ecc7f5d8f8d15a385eaa19b5de9078768c0f935aba9a3115e8e10efe72806cfa53be5aca73f5c2caf
7
- data.tar.gz: 178596fd8db63262bc35aeb25ae13e11c609b3f50a85bc06d91ce12063b9739973f80ce5783ec5a330d115b3b07e9389718f2316d8c53590b47867ad777b193d
6
+ metadata.gz: f548932ee5b0b890a972e09727b2c73264cc30188e8a9ee24ef7f61cfa165a71b52797cf8e0c69c6331e3a7be2d5b82b5bc41c791c32ef88ef3e2760a44d6c65
7
+ data.tar.gz: cd7ab7cb88ca3775bbdd49ed1e1a187e0a5846383815735eec415edfc12bd3318c36f85b6b77d479659c2fdf86bc38fcb8b0caa2838d138c2de9eb4ea8eba46e
data/CHANGELOG.md CHANGED
@@ -6,6 +6,15 @@ number means the same thing everywhere.
6
6
  **The authoritative release notes for every shipped version live in the documentation:**
7
7
  https://tina4.com/ruby/36-releases
8
8
 
9
+ ## 3.13.135
10
+
11
+ Fix release. The dev-admin version check returns no version and a reason when it cannot
12
+ reach RubyGems (set TINA4_VERSION_CHECK_URL to override the registry), so the toolbar reports
13
+ "could not check" instead of a false "up to date". Web Push pads the VAPID private scalar to
14
+ the fixed 32-byte width, so a leading-zero scalar no longer produces a key the app's own
15
+ validation rejects; the public point and the ECDH secret were already correct. Full notes:
16
+ https://tina4.com/ruby/36-releases
17
+
9
18
  ## 3.13.134
10
19
 
11
20
  Feature 140 Web Push is now available with provider-neutral subscription delivery,
@@ -842,23 +842,43 @@ module Tina4
842
842
  [status, { "content-type" => "application/json; charset=utf-8" }, [body]]
843
843
  end
844
844
 
845
+ # A version check that did not happen says so.
846
+ #
847
+ # This used to fall back to latest = current on any failure, and the
848
+ # toolbar renders that as a green "Latest: vX — You are up to date!". A
849
+ # developer several releases behind, on a machine with no route out, was
850
+ # told the opposite of the truth — and the toolbar's own "Could not check
851
+ # for updates" branch could never fire, because the failure arrived as a
852
+ # success.
853
+ #
854
+ # latest is nil when the check could not be made, and error says why. The
855
+ # registry URL is TINA4_VERSION_CHECK_URL when set (a mirror, or a test's
856
+ # own server), else RubyGems.
845
857
  def version_check_payload
846
858
  current = Tina4::VERSION
847
- latest = current
859
+ url = ENV.fetch("TINA4_VERSION_CHECK_URL",
860
+ "https://rubygems.org/api/v1/versions/tina4ruby/latest.json")
848
861
  begin
849
- uri = URI.parse("https://rubygems.org/api/v1/versions/tina4ruby/latest.json")
862
+ uri = URI.parse(url)
850
863
  http = Net::HTTP.new(uri.host, uri.port)
851
- http.use_ssl = true
864
+ http.use_ssl = (uri.scheme == "https")
852
865
  http.open_timeout = 5
853
866
  http.read_timeout = 5
854
- req = Net::HTTP::Get.new(uri)
855
- resp = http.request(req)
856
- if resp.is_a?(Net::HTTPSuccess)
857
- data = JSON.parse(resp.body)
858
- latest = data["version"] || current
867
+ resp = http.request(Net::HTTP::Get.new(uri))
868
+ unless resp.is_a?(Net::HTTPSuccess)
869
+ return { current: current, latest: nil,
870
+ error: "RubyGems answered #{resp.code}" }
859
871
  end
860
- rescue StandardError
861
- # Offline or timeout return current as latest
872
+ latest = JSON.parse(resp.body)["version"]
873
+ # Reaching RubyGems is not the same as learning the version: an
874
+ # answer with none in it is the same lie by another route.
875
+ if latest.nil? || latest.to_s.empty?
876
+ return { current: current, latest: nil,
877
+ error: "RubyGems did not report a version" }
878
+ end
879
+ rescue StandardError => e
880
+ return { current: current, latest: nil,
881
+ error: "#{e.class}: #{e.message}" }
862
882
  end
863
883
  { current: current, latest: latest }
864
884
  end
@@ -71,7 +71,7 @@
71
71
 
72
72
  // Build a system
73
73
  const ui = SwaggerUIBundle({
74
- url: "{SWAGGER_ROUTE}/swagger.json",
74
+ url: "/swagger/openapi.json",
75
75
  dom_id: '#swagger-ui',
76
76
  deepLinking: true,
77
77
  presets: [
data/lib/tina4/push.rb CHANGED
@@ -20,11 +20,20 @@ module Tina4
20
20
  require_openssl
21
21
  key = OpenSSL::PKey::EC.generate("prime256v1")
22
22
  {
23
+ # The public point keeps its width -- the 0x04 lead byte is non-zero, so
24
+ # to_s(2) never drops it. The private SCALAR has no such guard: OpenSSL
25
+ # strips a leading zero byte, so ~0.3% of keys come back 31 bytes and the
26
+ # app's own 32-byte validation would then reject the key it just made.
23
27
  "publicKey" => b64(key.public_key.to_bn.to_s(2)),
24
- "privateKey" => b64(key.private_key.to_s(2))
28
+ "privateKey" => b64(pad32(key.private_key.to_s(2)))
25
29
  }
26
30
  end
27
31
 
32
+ # Left-pad big-endian EC material to the fixed 32-byte P-256 field width.
33
+ def self.pad32(bytes)
34
+ bytes.b.rjust(32, "\x00".b)
35
+ end
36
+
28
37
  def initialize(subject: nil, public_key: nil, private_key: nil, ttl: 60, urgency: nil)
29
38
  @subject = (subject || ENV.fetch("TINA4_VAPID_SUBJECT", "")).strip
30
39
  @public_key = (public_key || ENV.fetch("TINA4_VAPID_PUBLIC", "")).strip
@@ -1033,6 +1033,14 @@ module Tina4
1033
1033
  el.className = 't4-ok';
1034
1034
  el.innerHTML = 'Latest: <strong class="t4-ok">v' + latest + '</strong> &mdash; You are up to date!';
1035
1035
  }
1036
+ // A check that did not happen is not a clean bill of health. The
1037
+ // server sends latest: null when it could not reach the registry,
1038
+ // and saying so is the whole point -- "up to date" here would be a
1039
+ // guess dressed as a fact.
1040
+ function couldNotCheck(el, why) {
1041
+ el.className = 't4-err';
1042
+ el.textContent = 'Could not check for updates' + (why ? ' (' + why + ')' : '');
1043
+ }
1036
1044
  function checkVersion() {
1037
1045
  if (modal.style.display === 'block') { modal.style.display = 'none'; return; }
1038
1046
  modal.style.display = 'block';
@@ -1041,6 +1049,10 @@ module Tina4
1041
1049
  el.textContent = 'Checking for updates...';
1042
1050
  fetch('/__dev/api/version-check').then(function (r) { return r.json(); }).then(function (d) {
1043
1051
  var latest = d.latest, current = d.current;
1052
+ // A check that did not happen says so -- act on a missing
1053
+ // latest before comparing, so a null never falls into the
1054
+ // up-to-date branch.
1055
+ if (!latest) { couldNotCheck(el, d.error); return; }
1044
1056
  if (latest === current) { upToDate(el, latest); return; }
1045
1057
  var cP = current.split('.').map(Number), lP = latest.split('.').map(Number);
1046
1058
  var isNewer = false, i, c, l;
data/lib/tina4/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tina4
4
- VERSION = "3.13.134"
4
+ VERSION = "3.13.136"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tina4ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.13.134
4
+ version: 3.13.136
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tina4 Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-09-05 00:00:00.000000000 Z
11
+ date: 2026-09-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack