spree_api 5.6.1 → 6.0.0.beta2

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.
Files changed (542) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +28 -0
  3. data/Rakefile +1 -1
  4. data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
  5. data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
  6. data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
  7. data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
  8. data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
  9. data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
  10. data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
  11. data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
  12. data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
  13. data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
  14. data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +20 -5
  15. data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
  16. data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
  17. data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
  18. data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
  19. data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
  20. data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
  21. data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
  22. data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
  23. data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
  24. data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
  25. data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
  26. data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
  27. data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
  28. data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
  29. data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
  30. data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
  31. data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
  32. data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
  33. data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
  34. data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
  35. data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
  36. data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
  37. data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
  38. data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
  39. data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
  40. data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
  41. data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
  42. data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
  43. data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
  44. data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
  45. data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
  46. data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
  47. data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
  48. data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +18 -9
  49. data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
  50. data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
  51. data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
  52. data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
  53. data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
  54. data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
  55. data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
  56. data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
  57. data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
  58. data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
  59. data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
  60. data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
  61. data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
  62. data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
  63. data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
  64. data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
  65. data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
  66. data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
  67. data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
  68. data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
  69. data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
  70. data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
  71. data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
  72. data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
  73. data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
  74. data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
  75. data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
  76. data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
  77. data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
  78. data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
  79. data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
  80. data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
  81. data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
  82. data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
  83. data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
  84. data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
  85. data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
  86. data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
  87. data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
  88. data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
  89. data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
  90. data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
  91. data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
  92. data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
  93. data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
  94. data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
  95. data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
  96. data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
  97. data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
  98. data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
  99. data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
  100. data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
  101. data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
  102. data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
  103. data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
  104. data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
  105. data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
  106. data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
  107. data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
  108. data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
  109. data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
  110. data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
  111. data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
  112. data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
  113. data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
  114. data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
  115. data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
  116. data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
  117. data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
  118. data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
  119. data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
  120. data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
  121. data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
  122. data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
  123. data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
  124. data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
  125. data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
  126. data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
  127. data/app/controllers/spree/api/v3/admin/orders_controller.rb +164 -33
  128. data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
  129. data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
  130. data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
  131. data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
  132. data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
  133. data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
  134. data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
  135. data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
  136. data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
  137. data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
  138. data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
  139. data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
  140. data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
  141. data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
  142. data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
  143. data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
  144. data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
  145. data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
  146. data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
  147. data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
  148. data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
  149. data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
  150. data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
  151. data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
  152. data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
  153. data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
  154. data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
  155. data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
  156. data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
  157. data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
  158. data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
  159. data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
  160. data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
  161. data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
  162. data/app/controllers/spree/api/v3/admin/setup_controller.rb +239 -0
  163. data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
  164. data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
  165. data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
  166. data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
  167. data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
  168. data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
  169. data/app/controllers/spree/api/v3/admin/store_controller.rb +66 -0
  170. data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
  171. data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
  172. data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
  173. data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
  174. data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
  175. data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
  176. data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
  177. data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
  178. data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
  179. data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
  180. data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
  181. data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
  182. data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
  183. data/app/controllers/spree/api/v3/base_controller.rb +74 -16
  184. data/app/controllers/spree/api/v3/resource_controller.rb +170 -39
  185. data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
  186. data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
  187. data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
  188. data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
  189. data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
  190. data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
  191. data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
  192. data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
  193. data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
  194. data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
  195. data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
  196. data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
  197. data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
  198. data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
  199. data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
  200. data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
  201. data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
  202. data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
  203. data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
  204. data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
  205. data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
  206. data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
  207. data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
  208. data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
  209. data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
  210. data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
  211. data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
  212. data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
  213. data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
  214. data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
  215. data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
  216. data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
  217. data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
  218. data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
  219. data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
  220. data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
  221. data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
  222. data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
  223. data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
  224. data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
  225. data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
  226. data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
  227. data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
  228. data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
  229. data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
  230. data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
  231. data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
  232. data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
  233. data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
  234. data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
  235. data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
  236. data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
  237. data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
  238. data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
  239. data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
  240. data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
  241. data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
  242. data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
  243. data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
  244. data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
  245. data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
  246. data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
  247. data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
  248. data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
  249. data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
  250. data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
  251. data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
  252. data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
  253. data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
  254. data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
  255. data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
  256. data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
  257. data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
  258. data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
  259. data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
  260. data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
  261. data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
  262. data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
  263. data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
  264. data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
  265. data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
  266. data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
  267. data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
  268. data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
  269. data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
  270. data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
  271. data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
  272. data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
  273. data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
  274. data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
  275. data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
  276. data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
  277. data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
  278. data/app/models/spree/api/data_request_urls.rb +25 -0
  279. data/app/models/spree/api/digital_link_urls.rb +26 -0
  280. data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
  281. data/app/serializers/spree/api/v3/admin/actor_serializer.rb +28 -0
  282. data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
  283. data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
  284. data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +15 -2
  285. data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
  286. data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
  287. data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
  288. data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
  289. data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
  290. data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
  291. data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
  292. data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
  293. data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
  294. data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
  295. data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
  296. data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
  297. data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
  298. data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
  299. data/app/serializers/spree/api/v3/admin/claim_serializer.rb +28 -0
  300. data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
  301. data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
  302. data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
  303. data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
  304. data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
  305. data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
  306. data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
  307. data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
  308. data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
  309. data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
  310. data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
  311. data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
  312. data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
  313. data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
  314. data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
  315. data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
  316. data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
  317. data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
  318. data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
  319. data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
  320. data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
  321. data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
  322. data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
  323. data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
  324. data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
  325. data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
  326. data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
  327. data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
  328. data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
  329. data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +34 -0
  330. data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
  331. data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
  332. data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
  333. data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
  334. data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
  335. data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
  336. data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
  337. data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
  338. data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
  339. data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
  340. data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +46 -5
  341. data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
  342. data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
  343. data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
  344. data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
  345. data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
  346. data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
  347. data/app/serializers/spree/api/v3/admin/order_serializer.rb +126 -31
  348. data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
  349. data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
  350. data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
  351. data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
  352. data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
  353. data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
  354. data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
  355. data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
  356. data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
  357. data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
  358. data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
  359. data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
  360. data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
  361. data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
  362. data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
  363. data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
  364. data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
  365. data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
  366. data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
  367. data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
  368. data/app/serializers/spree/api/v3/admin/refund_serializer.rb +6 -5
  369. data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
  370. data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
  371. data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
  372. data/app/serializers/spree/api/v3/admin/return_serializer.rb +58 -0
  373. data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
  374. data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +32 -0
  375. data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
  376. data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
  377. data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
  378. data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
  379. data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
  380. data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
  381. data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
  382. data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
  383. data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
  384. data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
  385. data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
  386. data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
  387. data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
  388. data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
  389. data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +48 -0
  390. data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
  391. data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
  392. data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
  393. data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
  394. data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
  395. data/app/serializers/spree/api/v3/admin/store_serializer.rb +65 -1
  396. data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
  397. data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
  398. data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
  399. data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
  400. data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
  401. data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
  402. data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
  403. data/app/serializers/spree/api/v3/base_serializer.rb +61 -2
  404. data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
  405. data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
  406. data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
  407. data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
  408. data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
  409. data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
  410. data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
  411. data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
  412. data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
  413. data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
  414. data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
  415. data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
  416. data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
  417. data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
  418. data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
  419. data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
  420. data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
  421. data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
  422. data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
  423. data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
  424. data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
  425. data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
  426. data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
  427. data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
  428. data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
  429. data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
  430. data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
  431. data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
  432. data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
  433. data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
  434. data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
  435. data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
  436. data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
  437. data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
  438. data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
  439. data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
  440. data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
  441. data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
  442. data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
  443. data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
  444. data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
  445. data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
  446. data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
  447. data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
  448. data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
  449. data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
  450. data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
  451. data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
  452. data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
  453. data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
  454. data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
  455. data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
  456. data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
  457. data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
  458. data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
  459. data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
  460. data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
  461. data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
  462. data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
  463. data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
  464. data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
  465. data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
  466. data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
  467. data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
  468. data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
  469. data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
  470. data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
  471. data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
  472. data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
  473. data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
  474. data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
  475. data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
  476. data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
  477. data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
  478. data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
  479. data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
  480. data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
  481. data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
  482. data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
  483. data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
  484. data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
  485. data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
  486. data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
  487. data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
  488. data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
  489. data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
  490. data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
  491. data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
  492. data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
  493. data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
  494. data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
  495. data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
  496. data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
  497. data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
  498. data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
  499. data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
  500. data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
  501. data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
  502. data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
  503. data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
  504. data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
  505. data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
  506. data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
  507. data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
  508. data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
  509. data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
  510. data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
  511. data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
  512. data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
  513. data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
  514. data/config/brakeman.ignore +1 -1
  515. data/config/initializers/typelizer.rb +51 -4
  516. data/config/locales/en.yml +5 -0
  517. data/config/routes.rb +730 -22
  518. data/lib/spree/api/configuration.rb +19 -19
  519. data/lib/spree/api/dependencies.rb +174 -227
  520. data/lib/spree/api/engine.rb +6 -0
  521. data/lib/spree/api/openapi/schema_helper.rb +179 -13
  522. data/lib/spree/api/testing_support/v3/base.rb +45 -15
  523. data/lib/spree/api.rb +10 -4
  524. data/lib/typelizer/open_enums.rb +35 -0
  525. metadata +342 -27
  526. data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
  527. data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
  528. data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
  529. data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
  530. data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
  531. data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
  532. data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
  533. data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
  534. data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
  535. data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
  536. data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
  537. data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
  538. data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
  539. data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
  540. data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
  541. data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
  542. data/app/serializers/spree/api/v3/shipping_category_serializer.rb +0 -11
