solidus_api 4.7.1 → 4.8.0

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: 92ccd1baa7331139315707fd902eeec5712a41d6563f713611c4c4c32beaff34
4
- data.tar.gz: 2b93ffdf94c871ec54eaabda3c9c4b46e5108283e1d2aa99686dba426e811cf2
3
+ metadata.gz: f4ff5000b131bd3d2fce8bc9e81165d860447f4c5a94d5364852af656fa4de8d
4
+ data.tar.gz: b46b662948606c65253e766a0b207ea00ad473aa217811b70a0d4bdee2c69c8a
5
5
  SHA512:
6
- metadata.gz: d91812f69f054d0536f3bd0bc34a7c028ded3d4172917348d587fbeac25b2a5bb7e2eab28f38d6ae72f82a0a781137c4c53372005c876c42abaf6b115ba9a95f
7
- data.tar.gz: 2eb2ce76ec4d4a9892f7fa3fd99691f81376cdb0580f8ca39c227ba2f7c394ddb25b14c7e1180cbe931ad0c7f8d5d4d297988b576eabe7f5ca2e70451bbbc920
6
+ metadata.gz: 8519bddff6d7f9b5dc478d19a1ef09b7f68473a89f94ab044c5c45e462bf93e72986888f2a6e5bc2dd0075f43d41330da07e0e9ba6955f751720f24a61fffbed
7
+ data.tar.gz: d0ee7c6a4d2584a00bbeb88e8442c3d6985e1c6f66590007458744cd3f11a2a9bbe9a06b88eddcba449dd7cf0d8fa239e513380ae9df3466fffb0726c8391ca1
data/LICENSE CHANGED
@@ -1,6 +1,9 @@
1
1
  Copyright (c) 2007-2014, Spree Commerce, Inc. and other contributors
2
2
  All rights reserved.
3
3
 
4
+ Copyright (c) 2015-2026, Solidus contributors
5
+ All rights reserved.
6
+
4
7
  Redistribution and use in source and binary forms, with or without modification,
5
8
  are permitted provided that the following conditions are met:
6
9
 
@@ -7,7 +7,7 @@ module Spree
7
7
  class BaseController < ActionController::Base
8
8
  self.responder = Spree::Api::Responders::AppResponder
9
9
  respond_to :json
10
- protect_from_forgery unless: -> { request.format.json? }
10
+ protect_from_forgery with: :exception, unless: -> { request.format.json? }
11
11
 
12
12
  include CanCan::ControllerAdditions
13
13
  include ActiveStorage::SetCurrent
@@ -122,7 +122,7 @@ module Spree
122
122
  end
123
123
 
124
124
  def requires_authentication?
125
- Spree::Api::Config[:requires_authentication]
125
+ Spree::Api::Config.requires_authentication
126
126
  end
127
127
 
128
128
  def not_found
@@ -42,10 +42,12 @@ module Spree
42
42
  def update
43
43
  authorize! :update, @order, order_token
44
44
 
45
+ if can?(:admin, @order) && user_id.present?
46
+ user = Spree.user_class.accessible_by(current_ability, :show).find(user_id)
47
+ end
48
+
45
49
  if Spree::Config.order_update_attributes_class.new(@order, update_params, request_env: request.headers.env).call
46
- if can?(:admin, @order) && user_id.present?
47
- @order.associate_user!(Spree.user_class.find(user_id))
48
- end
50
+ @order.associate_user!(user) if user
49
51
 
50
52
  return if after_update_attributes
51
53
 
@@ -105,10 +107,20 @@ module Spree
105
107
  end
106
108
 
107
109
  def update_order_state
108
- @order.state = params[:state] if params[:state]
110
+ return unless params[:state]
111
+
112
+ unless Spree::Api::Config.allow_arbitrary_state_in_checkout || valid_checkout_step?(params[:state])
113
+ return respond_with(@order, default_template: "spree/api/orders/invalid_state", status: 422)
114
+ end
115
+
116
+ @order.state = params[:state]
109
117
  state_callback(:before)
110
118
  end
111
119
 
120
+ def valid_checkout_step?(step)
121
+ @order.passed_checkout_step?(step) || @order.state == step
122
+ end
123
+
112
124
  def state_callback(before_or_after = :before)
113
125
  method_name = :"#{before_or_after}_#{@order.state}"
114
126
  send(method_name) if respond_to?(method_name, true)
@@ -85,11 +85,13 @@ module Spree
85
85
  def update
86
86
  authorize! :update, @order, order_token
87
87
 
88
+ user_id = params[:order][:user_id]
89
+ if can?(:admin, @order) && user_id
90
+ user = Spree.user_class.accessible_by(current_ability, :show).find(user_id)
91
+ end
92
+
88
93
  if @order.contents.update_cart(order_params)
89
- user_id = params[:order][:user_id]
90
- if can?(:admin, @order) && user_id
91
- @order.associate_user!(Spree.user_class.find(user_id))
92
- end
94
+ @order.associate_user!(user) if user
93
95
  respond_with(@order, default_template: :show)
