spree_core 5.3.4 → 5.3.5
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/app/jobs/spree/images/save_from_url_job.rb +47 -23
- data/app/models/spree/gift_card_batch.rb +4 -0
- data/app/models/spree/order.rb +2 -2
- data/app/models/spree/refund.rb +4 -0
- data/app/models/spree/store_credit.rb +4 -0
- data/app/models/spree/webhook_endpoint.rb +17 -0
- data/app/services/spree/data_feeds/google/required_attributes.rb +3 -8
- data/app/services/spree/gift_cards/apply.rb +5 -4
- data/config/locales/en.yml +4 -0
- data/lib/spree/core/configuration.rb +1 -0
- data/lib/spree/core/version.rb +1 -1
- metadata +17 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6ed5afbde4c027a14e708b2f10a4585eab43df462da64c93d409336561bd3e45
|
|
4
|
+
data.tar.gz: 7f10df74f02a7770d794793e396486adefcc2349c6e2f0232ed5771b6dec83b2
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 588d726ccf12398f757ded2e252e1fb90de5a11e2c5863aa06bb27a489dd6ba3e9f1993ef68e6370b4476fa8846f59b85a60046d13953723cec4140b516128ea
|
|
7
|
+
data.tar.gz: 11a5f3e4298506982cecdf1dea096852e500ed157cce75343659252d3573d3e499a3d39ab82553be8e70fb7c8af414e93e016fcb8204b3c6a9cebe03521fcee7
|
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
require 'open-uri'
|
|
2
2
|
require 'openssl'
|
|
3
|
+
require 'ssrf_filter'
|
|
4
|
+
require 'tempfile'
|
|
3
5
|
|
|
4
6
|
module Spree
|
|
5
7
|
module Images
|
|
6
8
|
class SaveFromUrlJob < ::Spree::BaseJob
|
|
7
9
|
queue_as Spree.queues.images
|
|
8
|
-
retry_on ActiveRecord::RecordInvalid,
|
|
10
|
+
retry_on ActiveRecord::RecordInvalid, wait: :polynomially_longer, attempts: Spree::Config.images_save_from_url_job_attempts.to_i
|
|
9
11
|
discard_on URI::InvalidURIError
|
|
12
|
+
discard_on SsrfFilter::Error
|
|
10
13
|
|
|
11
14
|
def perform(viewable_id, viewable_type, external_url, external_id = nil, position = nil)
|
|
12
15
|
viewable = viewable_type.safe_constantize.find(viewable_id)
|
|
@@ -29,34 +32,55 @@ module Spree
|
|
|
29
32
|
# still trigger save! if position has changed
|
|
30
33
|
image.save! and return if image_already_saved?(image, external_url)
|
|
31
34
|
|
|
32
|
-
|
|
33
|
-
unless %w[http https].include?(uri.scheme)
|
|
34
|
-
raise URI::InvalidURIError, "Invalid URL scheme: #{uri.scheme}. Only http and https are allowed."
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
file = uri.open(
|
|
38
|
-
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
39
|
-
'Accept' => 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
|
|
40
|
-
'Accept-Language' => 'en-US,en;q=0.9',
|
|
41
|
-
'Accept-Encoding' => 'gzip, deflate, br',
|
|
42
|
-
'Cache-Control' => 'no-cache',
|
|
43
|
-
'Pragma' => 'no-cache',
|
|
44
|
-
read_timeout: 60,
|
|
45
|
-
ssl_verify_mode: OpenSSL::SSL::VERIFY_PEER,
|
|
46
|
-
redirect: true
|
|
47
|
-
)
|
|
48
|
-
filename = File.basename(uri.path)
|
|
49
|
-
|
|
50
|
-
image.attachment.attach(io: file, filename: filename)
|
|
51
|
-
image.external_url = external_url
|
|
52
|
-
image.external_id = external_id if external_id.present? && image.respond_to?(:external_id)
|
|
53
|
-
image.save!
|
|
35
|
+
download_and_attach_image(external_url, image, external_id)
|
|
54
36
|
rescue ActiveStorage::IntegrityError => e
|
|
55
37
|
raise e unless Rails.env.test?
|
|
56
38
|
end
|
|
57
39
|
|
|
58
40
|
private
|
|
59
41
|
|
|
42
|
+
def download_and_attach_image(external_url, image, external_id)
|
|
43
|
+
max_size = Spree::Config.max_image_download_size
|
|
44
|
+
|
|
45
|
+
response = SsrfFilter.get(
|
|
46
|
+
external_url,
|
|
47
|
+
headers: {
|
|
48
|
+
'User-Agent' => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36',
|
|
49
|
+
'Accept' => 'image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
|
|
50
|
+
'Accept-Language' => 'en-US,en;q=0.9',
|
|
51
|
+
'Accept-Encoding' => 'gzip, deflate, br',
|
|
52
|
+
'Cache-Control' => 'no-cache',
|
|
53
|
+
'Pragma' => 'no-cache'
|
|
54
|
+
},
|
|
55
|
+
http_options: {
|
|
56
|
+
read_timeout: 60,
|
|
57
|
+
open_timeout: 30
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
body = response.body
|
|
62
|
+
if body.bytesize > max_size
|
|
63
|
+
raise StandardError, "Image file size exceeds the maximum allowed size of #{max_size} bytes"
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
uri = URI.parse(external_url)
|
|
67
|
+
filename = File.basename(uri.path)
|
|
68
|
+
tempfile = Tempfile.new(['spree_image', File.extname(uri.path)], binmode: true)
|
|
69
|
+
|
|
70
|
+
begin
|
|
71
|
+
tempfile.write(body)
|
|
72
|
+
tempfile.rewind
|
|
73
|
+
|
|
74
|
+
image.attachment.attach(io: tempfile, filename: filename)
|
|
75
|
+
image.external_url = external_url
|
|
76
|
+
image.external_id = external_id if external_id.present? && image.respond_to?(:external_id)
|
|
77
|
+
image.save!
|
|
78
|
+
ensure
|
|
79
|
+
tempfile.close
|
|
80
|
+
tempfile.unlink
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
60
84
|
def image_already_saved?(image, external_url)
|
|
61
85
|
image.persisted? && image.attachment.attached? && image.external_url.present? && external_url == image.external_url
|
|
62
86
|
end
|
data/app/models/spree/order.rb
CHANGED
|
@@ -275,9 +275,9 @@ module Spree
|
|
|
275
275
|
# @return [Boolean]
|
|
276
276
|
def order_refunded?
|
|
277
277
|
return false if item_count.zero?
|
|
278
|
+
return false if refunds_total.zero?
|
|
278
279
|
|
|
279
|
-
|
|
280
|
-
refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
280
|
+
payment_state.in?(%w[void failed]) || refunds_total == total_minus_store_credits - additional_tax_total.abs
|
|
281
281
|
end
|
|
282
282
|
|
|
283
283
|
def refunds_total
|
data/app/models/spree/refund.rb
CHANGED
|
@@ -52,6 +52,10 @@ module Spree
|
|
|
52
52
|
extend Spree::DisplayMoney
|
|
53
53
|
money_methods :amount, :amount_used, :amount_remaining, :amount_authorized
|
|
54
54
|
|
|
55
|
+
def amount=(amount)
|
|
56
|
+
self[:amount] = Spree::LocalizedNumber.parse(amount)
|
|
57
|
+
end
|
|
58
|
+
|
|
55
59
|
self.whitelisted_ransackable_attributes = %w[user_id created_by_id amount currency type_id]
|
|
56
60
|
self.whitelisted_ransackable_associations = %w[type user created_by]
|
|
57
61
|
|
|
@@ -1,17 +1,23 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'ssrf_filter'
|
|
4
|
+
require 'resolv'
|
|
5
|
+
|
|
3
6
|
module Spree
|
|
4
7
|
class WebhookEndpoint < Spree.base_class
|
|
5
8
|
acts_as_paranoid
|
|
6
9
|
|
|
7
10
|
include Spree::SingleStoreResource
|
|
8
11
|
|
|
12
|
+
encrypts :secret_key, deterministic: true if Rails.configuration.active_record.encryption.include?(:primary_key)
|
|
13
|
+
|
|
9
14
|
belongs_to :store, class_name: 'Spree::Store'
|
|
10
15
|
has_many :webhook_deliveries, class_name: 'Spree::WebhookDelivery', dependent: :destroy_async
|
|
11
16
|
|
|
12
17
|
validates :store, :url, presence: true
|
|
13
18
|
validates :url, format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), message: :invalid_url }
|
|
14
19
|
validates :active, inclusion: { in: [true, false] }
|
|
20
|
+
validate :url_must_not_resolve_to_private_ip, if: -> { url.present? && url_changed? }
|
|
15
21
|
|
|
16
22
|
before_create :generate_secret_key
|
|
17
23
|
|
|
@@ -49,5 +55,16 @@ module Spree
|
|
|
49
55
|
def generate_secret_key
|
|
50
56
|
self.secret_key ||= SecureRandom.hex(32)
|
|
51
57
|
end
|
|
58
|
+
|
|
59
|
+
def url_must_not_resolve_to_private_ip
|
|
60
|
+
uri = URI.parse(url)
|
|
61
|
+
blacklist = SsrfFilter::IPV4_BLACKLIST + SsrfFilter::IPV6_BLACKLIST
|
|
62
|
+
addresses = Resolv.getaddresses(uri.host)
|
|
63
|
+
if addresses.any? { |addr| blacklist.any? { |range| range.include?(IPAddr.new(addr)) } }
|
|
64
|
+
errors.add(:url, :internal_address_not_allowed)
|
|
65
|
+
end
|
|
66
|
+
rescue URI::InvalidURIError, Resolv::ResolvError, IPAddr::InvalidAddressError, ArgumentError
|
|
67
|
+
# URI format validation handles invalid URLs; DNS failures are not SSRF
|
|
68
|
+
end
|
|
52
69
|
end
|
|
53
70
|
end
|
|
@@ -41,15 +41,10 @@ module Spree
|
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def get_image_link(variant, product)
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
image = variant.thumbnail || product.thumbnail
|
|
45
|
+
return if image.nil?
|
|
46
46
|
|
|
47
|
-
|
|
48
|
-
if img.nil?
|
|
49
|
-
img = product.images.first&.plp_url
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
img
|
|
47
|
+
Rails.application.routes.url_helpers.cdn_image_url(image.attachment.variant(:xlarge))
|
|
53
48
|
end
|
|
54
49
|
|
|
55
50
|
def format_price(variant)
|
|
@@ -25,15 +25,16 @@ module Spree
|
|
|
25
25
|
return failure(:gift_card_mismatched_customer) if gift_card.user != order.user
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
amount = [gift_card.amount_remaining, order.total].min
|
|
29
28
|
store = order.store
|
|
30
29
|
|
|
31
|
-
return failure(:gift_card_no_amount_remaining) unless amount.positive? || order.total.zero?
|
|
32
|
-
|
|
33
30
|
payment_method = ensure_store_credit_payment_method!(store)
|
|
34
31
|
|
|
35
|
-
gift_card.lock!
|
|
36
32
|
order.with_lock do
|
|
33
|
+
gift_card.lock!
|
|
34
|
+
amount = [gift_card.amount_remaining, order.total].min
|
|
35
|
+
|
|
36
|
+
return failure(:gift_card_no_amount_remaining) unless amount.positive? || order.total.zero?
|
|
37
|
+
|
|
37
38
|
store_credit = gift_card.store_credits.create!(
|
|
38
39
|
store: store,
|
|
39
40
|
user: order.user,
|
data/config/locales/en.yml
CHANGED
|
@@ -361,6 +361,10 @@ en:
|
|
|
361
361
|
cannot_destroy_if_attached_to_line_items: Cannot delete Variants that are added to placed Orders. In such cases, please discontinue them.
|
|
362
362
|
must_supply_price_for_variant_or_master: Must supply price for variant or master price for product.
|
|
363
363
|
no_master_variant_found_to_infer_price: No master variant found to infer price
|
|
364
|
+
spree/webhook_endpoint:
|
|
365
|
+
attributes:
|
|
366
|
+
url:
|
|
367
|
+
internal_address_not_allowed: must not point to an internal or private network address
|
|
364
368
|
spree/wished_item:
|
|
365
369
|
attributes:
|
|
366
370
|
variant:
|
|
@@ -47,6 +47,7 @@ module Spree
|
|
|
47
47
|
preference :expedited_exchanges_days_window, :integer, default: 14 # the amount of days the customer has to return their item after the expedited exchange is shipped in order to avoid being charged
|
|
48
48
|
preference :geocode_addresses, :boolean, default: true
|
|
49
49
|
preference :images_save_from_url_job_attempts, :integer, default: 5
|
|
50
|
+
preference :max_image_download_size, :integer, default: 20_971_520 # 20 MB in bytes
|
|
50
51
|
|
|
51
52
|
# Preprocessed product image variant sizes at 2x retina resolution.
|
|
52
53
|
# These variants are generated on upload to reduce runtime processing.
|
data/lib/spree/core/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: spree_core
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 5.3.
|
|
4
|
+
version: 5.3.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Sean Schofield
|
|
@@ -573,6 +573,20 @@ dependencies:
|
|
|
573
573
|
- - "~>"
|
|
574
574
|
- !ruby/object:Gem::Version
|
|
575
575
|
version: '2.0'
|
|
576
|
+
- !ruby/object:Gem::Dependency
|
|
577
|
+
name: ssrf_filter
|
|
578
|
+
requirement: !ruby/object:Gem::Requirement
|
|
579
|
+
requirements:
|
|
580
|
+
- - "~>"
|
|
581
|
+
- !ruby/object:Gem::Version
|
|
582
|
+
version: '1.0'
|
|
583
|
+
type: :runtime
|
|
584
|
+
prerelease: false
|
|
585
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
586
|
+
requirements:
|
|
587
|
+
- - "~>"
|
|
588
|
+
- !ruby/object:Gem::Version
|
|
589
|
+
version: '1.0'
|
|
576
590
|
description: Spree Models, Helpers, Services and core libraries
|
|
577
591
|
email: hello@spreecommerce.org
|
|
578
592
|
executables: []
|
|
@@ -1717,9 +1731,9 @@ licenses:
|
|
|
1717
1731
|
- BSD-3-Clause
|
|
1718
1732
|
metadata:
|
|
1719
1733
|
bug_tracker_uri: https://github.com/spree/spree/issues
|
|
1720
|
-
changelog_uri: https://github.com/spree/spree/releases/tag/v5.3.
|
|
1734
|
+
changelog_uri: https://github.com/spree/spree/releases/tag/v5.3.5
|
|
1721
1735
|
documentation_uri: https://docs.spreecommerce.org/
|
|
1722
|
-
source_code_uri: https://github.com/spree/spree/tree/v5.3.
|
|
1736
|
+
source_code_uri: https://github.com/spree/spree/tree/v5.3.5
|
|
1723
1737
|
rdoc_options: []
|
|
1724
1738
|
require_paths:
|
|
1725
1739
|
- lib
|