@@ -37,7 +37,15 @@ module Spree
37
37
  # tags, etc.) or for specific actions (`only: :index`) when an
38
38
  # action authorizes another way, e.g. by filtering its collection
39
39
  # per-type (exports).
40
- def skip_scope_check!(only: nil)
40
+ #
41
+ # `jwt_only: true` narrows the exemption to JWT staff: secret API
42
+ # keys still have their scope enforced. Use it for shell data a
43
+ # signed-in staff member reads to render the dashboard (the store
44
+ # itself) but which a scope-limited integration key has no business
45
+ # reading outside its granted scope.
46
+ def skip_scope_check!(only: nil, jwt_only: false)
47
+ self._scope_check_skip_jwt_only = jwt_only
48
+
41
49
  if only
42
50
  self._scope_check_skipped_actions = Array(only).map(&:to_s)
43
51
  else
@@ -50,6 +58,7 @@ module Spree
50
58
  class_attribute :_scoped_resource, instance_accessor: false
51
59
  class_attribute :_scope_check_skipped, instance_accessor: false, default: false
52
60
  class_attribute :_scope_check_skipped_actions, instance_accessor: false
61
+ class_attribute :_scope_check_skip_jwt_only, instance_accessor: false, default: false
53
62
  before_action :authorize_api_key_scope!