94
96
  else
95
97
  invalid_resource!(@order)
@@ -148,7 +150,7 @@ module Spree
148
150
  # @api public
149
151
  def determine_order_user
150
152
  if order_params[:user_id].present?
151
- Spree.user_class.find(order_params[:user_id])
153
+ Spree.user_class.accessible_by(current_ability, :show).find(order_params[:user_id])
152
154
  else
153
155
  current_api_user
154
156
  end
@@ -8,18 +8,12 @@ module Spree
8
8
  ids = params[:ids].split(",").flatten
9
9
  @products = product_scope.where(id: ids)
10
10
  else
11
- products_includes = [
12
- :variants,
13
- :option_types,
14
- :product_properties,
15
- {classifications: :taxon}
16
- ]
17
11
  @products = product_scope
18
12
  .ransack(params[:q])
19
13
  .result
20
- .includes(products_includes)
21
14
  end
22
15
 
16
+ @products = @products.includes(products_includes)
23
17
  @products = paginate(@products.distinct)
24
18
  expires_in 15.minutes, public: true
25
19
  headers["Surrogate-Control"] = "max-age=#{15.minutes}"
@@ -108,6 +102,19 @@ module Spree
108
102
 
109
103
  private
110
104
 
105
+ def products_includes
106
+ [
107
+ :option_types,
108
+ :product_properties,
109
+ {classifications: :taxon},
110
+ {master: variants_includes},
111
+ {variants: variants_includes},
112
+ {variants_including_master: variants_includes}
113
+ ]
114
+ end
115
+
116
+ def variants_includes = {stock_items: :stock_location, images: Spree::Image.attachment_preloads}
117
+
111
118
  def product_params
112
119
  product_params = params.require(:product).permit(permitted_product_attributes)
113
120
  if product_params[:taxon_ids].present?
@@ -93,7 +93,7 @@ module Spree
93
93
  end
94
94
 
95
95
  def transfer_to_location
96
- @desired_stock_location = Spree::StockLocation.find(params[:stock_location_id])
96
+ @desired_stock_location = Spree::StockLocation.accessible_by(current_ability, :show).find(params[:stock_location_id])
97
97
  @desired_shipment = @original_shipment.order.shipments.build(stock_location: @desired_stock_location)
98
98
  transfer_to_shipment
99
99
  end
@@ -34,6 +34,7 @@ module Spree
34
34
 
35
35
  def scope
36
36
  @stock_location.stock_movements.accessible_by(current_ability)
37
+ .includes(stock_item: {variant: [:product, :prices, :stock_items, :images, {option_values: :option_type}]})
37
38
  end
38
39
 
39
40
  def stock_movement_params
@@ -5,6 +5,7 @@ class Spree::Api::UsersController < Spree::Api::BaseController
5
5
 
6
6
  def index
7
7
  user_scope = user_class.accessible_by(current_ability, :show)
8
+ .includes(bill_address: [:state, :country], ship_address: [:state, :country])
8
9
  if params[:ids]
9
10
  ids = params[:ids].split(",").flatten
10
11
  @users = user_scope.where(id: ids)
@@ -80,10 +81,16 @@ class Spree::Api::UsersController < Spree::Api::BaseController
80
81
  end
81
82
 
82
83
  def permitted_user_attributes
84
+ attributes = super
85
+
83
86
  if action_name == "create" || can?(:update_email, @user)
84
- super | [:email]
85
- else
86
- super
87
+ attributes |= [:email]
87
88
  end
89
+
90
+ unless action_name == "create" || @user == current_api_user || can?(:update_password, @user)
91
+ attributes -= [:password, :password_confirmation]
92
+ end
93
+
94
+ attributes
88
95
  end
89
96
  end
@@ -89,8 +89,16 @@ module Spree
89
89
  end
90
90
 
91
91
  def include_list
92
- [{option_values: :option_type}, :product, :prices, :images, {stock_items: :stock_location}]
92
+ [
93
+ {option_values: :option_type},
94
+ {product: {master: images_includes}},
95
+ :prices,
96
+ images_includes,
97
+ {stock_items: :stock_location}
98
+ ]
93
99
  end
100
+
101
+ def images_includes = {images: Spree::Image.attachment_preloads}
94
102
  end
95
103
  end
96
104
  end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.symbol(::Money.new(1, Spree::Config[:currency]).symbol)
