openreceive-rails 0.2.1 → 0.2.3
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 +43 -0
- data/lib/generators/openreceive/install/install_generator.rb +10 -6
- data/lib/generators/openreceive/install/templates/migration.rb +4 -3
- data/lib/openreceive/configuration.rb +49 -1
- data/lib/openreceive/engine.rb +18 -1
- data/lib/openreceive/rails/version.rb +1 -1
- metadata +25 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 4fd30ded365e254b6529fc4c006d8ec597a83f659cdf4b60b34127817d7fc995
|
|
4
|
+
data.tar.gz: b272234e0a5eadb74ac2c63a9df71d3af0cc62d290497005af206653a489743d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 85bdd9b23bc16d13d4e1b3e4d7bc788cf2987c44431a9c345c9a6f48c63aea11f27e8c8ab7d40b1343e787048a15768eed8baaf40bf60d2e6b6b27fedb1d5d47
|
|
7
|
+
data.tar.gz: 8ed6a9cd303864c971b5b8597e34cbe2e1e6b2cf9e5b1651a38f6183e43f4f69ab1a05af90c364f237b3698432c101c059eaf61bba9738cae692a4aea65ffb93
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.2.3 - 2026-08-25
|
|
4
|
+
|
|
5
|
+
The Ruby gems release in lockstep with the npm workspace version. The full
|
|
6
|
+
release narrative lives in the repository-root
|
|
7
|
+
[CHANGELOG](https://github.com/openreceive/openreceive/blob/master/CHANGELOG.md);
|
|
8
|
+
entries here are scoped to this gem.
|
|
9
|
+
|
|
10
|
+
- The mounted engine inherits `openreceive-server`'s `POST /checkouts` change:
|
|
11
|
+
the response now carries `payment_methods` alongside `checkout` (HTTP
|
|
12
|
+
contract 0.4.1). No configuration change; hosts using `@openreceive/browser`
|
|
13
|
+
see no difference.
|
|
14
|
+
|
|
15
|
+
## 0.2.2 - 2026-08-25
|
|
16
|
+
|
|
17
|
+
The Ruby gems release in lockstep with the npm workspace version. The full
|
|
18
|
+
release narrative lives in the repository-root
|
|
19
|
+
[CHANGELOG](https://github.com/openreceive/openreceive/blob/master/CHANGELOG.md);
|
|
20
|
+
entries here are scoped to this gem.
|
|
21
|
+
|
|
22
|
+
- **Fixed: the generated migration would not load.** `openreceive:install` wrote
|
|
23
|
+
`class CreateOpenreceiveTables`, but the engine's own acronym inflection makes
|
|
24
|
+
Rails resolve the file name to `CreateOpenReceiveTables`, so
|
|
25
|
+
`bin/rails db:migrate` failed with `NameError` on every install. The template
|
|
26
|
+
declares the class Rails looks for, and a new generator test registers the
|
|
27
|
+
acronym and runs the migration for real.
|
|
28
|
+
- **`nwc-ruby` is now a runtime dependency.** Building the client from `NWC_URI`
|
|
29
|
+
is this gem's DEFAULT wallet path, so installing only `openreceive-rails`
|
|
30
|
+
used to boot fine and then 500 on the first checkout with
|
|
31
|
+
`Install nwc-ruby or configure nwc_client.` `config.nwc_client` remains the
|
|
32
|
+
override for hosts bringing their own client.
|
|
33
|
+
- **Fixed: the boot preflight failed `assets:precompile`.** An image build is a
|
|
34
|
+
production boot with no wallet secrets mounted, so the eager preflight failed
|
|
35
|
+
the build rather than the deploy. Asset builds are now detected
|
|
36
|
+
(`SECRET_KEY_BASE_DUMMY`, or an `assets:precompile`/`clean`/`clobber` rake
|
|
37
|
+
invocation) and skipped with a log line.
|
|
38
|
+
- **Added `config.eager_preflight`** (default `true`) — the supported opt-out
|
|
39
|
+
for any other boot that must come up without wallet secrets. It disables the
|
|
40
|
+
BOOT check only; the wallet is still checked on the first request, and a real
|
|
41
|
+
production boot with no `NWC_URI` still fails closed.
|
|
42
|
+
- The generated migration's `payment_hash` check constraint hoists its adapter
|
|
43
|
+
branch to a local, so the first file a developer opens after running the
|
|
44
|
+
generator reads as ordinary Ruby.
|
|
45
|
+
|
|
3
46
|
## 0.2.1 - 2026-08-24
|
|
4
47
|
|
|
5
48
|
The Ruby gems release in lockstep with the npm workspace version. The full
|
|
@@ -61,15 +61,19 @@ module OpenReceive
|
|
|
61
61
|
# the app actually runs. MySQL's bare REGEXP follows the column's
|
|
62
62
|
# case-insensitive collation, so its rendering pins case sensitivity
|
|
63
63
|
# with REGEXP_LIKE's 'c' flag.
|
|
64
|
+
#
|
|
65
|
+
# Rendered as the right-hand side of `hash_check =` at method-body
|
|
66
|
+
# indentation, so the branch reads as ordinary Ruby in the file the
|
|
67
|
+
# developer opens right after running the generator.
|
|
64
68
|
def payment_hash_check_sql
|
|
65
|
-
return %("REGEXP_LIKE(payment_hash, '^[0-9a-f]{64}$', 'c')") if mysql_adapter?
|
|
69
|
+
return %( "REGEXP_LIKE(payment_hash, '^[0-9a-f]{64}$', 'c')") if mysql_adapter?
|
|
66
70
|
|
|
67
|
-
<<~RUBY.
|
|
71
|
+
<<~RUBY.chomp.gsub(/^/, " ")
|
|
68
72
|
if connection.adapter_name.downcase.include?("postgres")
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
+
"payment_hash ~ '^[0-9a-f]{64}$'"
|
|
74
|
+
else
|
|
75
|
+
"length(payment_hash) = 64 AND payment_hash NOT GLOB '*[^0-9a-f]*'"
|
|
76
|
+
end
|
|
73
77
|
RUBY
|
|
74
78
|
end
|
|
75
79
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# durable reconcile gate they share. Same host database, never a second one.
|
|
5
5
|
#
|
|
6
6
|
<%= fulfillment_note("# ") %>
|
|
7
|
-
class
|
|
7
|
+
class CreateOpenReceiveTables < ActiveRecord::Migration[<%= migration_version %>]
|
|
8
8
|
def change
|
|
9
9
|
create_table :openreceive_payments do |t|
|
|
10
10
|
# Your order id, as you passed it.
|
|
@@ -54,8 +54,9 @@ class CreateOpenreceiveTables < ActiveRecord::Migration[<%= migration_version %>
|
|
|
54
54
|
add_check_constraint :openreceive_payments,
|
|
55
55
|
"status IN ('pending', 'settled', 'expired', 'failed', 'attention')",
|
|
56
56
|
name: "openreceive_payments_status_check"
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
hash_check =
|
|
58
|
+
<%= payment_hash_check_sql %>
|
|
59
|
+
add_check_constraint :openreceive_payments, hash_check,
|
|
59
60
|
name: "openreceive_payments_payment_hash_check"
|
|
60
61
|
|
|
61
62
|
# Which schema generation is installed. The engine refuses to run against a
|
|
@@ -36,7 +36,7 @@ module OpenReceive
|
|
|
36
36
|
:resolve_checkout, :on_checkout_created,
|
|
37
37
|
:rate_limit, :rate_limiting, :client_ip, :price_provider,
|
|
38
38
|
:swap_providers, :price_currencies, :allow_spend_capable_wallet,
|
|
39
|
-
:opportunistic_reconcile
|
|
39
|
+
:opportunistic_reconcile, :eager_preflight
|
|
40
40
|
|
|
41
41
|
def initialize
|
|
42
42
|
@parent_controller = "ActionController::Base"
|
|
@@ -78,6 +78,13 @@ module OpenReceive
|
|
|
78
78
|
# `bin/rails openreceive:notifications` worker owns scanning), or a Hash
|
|
79
79
|
# with min_interval_seconds to tune.
|
|
80
80
|
@opportunistic_reconcile = true
|
|
81
|
+
# The production boot preflight (Engine's after_initialize): build the
|
|
82
|
+
# service, and with it the wallet check, so a missing NWC_URI or a
|
|
83
|
+
# spend-capable wallet stops a deploy instead of the first customer. ON by
|
|
84
|
+
# default. Asset builds are detected and skipped automatically (see
|
|
85
|
+
# OpenReceive.eager_preflight?); set false for any other boot that must
|
|
86
|
+
# come up without wallet secrets.
|
|
87
|
+
@eager_preflight = true
|
|
81
88
|
end
|
|
82
89
|
|
|
83
90
|
def service
|
|
@@ -353,6 +360,8 @@ module OpenReceive
|
|
|
353
360
|
end
|
|
354
361
|
end
|
|
355
362
|
|
|
363
|
+
# Rake tasks that are an ASSET BUILD, never a serving boot.
|
|
364
|
+
ASSET_BUILD_TASKS = %w[assets:precompile assets:clean assets:clobber].freeze
|
|
356
365
|
|
|
357
366
|
class << self
|
|
358
367
|
def configure
|
|
@@ -368,6 +377,45 @@ module OpenReceive
|
|
|
368
377
|
@configured == true
|
|
369
378
|
end
|
|
370
379
|
|
|
380
|
+
# Whether the engine's production boot preflight should run (see Engine).
|
|
381
|
+
#
|
|
382
|
+
# It must not run during `rails assets:precompile`. That is a production
|
|
383
|
+
# boot by RAILS_ENV, but it happens inside an image build where no wallet
|
|
384
|
+
# secrets are mounted — they arrive at deploy time — so the preflight would
|
|
385
|
+
# fail the BUILD, long before the deploy it exists to protect. Rails' own
|
|
386
|
+
# generated Dockerfile has exactly this shape.
|
|
387
|
+
def eager_preflight?
|
|
388
|
+
preflight_skip_reason.nil?
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
# nil when the boot preflight should run; otherwise the short reason the
|
|
392
|
+
# engine logs, so an operator who expected a fail-closed boot and did not
|
|
393
|
+
# get one can see why in the same log line.
|
|
394
|
+
def preflight_skip_reason
|
|
395
|
+
return "config.eager_preflight = false" unless config.eager_preflight
|
|
396
|
+
return "asset build" if asset_build?
|
|
397
|
+
|
|
398
|
+
nil
|
|
399
|
+
end
|
|
400
|
+
|
|
401
|
+
# An asset build, by the two signals that are actually reliable.
|
|
402
|
+
# `Rails.const_defined?(:Console)`-style sniffing is not: the console
|
|
403
|
+
# constant exists in a serving boot too.
|
|
404
|
+
def asset_build?
|
|
405
|
+
# Rails' own convention for "a production boot with a throwaway secret",
|
|
406
|
+
# set by its generated Dockerfile alongside `rails assets:precompile`.
|
|
407
|
+
return true unless ENV["SECRET_KEY_BASE_DUMMY"].to_s.empty?
|
|
408
|
+
|
|
409
|
+
# The honest test for older/hand-written build shapes: what was actually
|
|
410
|
+
# invoked. `SECRET_KEY_BASE=dummy rails assets:precompile` lands here.
|
|
411
|
+
return false unless defined?(::Rake)
|
|
412
|
+
|
|
413
|
+
::Rake.application.top_level_tasks.any? { |task| ASSET_BUILD_TASKS.include?(task.to_s) }
|
|
414
|
+
rescue StandardError
|
|
415
|
+
# Rake present but without a usable application: not an asset build.
|
|
416
|
+
false
|
|
417
|
+
end
|
|
418
|
+
|
|
371
419
|
def config
|
|
372
420
|
@config ||= Configuration.new
|
|
373
421
|
end
|
data/lib/openreceive/engine.rb
CHANGED
|
@@ -17,6 +17,13 @@ module OpenReceive
|
|
|
17
17
|
# customer-facing 500s on the first checkout. Skipped when the host never
|
|
18
18
|
# ran OpenReceive.configure (gem installed, installer not run yet), and
|
|
19
19
|
# outside production so tests and consoles boot without a live wallet.
|
|
20
|
+
#
|
|
21
|
+
# `rails assets:precompile` is the one production boot that must NOT be
|
|
22
|
+
# preflighted: it runs inside an image build, before any wallet secret is
|
|
23
|
+
# mounted, so checking there fails the build rather than the deploy. It is
|
|
24
|
+
# detected and skipped automatically (OpenReceive.eager_preflight?), and
|
|
25
|
+
# `config.eager_preflight = false` is the explicit lever for any other
|
|
26
|
+
# secretless boot.
|
|
20
27
|
config.after_initialize do
|
|
21
28
|
if OpenReceive.configured?
|
|
22
29
|
if OpenReceive.config.on_paid.equal?(OpenReceive::LOGGING_ON_PAID)
|
|
@@ -26,7 +33,17 @@ module OpenReceive
|
|
|
26
33
|
"config/initializers/openreceive.rb."
|
|
27
34
|
)
|
|
28
35
|
end
|
|
29
|
-
|
|
36
|
+
if ::Rails.env.production?
|
|
37
|
+
skipped = OpenReceive.preflight_skip_reason
|
|
38
|
+
if skipped.nil?
|
|
39
|
+
OpenReceive.config.service
|
|
40
|
+
else
|
|
41
|
+
::Rails.logger&.info(
|
|
42
|
+
"[openreceive] boot preflight skipped (#{skipped}) — the wallet is " \
|
|
43
|
+
"checked on the first request instead."
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
30
47
|
end
|
|
31
48
|
end
|
|
32
49
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: openreceive-rails
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.3
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- OpenReceive
|
|
@@ -15,28 +15,28 @@ dependencies:
|
|
|
15
15
|
requirements:
|
|
16
16
|
- - '='
|
|
17
17
|
- !ruby/object:Gem::Version
|
|
18
|
-
version: 0.2.
|
|
18
|
+
version: 0.2.3
|
|
19
19
|
type: :runtime
|
|
20
20
|
prerelease: false
|
|
21
21
|
version_requirements: !ruby/object:Gem::Requirement
|
|
22
22
|
requirements:
|
|
23
23
|
- - '='
|
|
24
24
|
- !ruby/object:Gem::Version
|
|
25
|
-
version: 0.2.
|
|
25
|
+
version: 0.2.3
|
|
26
26
|
- !ruby/object:Gem::Dependency
|
|
27
27
|
name: openreceive-server
|
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
|
29
29
|
requirements:
|
|
30
30
|
- - '='
|
|
31
31
|
- !ruby/object:Gem::Version
|
|
32
|
-
version: 0.2.
|
|
32
|
+
version: 0.2.3
|
|
33
33
|
type: :runtime
|
|
34
34
|
prerelease: false
|
|
35
35
|
version_requirements: !ruby/object:Gem::Requirement
|
|
36
36
|
requirements:
|
|
37
37
|
- - '='
|
|
38
38
|
- !ruby/object:Gem::Version
|
|
39
|
-
version: 0.2.
|
|
39
|
+
version: 0.2.3
|
|
40
40
|
- !ruby/object:Gem::Dependency
|
|
41
41
|
name: rails
|
|
42
42
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -51,6 +51,26 @@ dependencies:
|
|
|
51
51
|
- - ">="
|
|
52
52
|
- !ruby/object:Gem::Version
|
|
53
53
|
version: '8.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: nwc-ruby
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.2'
|
|
61
|
+
- - ">="
|
|
62
|
+
- !ruby/object:Gem::Version
|
|
63
|
+
version: 0.2.4
|
|
64
|
+
type: :runtime
|
|
65
|
+
prerelease: false
|
|
66
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
67
|
+
requirements:
|
|
68
|
+
- - "~>"
|
|
69
|
+
- !ruby/object:Gem::Version
|
|
70
|
+
version: '0.2'
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: 0.2.4
|
|
54
74
|
- !ruby/object:Gem::Dependency
|
|
55
75
|
name: sqlite3
|
|
56
76
|
requirement: !ruby/object:Gem::Requirement
|