54
63
  end
55
64
 
@@ -58,9 +67,12 @@ module Spree
58
67
  def authorize_api_key_scope!
59
68
  # Endpoints explicitly exempt from the scope mechanism (auth, me, public
60
69
  # invitation acceptance, per-type-filtered exports, etc.) opt out first,
61
- # before any key resolution or enforcement.
62
- return if self.class._scope_check_skipped
63
- return if self.class._scope_check_skipped_actions&.include?(action_name)
70
+ # before any key resolution or enforcement. A `jwt_only` skip is the
71
+ # exception: it exempts JWT staff but still enforces scope for secret
72
+ # keys, so it must fall through to key resolution below.
73
+ if scope_check_skipped_for_action? && !self.class._scope_check_skip_jwt_only
74
+ return
75
+ end
64
76
 
65
77
  # Fail CLOSED, not open. A nil `current_api_key` legitimately means a
66
78
  # non-secret-key request (JWT admin / publishable) authorized by other
@@ -73,15 +85,25 @@ module Spree
73
85
  resolve_current_api_key_for_scope_check!
74
86
 
75
87
  unless current_api_key
76
- return unless secret_key_request?
77
-
78
- # A secret-key token was presented but did not resolve to a live key
79
- # for this store — reject rather than silently skip the scope check.
80
- return render_error(
81
- code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:invalid_token],
82
- message: 'Valid secret API key required',
83
- status: :unauthorized
84
- )
88
+ if secret_key_request?
89
+ # A secret-key token was presented but did not resolve to a live key
90
+ # for this store — reject rather than silently skip the scope check.
91
+ return render_error(
92
+ code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:invalid_token],
93
+ message: 'Valid secret API key required',
94
+ status: :unauthorized
95
+ )
96
+ end
97
+
98
+ # A `jwt_only` skip exempts the JWT/publishable principal we now know
99
+ # this is (no secret key resolved) — shell data the dashboard reads
100
+ # without a specific scope.
101
+ return if scope_check_skipped_for_action? && self.class._scope_check_skip_jwt_only
102
+
103
+ # JWT staff pass through the same key gate as secret keys: their
104
+ # roles' catalog keys play the role scopes play for keys, so both
105
+ # principals share one enforcement contract per controller.
106
+ return authorize_staff_permission!
85
107
  end