3
+ json.symbol(::Money.new(1, Spree::Config.currency).symbol)
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.default_country_iso(Spree::Config[:default_country_iso])
3
+ json.default_country_iso(Spree::Config.default_country_iso)
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ json.errors(state: [I18n.t(:invalid_state, scope: "spree.api.order")])
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ json.call(store, *store_attributes)
4
+ json.address do
5
+ if store.address
6
+ json.partial!("spree/api/addresses/address", address: store.address)
7
+ else
8
+ json.nil!
9
+ end
10
+ end
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.stores(@stores) { |store| json.call(store, *store_attributes) }
3
+ json.stores(@stores) { |store| json.partial!("spree/api/stores/store", store:) }
@@ -1,3 +1,3 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.call(@store, *store_attributes)
3
+ json.partial!("spree/api/stores/store", store: @store)
@@ -6,7 +6,7 @@ json.cache! [I18n.locale, Spree::StockLocation.accessible_by(current_ability), v
6
6
  json.variant_properties(variant.variant_properties) do |variant_property|
7
7
  json.call(variant_property, *variant_property_attributes)
8
8
  end
9
- json.stock_items(variant.stock_items.accessible_by(current_ability)) do |stock_item|
9
+ json.stock_items(variant.stock_items.select { can?(:read, _1) }) do |stock_item|
10
10
  json.call(stock_item, :id, :count_on_hand, :stock_location_id, :backorderable)
11
11
  json.available stock_item.available?
12
12
  json.stock_location_name(stock_item.stock_location.name)
@@ -12,6 +12,7 @@ en:
12
12
  order:
13
13
  expected_total_mismatch: Expected total does not match actual total.
14
14
  invalid_shipping_method: Invalid shipping method specified.
15
+ invalid_state: Invalid state specified.
15
16
  quantity_is_not_available: Quantity is not available for items in your order
16
17
  payment:
17
18
  credit_over_limit: This payment can only be credited up to %{limit}. Please specify an amount less than or equal to this number.
data/lib/spree/api.rb CHANGED
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "kaminari/activerecord"
3
4
  require "spree/core"
4
5
 
5
6
  require "spree/api/engine"
@@ -2,6 +2,10 @@
2
2
 
3
3
  module Spree
4
4
  class ApiConfiguration < Preferences::Configuration
5
+ # @!attribute [rw] allow_arbitrary_state_in_api
6
+ # @return [Boolean] When true, the API will allow arbitrary state transitions on orders (default: +false+)
7
+ preference :allow_arbitrary_state_in_checkout, :boolean, default: false
8
+
5
9
  preference :requires_authentication, :boolean, default: true
6
10
 
7
11
  preference :product_attributes, :array, default: [
@@ -6474,6 +6474,8 @@ components:
6474
6474
  type: string
6475
6475
  url:
6476
6476
  type: string
6477
+ address:
6478
+ $ref: '#/components/schemas/address'
6477
6479
  taxonomy:
6478
6480
  type: object
6479
6481
  properties:
@@ -6955,6 +6957,8 @@ components:
6955
6957
  type: string
6956
6958
  cart_tax_country_iso:
6957
6959
  type: string
6960
+ address_attributes:
6961
+ $ref: '#/components/schemas/address-input'
6958
6962
  taxonomy-input:
6959
6963
  type: object
6960
6964
  title: Taxonomy input
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: solidus_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.7.1
4
+ version: 4.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solidus Team
@@ -57,14 +57,14 @@ dependencies:
57
57
  requirements:
58
58
  - - '='
59
59
  - !ruby/object:Gem::Version
60
- version: 4.7.1
60
+ version: 4.8.0
61
61
  type: :runtime
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - '='
66
66
  - !ruby/object:Gem::Version
67
- version: 4.7.1
67
+ version: 4.8.0
68
68
  description: REST API for the Solidus e-commerce framework.
69
69
  email: contact@solidus.io
70
70
  executables: []
@@ -152,6 +152,7 @@ files:
152
152
  - app/views/spree/api/orders/expected_total_mismatch.json.jbuilder
153
153
  - app/views/spree/api/orders/index.json.jbuilder
154
154
  - app/views/spree/api/orders/invalid_shipping_method.json.jbuilder
155
+ - app/views/spree/api/orders/invalid_state.json.jbuilder
155
156
  - app/views/spree/api/orders/mine.json.jbuilder
156
157
  - app/views/spree/api/orders/show.json.jbuilder
157
158
  - app/views/spree/api/payments/credit_over_limit.json.jbuilder
@@ -197,6 +198,7 @@ files:
197
198
  - app/views/spree/api/stock_movements/index.json.jbuilder
198
199
  - app/views/spree/api/stock_movements/show.json.jbuilder
199
200
  - app/views/spree/api/store_credit_events/mine.json.jbuilder
201
+ - app/views/spree/api/stores/_store.json.jbuilder
200
202
  - app/views/spree/api/stores/index.json.jbuilder
201
203
  - app/views/spree/api/stores/show.json.jbuilder
202
204
  - app/views/spree/api/taxonomies/_nested.json.jbuilder
@@ -270,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
270
272
  - !ruby/object:Gem::Version
271
273
  version: 1.8.23
272
274
  requirements: []
273
- rubygems_version: 4.0.10
275
+ rubygems_version: 4.0.20
274
276
  specification_version: 4
275
277
  summary: REST API for the Solidus e-commerce framework.
276
278
  test_files: []