inline_forms 8.1.53 → 8.1.55
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 +4 -4
- data/CHANGELOG.md +29 -0
- data/app/views/devise/passwords/edit.html.erb +1 -1
- data/app/views/devise/passwords/new.html.erb +1 -1
- data/app/views/devise/shared/_header_and_errors.html.erb +9 -2
- data/lib/inline_forms/gem_files.rb +32 -0
- data/lib/inline_forms/version.rb +1 -1
- data/test/gem_package_modes_test.rb +86 -0
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 7fff4c0c21d69de2e6836a1a6a16e1e293b8c740fe0615a429ab6775f89fd59a
|
|
4
|
+
data.tar.gz: 479db5cb0c201625bc4c5561f1a3188d3e87ce128387c6a7e08c708d749600b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 20499e3a0edf5819e20dc5a2d6893835acb72a08039df25190f184136c93d8c8904de2c5f6def7d3746dd7a1804eb01f51cc3560bd70d5d196e4a95be62911bf
|
|
7
|
+
data.tar.gz: 809595fc167bab2e5c9015fb034dcc10be2ff6d5dde3b958d24cdf2ae96ed027ed56577342e5e56f4d5e3f6a02311cb7662a736dfe89636456f96961442bb5bb
|
data/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,35 @@ All notable changes to this project are documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [8.1.55] - 2026-10-04
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **Published gems were unreadable for other users.** RubyGems packages each file with its on-disk mode, and `gem install` restores it. The release checkout is group-only (`rw-rw----`), so every file in the published 8.1.53 gems was `0660`. After `gem install` only the installing user and group could read them: for anyone else `require "inline_forms"` failed silently (Bundler swallows that LoadError), so the app died at boot with `uninitialized constant InlineForms`. A Docker image that installs gems as root and runs as another user could not boot at all. Gem builds now package every file as `0644`, or `0755` when the owner may execute it, whatever the checkout's modes: `InlineFormsGemFiles` wraps `Gem::Package#add_files`, and all three gemspecs in this repo load it, so `gem build`, `rake build` and the CI full gate are all covered. validation_hints 8.1.55 has the same fix. 8.1.53 cannot be republished (RubyGems never accepts a version twice), so apps on 8.1.53 should move to 8.1.55.
|
|
12
|
+
|
|
13
|
+
### Tests
|
|
14
|
+
|
|
15
|
+
- Gem: `test/gem_package_modes_test.rb`: group-only files on disk are packaged `0644`/`0755`, and the inline_forms, inline_forms_installer and inline_forms_schema_edit gemspecs build with every file world-readable.
|
|
16
|
+
|
|
17
|
+
### Lockstep
|
|
18
|
+
|
|
19
|
+
- validation_hints 8.1.55, inline_forms_installer 8.1.55, inline_forms_schema_edit 8.1.55.
|
|
20
|
+
|
|
21
|
+
## [8.1.54] - 2026-10-04
|
|
22
|
+
|
|
23
|
+
### Fixed
|
|
24
|
+
|
|
25
|
+
- **"Forgot your password?" and the password reset page raised.** Devise 5 removed `devise_error_messages!`, and the gem's `devise/passwords/new` and `devise/passwords/edit` still called it, so both pages failed with `undefined method 'devise_error_messages!'` in every generated app. They now render Devise's own `devise/shared/error_messages` partial (`render "devise/shared/error_messages", resource: resource`).
|
|
26
|
+
- **`devise/shared/_header_and_errors`** (not rendered by the gem's own views; kept for host apps that render it). It looked up a translation named after the app (`t application_name`, which renders a translation_missing span), called the removed `devise_error_messages!`, and looked up `inline_forms.devise.` when `@default_message` was unset. It now shows `t('application_name', default: application_name)` like the `inline_forms` layout's title, Devise's error list when the resource has errors, and the `inline_forms.devise.<@default_message>` text only when `@default_message` is set.
|
|
27
|
+
|
|
28
|
+
### Tests
|
|
29
|
+
|
|
30
|
+
- Example app: `example_app_devise_passwords_test.rb`: the forgot-password and reset-password pages render, an unknown email re-renders the form with Devise's error list, and `_header_and_errors` shows the app name and the resource errors. The engine's dummy app has no Devise, so these tests live in the example app only.
|
|
31
|
+
|
|
32
|
+
### Lockstep
|
|
33
|
+
|
|
34
|
+
- validation_hints 8.1.54, inline_forms_installer 8.1.54, inline_forms_schema_edit 8.1.54.
|
|
35
|
+
|
|
7
36
|
## [8.1.53] - 2026-10-04
|
|
8
37
|
|
|
9
38
|
### Fixed
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
|
|
1
|
+
<%# Unused by the gem's own devise views; kept for host apps that render it. %>
|
|
2
|
+
<%# Same title source as layouts/inline_forms; Devise 5 dropped %>
|
|
3
|
+
<%# devise_error_messages!, so errors use Devise's own error_messages partial. %>
|
|
4
|
+
<div id="large_title"><%= t('application_name', default: application_name) %></div>
|
|
2
5
|
<div id="flash_message">
|
|
3
|
-
|
|
6
|
+
<% if resource.errors.any? %>
|
|
7
|
+
<%= render "devise/shared/error_messages", resource: resource %>
|
|
8
|
+
<% elsif @default_message.present? %>
|
|
9
|
+
<%= t("inline_forms.devise.#{@default_message}") %>
|
|
10
|
+
<% end %>
|
|
4
11
|
</div>
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# -*- encoding: utf-8 -*-
|
|
2
2
|
|
|
3
|
+
require "delegate"
|
|
4
|
+
require "rubygems/package"
|
|
5
|
+
|
|
3
6
|
module InlineFormsGemFiles
|
|
4
7
|
INSTALLER_FILE_PREFIXES = %w[
|
|
5
8
|
bin/inline_forms
|
|
@@ -68,4 +71,33 @@ module InlineFormsGemFiles
|
|
|
68
71
|
include_installer ? !installer_file : installer_file
|
|
69
72
|
end
|
|
70
73
|
end
|
|
74
|
+
|
|
75
|
+
# Mode a file gets inside the .gem: 0755 if the owner may execute it,
|
|
76
|
+
# else 0644. RubyGems packages each file's on-disk mode (File.lstat) and
|
|
77
|
+
# `gem install` restores it, and this checkout is group-only (rw-rw----),
|
|
78
|
+
# so 8.1.53 shipped every file as 0660: only the installing user and group
|
|
79
|
+
# could read the installed gem, `require "inline_forms"` failed silently
|
|
80
|
+
# for anyone else (Bundler swallows the LoadError), and a Docker image that
|
|
81
|
+
# installs as root and runs as another user could not boot.
|
|
82
|
+
def packaged_mode(mode)
|
|
83
|
+
(mode & 0o100).zero? ? 0o644 : 0o755
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Wraps the tar writer Gem::Package#add_files writes to, so every file
|
|
87
|
+
# goes in with packaged_mode instead of its on-disk mode.
|
|
88
|
+
class ReadableTar < SimpleDelegator
|
|
89
|
+
def add_file_simple(name, mode, size, &block)
|
|
90
|
+
__getobj__.add_file_simple(name, InlineFormsGemFiles.packaged_mode(mode), size, &block)
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
module ReadablePackage
|
|
95
|
+
def add_files(tar)
|
|
96
|
+
super(ReadableTar.new(tar))
|
|
97
|
+
end
|
|
98
|
+
end
|
|
71
99
|
end
|
|
100
|
+
|
|
101
|
+
# Loaded by every gemspec in this repo, so `gem build`, `rake build` and the
|
|
102
|
+
# CI full gate all package world-readable files whatever the checkout's modes.
|
|
103
|
+
Gem::Package.prepend(InlineFormsGemFiles::ReadablePackage) unless Gem::Package <= InlineFormsGemFiles::ReadablePackage
|
data/lib/inline_forms/version.rb
CHANGED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
$LOAD_PATH.unshift File.expand_path("../lib", __dir__)
|
|
4
|
+
|
|
5
|
+
require "minitest/autorun"
|
|
6
|
+
require "tmpdir"
|
|
7
|
+
require "zlib"
|
|
8
|
+
require "inline_forms/gem_files"
|
|
9
|
+
|
|
10
|
+
# 8.1.53 shipped every file as 0660 (the checkout's group-only modes), so an
|
|
11
|
+
# installed gem was unreadable for anyone outside the installing user and
|
|
12
|
+
# group. Gem builds now package 0644 / 0755 whatever the on-disk modes.
|
|
13
|
+
class GemPackageModesTest < Minitest::Test
|
|
14
|
+
REPO_ROOT = File.expand_path("..", __dir__)
|
|
15
|
+
|
|
16
|
+
def packaged_modes(gem_path)
|
|
17
|
+
modes = {}
|
|
18
|
+
File.open(gem_path, "rb") do |io|
|
|
19
|
+
Gem::Package::TarReader.new(io).each do |entry|
|
|
20
|
+
next unless entry.full_name == "data.tar.gz"
|
|
21
|
+
|
|
22
|
+
Gem::Package::TarReader.new(Zlib::GzipReader.new(entry)).each do |file|
|
|
23
|
+
modes[file.full_name] = file.header.mode & 0o777
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
modes
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def build(spec, dir, gem_dir)
|
|
31
|
+
gem_path = File.join(gem_dir, "#{spec.full_name}.gem")
|
|
32
|
+
Dir.chdir(dir) do
|
|
33
|
+
package = Gem::Package.new(gem_path)
|
|
34
|
+
package.spec = spec
|
|
35
|
+
Gem::DefaultUserInteraction.use_ui(Gem::SilentUI.new) { package.build(true) }
|
|
36
|
+
end
|
|
37
|
+
gem_path
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_packaged_mode_keeps_only_the_owner_execute_bit
|
|
41
|
+
assert_equal 0o644, InlineFormsGemFiles.packaged_mode(0o100660)
|
|
42
|
+
assert_equal 0o644, InlineFormsGemFiles.packaged_mode(0o100600)
|
|
43
|
+
assert_equal 0o755, InlineFormsGemFiles.packaged_mode(0o100770)
|
|
44
|
+
assert_equal 0o755, InlineFormsGemFiles.packaged_mode(0o100700)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_group_only_files_are_packaged_world_readable
|
|
48
|
+
Dir.mktmpdir do |src|
|
|
49
|
+
Dir.mktmpdir do |out|
|
|
50
|
+
File.write(File.join(src, "plain.rb"), "# plain\n")
|
|
51
|
+
File.write(File.join(src, "tool"), "#!/bin/sh\n")
|
|
52
|
+
File.chmod(0o660, File.join(src, "plain.rb"))
|
|
53
|
+
File.chmod(0o700, File.join(src, "tool"))
|
|
54
|
+
|
|
55
|
+
spec = Gem::Specification.new do |s|
|
|
56
|
+
s.name = "modes_probe"
|
|
57
|
+
s.version = "0.0.1"
|
|
58
|
+
s.summary = "probe"
|
|
59
|
+
s.authors = ["probe"]
|
|
60
|
+
s.files = %w[plain.rb tool]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
modes = packaged_modes(build(spec, src, out))
|
|
64
|
+
|
|
65
|
+
assert_equal({ "plain.rb" => 0o644, "tool" => 0o755 }, modes)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_every_gemspec_in_the_repo_packages_world_readable_files
|
|
71
|
+
%w[inline_forms.gemspec inline_forms_installer.gemspec
|
|
72
|
+
inline_forms_schema_edit/inline_forms_schema_edit.gemspec].each do |gemspec|
|
|
73
|
+
path = File.join(REPO_ROOT, gemspec)
|
|
74
|
+
spec = Gem::Specification.load(path)
|
|
75
|
+
refute_nil spec, gemspec
|
|
76
|
+
|
|
77
|
+
Dir.mktmpdir do |out|
|
|
78
|
+
modes = packaged_modes(build(spec, File.dirname(path), out))
|
|
79
|
+
|
|
80
|
+
refute_empty modes, gemspec
|
|
81
|
+
unreadable = modes.reject { |_, mode| (mode & 0o444) == 0o444 }
|
|
82
|
+
assert_empty unreadable, "#{gemspec}: not world-readable in the .gem"
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: inline_forms
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 8.1.
|
|
4
|
+
version: 8.1.55
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ace Suares
|
|
@@ -308,6 +308,7 @@ files:
|
|
|
308
308
|
- test/dummy/config/initializers/paper_trail_yaml_safe_load.rb
|
|
309
309
|
- test/dummy/config/routes.rb
|
|
310
310
|
- test/form_element_from_callee_test.rb
|
|
311
|
+
- test/gem_package_modes_test.rb
|
|
311
312
|
- test/inline_edit_polymorphic_path_test.rb
|
|
312
313
|
- test/inline_forms_addto_generator_test.rb
|
|
313
314
|
- test/inline_forms_generator_test.rb
|
|
@@ -388,6 +389,7 @@ test_files:
|
|
|
388
389
|
- test/dummy/config/initializers/paper_trail_yaml_safe_load.rb
|
|
389
390
|
- test/dummy/config/routes.rb
|
|
390
391
|
- test/form_element_from_callee_test.rb
|
|
392
|
+
- test/gem_package_modes_test.rb
|
|
391
393
|
- test/inline_edit_polymorphic_path_test.rb
|
|
392
394
|
- test/inline_forms_addto_generator_test.rb
|
|
393
395
|
- test/inline_forms_generator_test.rb
|