86
108
 
87
109
  resource = scoped_resource_name
@@ -101,27 +123,59 @@ module Spree
101
123
  )
102
124
  end
103
125
 
104
- # True when the request presents a secret API key token (`sk_` prefix),
105
- # regardless of whether authentication has resolved it into
106
- # `current_api_key` yet. Used to keep the scope guard fail-closed even if
107
- # it runs before the API key is loaded: a secret-key request whose key is
108
- # still nil must be denied, never waved through.
109
- def secret_key_request?
110
- extract_api_key.to_s.start_with?(Spree::ApiKey::PREFIXES['secret'])
126
+ # The JWT half of the key gate. The staffer's expanded role keys come
127
+ # from Spree::Ability#permission_keys; a custom ability class without
128
+ # that method falls back to plain CanCanCan `authorize!` enforcement.
129
+ def authorize_staff_permission!
130
+ return unless current_user
131
+
132
+ resource = scoped_resource_name
133
+ # Fail closed, mirroring the secret-key path: admin controllers must
134
+ # declare their scope (or skip explicitly).
135
+ raise MissingScopedResource, self.class unless resource
136
+
137
+ ability = current_ability
138
+ return unless ability.respond_to?(:permission_keys)
139
+
140
+ required = "#{action_kind}_#{resource}"
141
+ # Scope names outside the catalog (the exports/imports `:all`
142
+ # fallback, host-registered types) defer to CanCanCan's `authorize!`
143
+ # — the caller stays gated per subject, just not by key.
144
+ return unless Spree.permissions.key?(required)
145
+ return if ability.permission_keys.include?(required)
146
+
147
+ Rails.logger.info do
148
+ "[Spree] Access denied: user=#{current_user.id} required=#{required} " \
149
+ "held=#{ability.permission_keys.join(',')}"
150
+ end
151
+
152
+ render_error(
153
+ code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:access_denied],
154
+ message: "Missing permission: #{required}",
155
+ status: :forbidden,
156
+ details: { required_permission: required }
157
+ )
158
+ end
159
+
160
+ # Whether the current action opted out of scope checks via
161
+ # `skip_scope_check!` (whole-controller or `only:`). Independent of the
162
+ # `jwt_only` qualifier, which the caller weighs separately.
163
+ def scope_check_skipped_for_action?
164
+ self.class._scope_check_skipped ||
165
+ self.class._scope_check_skipped_actions&.include?(action_name) || false
111
166
  end
112
167
 
113
168
  # Resolves the request's secret API key into `@current_api_key` if a
114
169
  # secret-key token is present and it hasn't been resolved yet, so the scope
115
- # check does not depend on `authenticate_admin!` having already run. Mirrors
116
- # the secret-key resolution + store binding in AdminAuthentication, and is
117
- # idempotent: when the key is already loaded (guard runs after auth) it does
118
- # nothing.
170
+ # check does not depend on `authenticate_admin!` having already run. Uses
171
+ # the same memoized lookup as AdminAuthentication (the key selects the
172
+ # request's store — see Admin::StoreContext), and is idempotent: when the
173
+ # key is already loaded (guard runs after auth) it does nothing.
119
174
  def resolve_current_api_key_for_scope_check!
120
175
  return if @current_api_key
121
176
  return unless secret_key_request?
122
177
 
123
- key = Spree::ApiKey.find_by_secret_token(extract_api_key)
124
- @current_api_key = key if key && key.store_id == current_store.id
178
+ @current_api_key = secret_api_key
125
179
  end
126
180
 
127
181
  # The resource name used in scope strings (`read_<name>` / `write_<name>`).
@@ -0,0 +1,62 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Seller
5
+ # Cookie-based delivery for seller refresh tokens.
6
+ #
7
+ # Both the name and the path differ from the admin cookie, and both
8
+ # matter: a shared name would let one browser's admin session be
9
+ # redeemed on the seller panel, and the path is what stops each
10
+ # surface's cookie being sent to the other's endpoints. Together with
11
+ # the audience stamped on the token itself, a session belongs to
12
+ # exactly one surface.
13
+ #
14
+ # The CSRF reasoning is the admin concern's, unchanged: SameSite plus
15
+ # the Spree::AllowedOrigin allowlist. A seller dashboard served from an
16
+ # origin outside that allowlist would need its own answer.
17
+ module AuthCookies
18
+ extend ActiveSupport::Concern
19
+
20
+ # ActionController::API drops Cookies — re-include it on the auth
21
+ # controller only; the rest of the branch stays stateless.
22
+ included do
23
+ include ActionController::Cookies
24
+ end
25
+
26
+ REFRESH_COOKIE_NAME = :spree_seller_refresh_token
27
+ COOKIE_PATH = '/api/v3/seller/auth'.freeze
28
+
29
+ private
30
+
31
+ def set_refresh_cookie(refresh_token)
32
+ cookies.signed[REFRESH_COOKIE_NAME] = base_cookie_attributes.merge(
33
+ value: refresh_token.token,
34
+ expires: refresh_token.expires_at,
35
+ path: COOKIE_PATH,
36
+ httponly: true
37
+ )
38
+ end
39
+
40
+ def clear_refresh_cookie
41
+ cookies.delete(REFRESH_COOKIE_NAME, path: COOKIE_PATH)
42
+ end
43
+
44
+ def refresh_token_from_cookie
45
+ cookies.signed[REFRESH_COOKIE_NAME].presence
46
+ end
47
+
48
+ # Keyed off the request scheme, not the Rails env: Rails silently
49
+ # refuses to write a Secure cookie on a non-SSL request, so an app
50
+ # served over plain http would never receive one at all.
51
+ def base_cookie_attributes
52
+ if request.ssl?
53
+ { secure: true, same_site: :none }
54
+ else
55
+ { secure: false, same_site: :lax }
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,127 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ module Seller
5
+ # Resolves which seller a request acts as.
6
+ #
7
+ # The inverse of the admin branch's store context: there, the store is
8
+ # named by a header or a key and falls back to the default. Here the
9
+ # seller is named by the header, membership is checked against it, and
10
+ # the store is *derived* from the seller — never sent, never defaulted.
11
+ # A request that names no seller the caller belongs to has no tenant at
12
+ # all, which is an error rather than a default.
13
+ #
14
+ # Included into both branch anchors (BaseController and
15
+ # ResourceController) — parallel chains, so a concern on one is not on
16
+ # the other.
17
+ module SellerContext
18
+ extend ActiveSupport::Concern
19
+
20
+ SELLER_HEADER = 'X-Spree-Seller-Id'.freeze
21
+
22
+ # Prepended, like the admin branch's store context, because the
23
+ # shared base chain reads the store while setting up locale and
24
+ # currency — before any ordinary callback runs.
25
+ #
26
+ # Resolving a seller needs the caller, so this identifies them first
27
+ # by calling `authenticate_user`, which is idempotent and is the same
28
+ # method the authentication callback runs later. That later callback
29
+ # remains the authority on whether the request may proceed; this only
30
+ # establishes the tenant early enough for the chain beneath it.
31
+ included do
32
+ prepend_before_action :set_current_seller_context
33
+ end
34
+
35
+ # The seller this request acts as, or nil when the header names none
36
+ # the caller belongs to.
37
+ #
38
+ # @return [Spree::Seller, nil]
39
+ # `||=` rather than a `defined?` memo on purpose: a nil must not
40
+ # stick. The locale/currency chain reads `current_store` — and so
41
+ # this — before authentication has run, and caching that first miss
42
+ # would leave a controller which skips the context callback
43
+ # (MeController) permanently seller-less even with a valid header.
44
+ def current_seller
45
+ @current_seller ||= resolve_current_seller
46
+ end
47
+
48
+ # Derived from the seller, so a seller can never widen their reach by
49
+ # sending a store header.
50
+ #
51
+ # Falls back to the default store only when no seller resolved — such
52
+ # a request is already being rejected, and the chain beneath this
53
+ # (locale and currency setup) reads the store before the rejection
54
+ # renders. Nothing tenant-bearing is served through the fallback.
55
+ #
56
+ # @return [Spree::Store, nil]
57
+ def current_store
58
+ current_seller&.store || Spree::Store.default
59
+ end
60
+
61
+ # The orders this seller has actually sold.
62
+ #
63
+ # A draft is either a checkout still in flight or the operator's own
64
+ # working document. Neither is this seller's, so neither is reachable
65
+ # from any endpoint on this branch — including the nested ones, which
66
+ # is why this lives here rather than in one controller's `scope`.
67
+ #
68
+ # @return [ActiveRecord::Relation]
69
+ def current_seller_orders
70
+ current_seller.orders.not_drafts
71
+ end
72
+
73
+ private
74
+
75
+ def set_current_seller_context
76
+ # Identify the caller before resolving their seller. Safe to call
77
+ # here: it only populates @current_user, and the authentication
78
+ # callback still decides whether an unidentified request proceeds.
79
+ authenticate_user
80
+
81
+ # Assigned even when nil: leaving the previous request's value on a
82
+ # reused thread would expose another tenant to anything reading it
83
+ # before the rejection lands.
84
+ Spree::Current.store = current_store
85
+
86
+ # An unauthenticated request has no seller to resolve, and saying
87
+ # so is authentication's job — let it answer with a 401 rather than
88
+ # reporting a missing tenant.
89
+ return true if current_user.nil?
90
+
91
+ require_current_seller!
92
+ end
93
+
94
+ def require_current_seller!
95
+ return true if current_seller
96
+
97
+ render_error(
98
+ code: ErrorHandler::ERROR_CODES[:access_denied],
99
+ message: Spree.t(:seller_access_denied),
100
+ status: :forbidden
101
+ )
102
+ false
103
+ end
104
+
105
+ # Membership is holding a role the seller owns — the same question
106
+ # the store back office asks, pointed at a different resource. A
107
+ # header naming a seller the caller has no role on resolves to
108
+ # nothing, so it reads as "no such seller" rather than "denied",
109
+ # which is also what stops the header being used to enumerate.
110
+ def resolve_current_seller
111
+ return nil if seller_id_header.blank?
112
+ return nil unless current_user.respond_to?(:sellers)
113
+
114
+ id = Spree::Seller.decode_own_prefixed_id(seller_id_header)
115
+ return nil if id.blank?
116
+
117
+ current_user.sellers.find_by(id: id)
118
+ end
119
+
120
+ def seller_id_header
121
+ request.headers[SELLER_HEADER]
122
+ end
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,40 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Authentication for the marketplace seller panel.
5
+ #
6
+ # Deliberately not a subclass or variant of AdminAuthentication: a seller
7
+ # holds no secret API key (keys are store-bound and grant `manage :all`),
8
+ # so this surface is JWT-only and the key path simply does not exist here.
9
+ module SellerAuthentication
10
+ extend ActiveSupport::Concern
11
+
12
+ included do
13
+ after_action :set_no_store_cache
14
+ end
15
+
16
+ protected
17
+
18
+ # Rejects an admin or storefront token before any seller is resolved.
19
+ def expected_audience
20
+ Spree::Api::V3::JwtAuthentication::JWT_AUDIENCE_SELLER
21
+ end
22
+
23
+ # Capability comes from the roles the seller holds *on this seller*.
24
+ # Passing the resource is what stops a store role — or the store's
25
+ # `admin` super-role — being read here (see Spree::Ability).
26
+ def ability_options
27
+ { store: current_store, resource: current_seller }
28
+ end
29
+
30
+ def authenticate_seller!
31
+ require_authentication!
32
+ end
33
+
34
+ def set_no_store_cache
35
+ response.headers['Cache-Control'] = 'private, no-store'
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,38 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Storefront access checks backed by Spree::Storefront::AccessPolicy —
5
+ # the Store API's replacement for CanCanCan. Ownership scoping remains
6
+ # the primary enforcement; these helpers cover the checks a scope cannot
7
+ # express (guest-token access to a specific cart or order).
8
+ module StorefrontAccess
9
+ extend ActiveSupport::Concern
10
+
11
+ protected
12
+
13
+ def storefront_access_policy
14
+ @storefront_access_policy ||= Spree.storefront_access_policy_class.new(
15
+ user: current_user,
16
+ store: current_store
17
+ )
18
+ end
19
+
20
+ # @raise [Spree::Storefront::AccessDenied] when the caller can neither
21
+ # prove ownership nor (for carts/orders) present the guest token
22
+ def authorize_storefront_read!(record, token: nil)
23
+ return if storefront_access_policy.readable?(record, token: token)
24
+
25
+ raise Spree::Storefront::AccessDenied
26
+ end
27
+
28
+ # @raise [Spree::Storefront::AccessDenied] when unreadable — or, for
29
+ # carts and orders, already completed
30
+ def authorize_storefront_write!(record, token: nil)
31
+ return if storefront_access_policy.writable?(record, token: token)
32
+
33
+ raise Spree::Storefront::AccessDenied
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,37 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # Serving a label file, shared by every surface that offers one — the
5
+ # operator's, the seller's and the customer's return download.
6
+ #
7
+ # The bytes are streamed rather than redirected to storage, so the
8
+ # credentials that reached the action are what protects the file. The
9
+ # one exception is a label whose file is still being fetched from the
10
+ # carrier: until it lands, the carrier's own copy stands in.
11
+ #
12
+ # Deliberately carries no scope of its own — the caller has already
13
+ # fetched and authorized the label.
14
+ module StreamsShippingLabel
15
+ extend ActiveSupport::Concern
16
+
17
+ # @param shipping_label [Spree::ShippingLabel]
18
+ # @yield when there is nothing to serve, so each surface answers in
19
+ # its own vocabulary (a 404 for a customer, a 422 for staff)
20
+ def stream_shipping_label(shipping_label, &on_missing)
21
+ if shipping_label.file.attached?
22
+ send_data(
23
+ shipping_label.file.download,
24
+ filename: shipping_label.download_filename,
25
+ type: shipping_label.file.content_type || 'application/octet-stream',
26
+ disposition: 'attachment'
27
+ )
28
+ elsif shipping_label.file_pending?
29
+ redirect_to shipping_label.file_url, allow_other_host: true
30
+ else
31
+ on_missing.call
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ module Spree
2
+ module Api
3
+ module V3
4
+ # The re-check action, shared by every surface where a registration is
5
+ # managed: nested under a customer, under a company, and the seller's
6
+ # own panel.
7
+ #
8
+ # Separate from the number-changed path, which the model stamps and a
9
+ # subscriber queues. This is staff asking "is it still valid now" — a
10
+ # number verified last year may have been deregistered since — so it
11
+ # queues a check without the number having changed.
12
+ module TaxIdentifierValidation
13
+ extend ActiveSupport::Concern
14
+
15
+ def validate
16
+ authorize_resource!(@resource, :update)
17
+
18
+ # A kind can be format-checked here and still have no registry to
19
+ # ask — core ships exactly that for EU VAT — so the message says
20
+ # what is missing rather than claiming nothing is registered.
21
+ unless @resource.validatable?
22
+ render_error(
23
+ code: 'tax_id_not_validatable',
24
+ message: "No registry validator is installed for tax identifier kind '#{@resource.kind}'",
25
+ status: :unprocessable_content
26
+ )
27
+ return
28
+ end
29
+
30
+ # Marked pending before the job is queued, not after: the job can
31
+ # finish first, and writing 'pending' afterwards would bury the
32
+ # verdict it just recorded.
33
+ @resource.update_columns(validation_status: 'pending', validated_at: nil, updated_at: Time.current)
34
+ Spree::TaxIdentifiers::ValidateJob.perform_later(@resource.id)
35
+
36
+ render json: serialize_resource(@resource.reload), status: :accepted
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -10,7 +10,9 @@ module Spree
10
10
  class AdminUsersController < ResourceController
11
11
  include Spree::Api::V3::Admin::RoleGrantGuard
12
12
 
13
- scoped_resource :settings
13
+ # Staff management is the escalation path — its own scope pair,
14
+ # grantable separately from store configuration (6.0-admin-rbac.md).
15
+ scoped_resource :staff
14
16
 
15
17
  # POST is not exposed — staff are created via invitations.
16
18
  def create
@@ -22,7 +24,7 @@ module Spree
22
24
  # the account globally. The user keeps access to any other stores.
23
25
  def destroy
24
26
  authorize!(:destroy, @resource)
25
- @resource.role_users.where(resource: current_store).destroy_all
27
+ @resource.role_users.where(role: current_store.roles).destroy_all
26
28
  head :no_content
27
29
  end
28
30
 
@@ -60,7 +62,7 @@ module Spree
60
62
  end
61
63
 
62
64
  def collection_includes
63
- [{ role_users: :role, avatar_attachment: :blob }, :stores]
65
+ [{ spree_roles: :resource, avatar_attachment: :blob }]
64
66
  end
65
67
 
66
68
  # Restrict to users with a role assignment on the current store.
@@ -69,10 +71,7 @@ module Spree
69
71
  # host-app-defined and may contain `json` columns, which Postgres
70
72
  # cannot compare for equality.
71
73
  def scope
72
- staff_ids = model_class.
73
- joins(:role_users).
74
- where(Spree::RoleUser.table_name => { resource: current_store }).
75
- select(:id)
74
+ staff_ids = model_class.joins(:spree_roles).merge(current_store.roles).select(:id)
76
75
 
77
76
  model_class.
78
77
  where(id: staff_ids).
@@ -93,17 +92,15 @@ module Spree
93
92
  # Reconcile the user's roles on this store to match `desired_role_ids`.
94
93
  # Adds missing assignments and removes extras — no-op for unchanged.
95
94
  def apply_role_ids(desired_role_ids)
96
- current = @resource.role_users.where(resource: current_store).pluck(:role_id).map(&:to_s)
95
+ store_roles = current_store.roles
96
+ current = @resource.role_users.where(role: store_roles).pluck(:role_id).map(&:to_s)
97
97
  target = desired_role_ids.map(&:to_s)
98
98
 
99
- (target - current).each do |role_id|
100
- role = Spree::Role.find_by(id: role_id)
101
- @resource.role_users.find_or_create_by!(role: role, resource: current_store) if role
99
+ store_roles.where(id: target - current).each do |role|
100
+ @resource.role_users.find_or_create_by!(role: role)
102
101
  end
103
102
 
104
- (current - target).each do |role_id|
105
- @resource.role_users.where(role_id: role_id, resource: current_store).destroy_all
106
- end
103
+ @resource.role_users.where(role: store_roles.where(id: current - target)).destroy_all
107
104
  end
108
105
  end
109
106
  end
@@ -16,7 +16,7 @@ module Spree
16
16
  end
17
17
 
18
18
  def permitted_params
19
- params.permit(:origin)
19
+ params.permit(*model_additional_permitted_attributes, :origin)
20
20
  end
21
21
  end
22
22
  end
@@ -3,6 +3,8 @@ module Spree
3
3
  module V3
4
4
  module Admin
5
5
  class ApiKeysController < ResourceController
6
+ include Spree::Api::V3::Admin::RoleGrantGuard
7
+
6
8
  # Dedicated scope — key management is credential-administration, not
7
9
  # store configuration. A `write_settings` key must not be able to
8
10
  # revoke or destroy higher-privileged keys.
@@ -13,14 +15,19 @@ module Spree
13
15
  skip_scope_check! only: :current
14
16
 
15
17
  # POST /api/v3/admin/api_keys
16
- # Prevents scope amplification: a key minted via a secret API key can
17
- # only carry scopes that key already holds. A JWT admin is governed by
18
- # CanCanCan (not scopes) and may grant any valid scope — so when a JWT
19
- # user authenticated the request, `current_ability` ignores the API key
20
- # (see AdminAuthentication#current_ability) and we skip the scope cap
21
- # too, even if an `X-Spree-Api-Key` header was also sent.
18
+ # Prevents scope amplification for BOTH principals: a key minted via a
19
+ # secret API key can only carry scopes that key already holds, and a
20
+ # JWT staffer can only mint scopes within their own roles' permission
21
+ # keys (admin-role holders are unbounded). Scopes and role permissions
22
+ # share the catalog vocabulary, so both compare as expanded key sets.
22
23
  def create
23
- if scope_limited_principal? && (excess = requested_scopes.reject { |s| current_api_key.has_scope?(s) }).any?
24
+ if scope_limited_principal?
25
+ excess = requested_scopes.reject { |s| current_api_key.has_scope?(s) }
26
+ else
27
+ excess = excess_permission_keys(requested_scopes)
28
+ end
29
+
30
+ if excess.any?
24
31
  return render_error(
25
32
  code: ERROR_CODES[:access_denied],
26
33
  message: "Cannot grant scopes beyond your own: #{excess.join(', ')}",
@@ -40,7 +47,7 @@ module Spree
40
47
  @resource = find_resource
41
48
  authorize!(:update, @resource)
42
49
 
43
- @resource.revoke!(try_spree_current_user)
50
+ @resource.revoke!(current_actor)
44
51
  render json: serialize_resource(@resource)
45
52
  end
46
53
 
@@ -83,7 +90,7 @@ module Spree
83
90
  # happens in `before_validation :generate_token` on the model.
84
91
  def build_resource
85
92
  scope.new(permitted_params).tap do |key|
86
- key.created_by = try_spree_current_user
93
+ key.created_by = current_actor
87
94
  end
88
95
  end
89
96
 
@@ -91,6 +98,8 @@ module Spree
91
98
  # lives on Spree::ApiKey); update is limited to the human-facing `name`.
92
99
  # Stripping them here keeps them out of mass assignment so a rename
93
100
  # returns 200 rather than 422.
101
+ # No extension union: an API key's scopes and type are the authorization
102
+ # surface itself, not extensible resource data.
94
103
  def permitted_params
95
104
  return params.permit(:name) if action_name == 'update'
96
105