spree_api 5.6.1 → 6.0.0.beta1
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/LICENSE +28 -0
- data/Rakefile +1 -1
- data/app/controllers/concerns/spree/api/v3/address_params.rb +17 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_listing.rb +46 -0
- data/app/controllers/concerns/spree/api/v3/admin/product_membership.rb +110 -0
- data/app/controllers/concerns/spree/api/v3/admin/receivable_actions.rb +68 -0
- data/app/controllers/concerns/spree/api/v3/admin/reporting_authorization.rb +27 -0
- data/app/controllers/concerns/spree/api/v3/admin/role_grant_guard.rb +69 -33
- data/app/controllers/concerns/spree/api/v3/admin/stock_receipt_actions.rb +86 -0
- data/app/controllers/concerns/spree/api/v3/admin/store_context.rb +97 -0
- data/app/controllers/concerns/spree/api/v3/admin/subclassed_resource.rb +12 -6
- data/app/controllers/concerns/spree/api/v3/admin/validation_details.rb +91 -0
- data/app/controllers/concerns/spree/api/v3/admin_authentication.rb +9 -5
- data/app/controllers/concerns/spree/api/v3/api_key_authentication.rb +41 -5
- data/app/controllers/concerns/spree/api/v3/authentication_strategies.rb +48 -0
- data/app/controllers/concerns/spree/api/v3/bulk_operations.rb +4 -6
- data/app/controllers/concerns/spree/api/v3/cart_resolvable.rb +52 -16
- data/app/controllers/concerns/spree/api/v3/company_address_writes.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/current_password_confirmation.rb +41 -0
- data/app/controllers/concerns/spree/api/v3/direct_uploads.rb +35 -0
- data/app/controllers/concerns/spree/api/v3/error_handler.rb +53 -11
- data/app/controllers/concerns/spree/api/v3/idempotent.rb +10 -4
- data/app/controllers/concerns/spree/api/v3/items_payload.rb +54 -0
- data/app/controllers/concerns/spree/api/v3/jwt_authentication.rb +23 -3
- data/app/controllers/concerns/spree/api/v3/key_store_context.rb +31 -0
- data/app/controllers/concerns/spree/api/v3/locale_and_currency.rb +3 -3
- data/app/controllers/concerns/spree/api/v3/order_lock.rb +22 -3
- data/app/controllers/concerns/spree/api/v3/orders/claim_actions.rb +112 -0
- data/app/controllers/concerns/spree/api/v3/orders/delivery_actions.rb +105 -0
- data/app/controllers/concerns/spree/api/v3/orders/exchange_actions.rb +117 -0
- data/app/controllers/concerns/spree/api/v3/orders/fulfillment_actions.rb +157 -0
- data/app/controllers/concerns/spree/api/v3/orders/post_sale_actions.rb +76 -0
- data/app/controllers/concerns/spree/api/v3/orders/return_actions.rb +116 -0
- data/app/controllers/concerns/spree/api/v3/orders/shipping_label_actions.rb +128 -0
- data/app/controllers/concerns/spree/api/v3/params_normalizer.rb +7 -4
- data/app/controllers/concerns/spree/api/v3/permission_serialization.rb +42 -0
- data/app/controllers/concerns/spree/api/v3/rate_limit_headers.rb +40 -6
- data/app/controllers/concerns/spree/api/v3/scoped_authorization.rb +80 -26
- data/app/controllers/concerns/spree/api/v3/seller/auth_cookies.rb +62 -0
- data/app/controllers/concerns/spree/api/v3/seller/seller_context.rb +127 -0
- data/app/controllers/concerns/spree/api/v3/seller_authentication.rb +40 -0
- data/app/controllers/concerns/spree/api/v3/storefront_access.rb +38 -0
- data/app/controllers/concerns/spree/api/v3/streams_shipping_label.rb +37 -0
- data/app/controllers/concerns/spree/api/v3/tax_identifier_validation.rb +41 -0
- data/app/controllers/spree/api/v3/admin/admin_users_controller.rb +11 -14
- data/app/controllers/spree/api/v3/admin/allowed_origins_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/api_keys_controller.rb +16 -7
- data/app/controllers/spree/api/v3/admin/auth_controller.rb +138 -22
- data/app/controllers/spree/api/v3/admin/base_controller.rb +2 -0
- data/app/controllers/spree/api/v3/admin/catalog_assignments_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/catalogs/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/catalogs/order_minimums_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/catalogs/products_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/catalogs/quantity_rules_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/catalogs_controller.rb +191 -0
- data/app/controllers/spree/api/v3/admin/categories/products_controller.rb +28 -41
- data/app/controllers/spree/api/v3/admin/categories_controller.rb +16 -7
- data/app/controllers/spree/api/v3/admin/channels_controller.rb +50 -2
- data/app/controllers/spree/api/v3/admin/claim_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/claims_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/collection_rules_controller.rb +40 -0
- data/app/controllers/spree/api/v3/admin/collections/products_controller.rb +101 -0
- data/app/controllers/spree/api/v3/admin/collections_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/commission_lines_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/commission_rates_controller.rb +174 -0
- data/app/controllers/spree/api/v3/admin/companies/addresses_controller.rb +65 -0
- data/app/controllers/spree/api/v3/admin/companies/base_controller.rb +29 -0
- data/app/controllers/spree/api/v3/admin/companies/invitations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/companies/memberships_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_exemption_certificates_controller.rb +137 -0
- data/app/controllers/spree/api/v3/admin/companies/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/admin/companies_controller.rb +59 -0
- data/app/controllers/spree/api/v3/admin/concerns/external_references.rb +166 -0
- data/app/controllers/spree/api/v3/admin/consent_records_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/countries_controller.rb +12 -4
- data/app/controllers/spree/api/v3/admin/custom_field_definitions_controller.rb +19 -4
- data/app/controllers/spree/api/v3/admin/custom_fields_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/customer_groups_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/addresses_controller.rb +4 -4
- data/app/controllers/spree/api/v3/admin/customers/base_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/customers/store_credits_controller.rb +2 -3
- data/app/controllers/spree/api/v3/admin/customers/tax_identifiers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/customers_controller.rb +190 -11
- data/app/controllers/spree/api/v3/admin/dashboard_controller.rb +24 -20
- data/app/controllers/spree/api/v3/admin/data_requests_controller.rb +60 -0
- data/app/controllers/spree/api/v3/admin/delivery_method_rules_controller.rb +54 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods/rules_controller.rb +114 -0
- data/app/controllers/spree/api/v3/admin/delivery_methods_controller.rb +243 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles/origin_groups_controller.rb +80 -0
- data/app/controllers/spree/api/v3/admin/delivery_profiles_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/delivery_zones_controller.rb +116 -0
- data/app/controllers/spree/api/v3/admin/digital_links_controller.rb +48 -0
- data/app/controllers/spree/api/v3/admin/direct_uploads_controller.rb +17 -3
- data/app/controllers/spree/api/v3/admin/exchanges_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/exports_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/gift_card_batches_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/gift_cards_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/imports_controller.rb +71 -8
- data/app/controllers/spree/api/v3/admin/integrations_controller.rb +67 -0
- data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +5 -5
- data/app/controllers/spree/api/v3/admin/invitations_controller.rb +5 -1
- data/app/controllers/spree/api/v3/admin/locales_controller.rb +3 -1
- data/app/controllers/spree/api/v3/admin/markets_controller.rb +9 -5
- data/app/controllers/spree/api/v3/admin/me_controller.rb +4 -30
- data/app/controllers/spree/api/v3/admin/media_controller.rb +88 -38
- data/app/controllers/spree/api/v3/admin/media_library_controller.rb +156 -0
- data/app/controllers/spree/api/v3/admin/option_types_controller.rb +1 -0
- data/app/controllers/spree/api/v3/admin/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/order_groups_controller.rb +43 -0
- data/app/controllers/spree/api/v3/admin/order_routing_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/orders/claims_controller.rb +56 -0
- data/app/controllers/spree/api/v3/admin/orders/deliveries_controller.rb +66 -0
- data/app/controllers/spree/api/v3/admin/orders/discount_codes_controller.rb +86 -0
- data/app/controllers/spree/api/v3/admin/orders/discounts_controller.rb +99 -0
- data/app/controllers/spree/api/v3/admin/orders/exchanges_controller.rb +62 -0
- data/app/controllers/spree/api/v3/admin/orders/fees_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/orders/fulfillments_controller.rb +45 -67
- data/app/controllers/spree/api/v3/admin/orders/items_controller.rb +40 -22
- data/app/controllers/spree/api/v3/admin/orders/labels_controller.rb +75 -0
- data/app/controllers/spree/api/v3/admin/orders/payments_controller.rb +36 -18
- data/app/controllers/spree/api/v3/admin/orders/refunds_controller.rb +39 -18
- data/app/controllers/spree/api/v3/admin/orders/returns_controller.rb +70 -0
- data/app/controllers/spree/api/v3/admin/orders/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/orders/tax_identifiers_controller.rb +41 -0
- data/app/controllers/spree/api/v3/admin/orders/tax_lines_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/orders_controller.rb +157 -32
- data/app/controllers/spree/api/v3/admin/package_types_controller.rb +39 -0
- data/app/controllers/spree/api/v3/admin/password_resets_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/payment_methods_controller.rb +15 -4
- data/app/controllers/spree/api/v3/admin/payout_providers_controller.rb +27 -0
- data/app/controllers/spree/api/v3/admin/permissions_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/policies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/admin/price_lists/products_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/price_lists_controller.rb +43 -29
- data/app/controllers/spree/api/v3/admin/prices_controller.rb +41 -4
- data/app/controllers/spree/api/v3/admin/product_types_controller.rb +93 -0
- data/app/controllers/spree/api/v3/admin/products/digital_assets_controller.rb +148 -0
- data/app/controllers/spree/api/v3/admin/products/variants_controller.rb +24 -3
- data/app/controllers/spree/api/v3/admin/products_controller.rb +149 -33
- data/app/controllers/spree/api/v3/admin/promotion_actions_controller.rb +6 -2
- data/app/controllers/spree/api/v3/admin/promotion_rules_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/promotions_controller.rb +1 -5
- data/app/controllers/spree/api/v3/admin/purchase_orders/stock_receipts_controller.rb +32 -0
- data/app/controllers/spree/api/v3/admin/purchase_orders_controller.rb +161 -0
- data/app/controllers/spree/api/v3/admin/refund_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/reporting/saved_reports_controller.rb +45 -0
- data/app/controllers/spree/api/v3/admin/reporting_controller.rb +95 -0
- data/app/controllers/spree/api/v3/admin/resource_controller.rb +27 -10
- data/app/controllers/spree/api/v3/admin/return_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/returns_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/roles_controller.rb +50 -6
- data/app/controllers/spree/api/v3/admin/seller_payouts_controller.rb +83 -0
- data/app/controllers/spree/api/v3/admin/seller_requirement_submissions_controller.rb +139 -0
- data/app/controllers/spree/api/v3/admin/seller_requirements_controller.rb +115 -0
- data/app/controllers/spree/api/v3/admin/seller_transfers_controller.rb +36 -0
- data/app/controllers/spree/api/v3/admin/sellers/balances_controller.rb +44 -0
- data/app/controllers/spree/api/v3/admin/sellers/invitations_controller.rb +77 -0
- data/app/controllers/spree/api/v3/admin/sellers/payouts_controller.rb +107 -0
- data/app/controllers/spree/api/v3/admin/sellers/team_controller.rb +64 -0
- data/app/controllers/spree/api/v3/admin/sellers_controller.rb +197 -0
- data/app/controllers/spree/api/v3/admin/setup_controller.rb +231 -0
- data/app/controllers/spree/api/v3/admin/stock_levels_controller.rb +172 -0
- data/app/controllers/spree/api/v3/admin/stock_locations_controller.rb +3 -2
- data/app/controllers/spree/api/v3/admin/stock_movements_controller.rb +37 -0
- data/app/controllers/spree/api/v3/admin/stock_reservations_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/stock_transfers/stock_receipts_controller.rb +31 -0
- data/app/controllers/spree/api/v3/admin/stock_transfers_controller.rb +134 -38
- data/app/controllers/spree/api/v3/admin/store_controller.rb +65 -0
- data/app/controllers/spree/api/v3/admin/store_credits/events_controller.rb +47 -0
- data/app/controllers/spree/api/v3/admin/store_credits_controller.rb +87 -0
- data/app/controllers/spree/api/v3/admin/suppliers_controller.rb +30 -0
- data/app/controllers/spree/api/v3/admin/tags_controller.rb +2 -2
- data/app/controllers/spree/api/v3/admin/tax_categories_controller.rb +4 -0
- data/app/controllers/spree/api/v3/admin/tax_providers_controller.rb +25 -0
- data/app/controllers/spree/api/v3/admin/tax_rates_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/tracking_carriers_controller.rb +33 -0
- data/app/controllers/spree/api/v3/admin/translatable_resources_controller.rb +37 -9
- data/app/controllers/spree/api/v3/admin/translations_controller.rb +10 -5
- data/app/controllers/spree/api/v3/admin/translations_coverage_controller.rb +150 -0
- data/app/controllers/spree/api/v3/admin/variants_controller.rb +11 -4
- data/app/controllers/spree/api/v3/admin/webhook_endpoints_controller.rb +1 -1
- data/app/controllers/spree/api/v3/base_controller.rb +59 -16
- data/app/controllers/spree/api/v3/resource_controller.rb +154 -38
- data/app/controllers/spree/api/v3/seller/auth_controller.rb +169 -0
- data/app/controllers/spree/api/v3/seller/balances_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/base_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/claim_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/countries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/delivery_methods_controller.rb +265 -0
- data/app/controllers/spree/api/v3/seller/delivery_profiles_controller.rb +65 -0
- data/app/controllers/spree/api/v3/seller/delivery_zones_controller.rb +41 -0
- data/app/controllers/spree/api/v3/seller/direct_uploads_controller.rb +21 -0
- data/app/controllers/spree/api/v3/seller/exports_controller.rb +195 -0
- data/app/controllers/spree/api/v3/seller/import_rows_controller.rb +49 -0
- data/app/controllers/spree/api/v3/seller/imports_controller.rb +317 -0
- data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +152 -0
- data/app/controllers/spree/api/v3/seller/invitations_controller.rb +71 -0
- data/app/controllers/spree/api/v3/seller/me_controller.rb +72 -0
- data/app/controllers/spree/api/v3/seller/onboarding_controller.rb +111 -0
- data/app/controllers/spree/api/v3/seller/order_cancellation_reasons_controller.rb +25 -0
- data/app/controllers/spree/api/v3/seller/orders/base_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders/claims_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/orders/deliveries_controller.rb +38 -0
- data/app/controllers/spree/api/v3/seller/orders/exchanges_controller.rb +50 -0
- data/app/controllers/spree/api/v3/seller/orders/fulfillments_controller.rb +79 -0
- data/app/controllers/spree/api/v3/seller/orders/labels_controller.rb +55 -0
- data/app/controllers/spree/api/v3/seller/orders/notes_controller.rb +82 -0
- data/app/controllers/spree/api/v3/seller/orders/returns_controller.rb +44 -0
- data/app/controllers/spree/api/v3/seller/orders_controller.rb +199 -0
- data/app/controllers/spree/api/v3/seller/package_types_controller.rb +100 -0
- data/app/controllers/spree/api/v3/seller/password_resets_controller.rb +155 -0
- data/app/controllers/spree/api/v3/seller/payouts_controller.rb +47 -0
- data/app/controllers/spree/api/v3/seller/policies_controller.rb +57 -0
- data/app/controllers/spree/api/v3/seller/product_types_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/products_controller.rb +394 -0
- data/app/controllers/spree/api/v3/seller/profile_controller.rb +137 -0
- data/app/controllers/spree/api/v3/seller/reasons_controller.rb +45 -0
- data/app/controllers/spree/api/v3/seller/requirement_submissions_controller.rb +95 -0
- data/app/controllers/spree/api/v3/seller/resource_controller.rb +75 -0
- data/app/controllers/spree/api/v3/seller/return_reasons_controller.rb +20 -0
- data/app/controllers/spree/api/v3/seller/stock_locations_controller.rb +56 -0
- data/app/controllers/spree/api/v3/seller/tax_identifiers_controller.rb +48 -0
- data/app/controllers/spree/api/v3/seller/team_controller.rb +103 -0
- data/app/controllers/spree/api/v3/seller/tracking_carriers_controller.rb +35 -0
- data/app/controllers/spree/api/v3/seller/transfers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/account/companies_controller.rb +42 -0
- data/app/controllers/spree/api/v3/store/auth_controller.rb +21 -34
- data/app/controllers/spree/api/v3/store/base_controller.rb +4 -0
- data/app/controllers/spree/api/v3/store/carts/discount_codes_controller.rb +24 -2
- data/app/controllers/spree/api/v3/store/carts/fulfillments_controller.rb +41 -15
- data/app/controllers/spree/api/v3/store/carts/items_controller.rb +53 -20
- data/app/controllers/spree/api/v3/store/carts/payment_sessions_controller.rb +36 -20
- data/app/controllers/spree/api/v3/store/carts/po_documents_controller.rb +111 -0
- data/app/controllers/spree/api/v3/store/carts/store_credits_controller.rb +2 -2
- data/app/controllers/spree/api/v3/store/carts/tax_identifiers_controller.rb +96 -0
- data/app/controllers/spree/api/v3/store/carts_controller.rb +57 -12
- data/app/controllers/spree/api/v3/store/categories_controller.rb +6 -3
- data/app/controllers/spree/api/v3/store/collections/products_controller.rb +59 -0
- data/app/controllers/spree/api/v3/store/collections_controller.rb +36 -0
- data/app/controllers/spree/api/v3/store/companies/addresses_controller.rb +81 -0
- data/app/controllers/spree/api/v3/store/companies/base_controller.rb +24 -0
- data/app/controllers/spree/api/v3/store/companies/invitations_controller.rb +50 -0
- data/app/controllers/spree/api/v3/store/companies/members_controller.rb +66 -0
- data/app/controllers/spree/api/v3/store/companies/orders_controller.rb +28 -0
- data/app/controllers/spree/api/v3/store/companies_controller.rb +47 -0
- data/app/controllers/spree/api/v3/store/company_invitations_controller.rb +90 -0
- data/app/controllers/spree/api/v3/store/countries_controller.rb +8 -6
- data/app/controllers/spree/api/v3/store/customer/addresses_controller.rb +3 -1
- data/app/controllers/spree/api/v3/store/customer/data_requests_controller.rb +78 -0
- data/app/controllers/spree/api/v3/store/customer/digital_links_controller.rb +52 -0
- data/app/controllers/spree/api/v3/store/customer/orders_controller.rb +6 -0
- data/app/controllers/spree/api/v3/store/customer/password_resets_controller.rb +7 -3
- data/app/controllers/spree/api/v3/store/customer/payment_setup_sessions_controller.rb +3 -3
- data/app/controllers/spree/api/v3/store/customer/store_credits_controller.rb +0 -3
- data/app/controllers/spree/api/v3/store/customer/tax_identifiers_controller.rb +91 -0
- data/app/controllers/spree/api/v3/store/customers_controller.rb +26 -31
- data/app/controllers/spree/api/v3/store/data_feeds_controller.rb +11 -0
- data/app/controllers/spree/api/v3/store/data_request_downloads_controller.rb +58 -0
- data/app/controllers/spree/api/v3/store/delivery_methods_controller.rb +108 -0
- data/app/controllers/spree/api/v3/store/digital_links_controller.rb +105 -0
- data/app/controllers/spree/api/v3/store/markets/countries_controller.rb +5 -9
- data/app/controllers/spree/api/v3/store/markets_controller.rb +4 -4
- data/app/controllers/spree/api/v3/store/newsletter_subscribers_controller.rb +8 -9
- data/app/controllers/spree/api/v3/store/orders/claims_controller.rb +94 -0
- data/app/controllers/spree/api/v3/store/orders/returns_controller.rb +116 -0
- data/app/controllers/spree/api/v3/store/orders/tax_identifiers_controller.rb +46 -0
- data/app/controllers/spree/api/v3/store/orders_controller.rb +12 -15
- data/app/controllers/spree/api/v3/store/products/filters_controller.rb +10 -3
- data/app/controllers/spree/api/v3/store/products_controller.rb +25 -6
- data/app/controllers/spree/api/v3/store/resource_controller.rb +2 -0
- data/app/controllers/spree/api/v3/store/sellers_controller.rb +43 -0
- data/app/controllers/spree/api/v3/store/wishlist_items_controller.rb +9 -6
- data/app/controllers/spree/api/v3/store/wishlists_controller.rb +3 -3
- data/app/controllers/spree/api/v3/webhooks/fulfillments_controller.rb +88 -0
- data/app/controllers/spree/api/v3/webhooks/payments_controller.rb +5 -2
- data/app/controllers/spree/api/v3/webhooks/payouts_controller.rb +61 -0
- data/app/models/spree/api/data_request_urls.rb +25 -0
- data/app/models/spree/api/digital_link_urls.rb +26 -0
- data/app/serializers/spree/api/v3/address_serializer.rb +17 -5
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +27 -4
- data/app/serializers/spree/api/v3/admin/admin_user_serializer.rb +13 -10
- data/app/serializers/spree/api/v3/admin/api_key_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/applied_promotion_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/cart_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/catalog_assignment_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/catalog_order_minimum_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/catalog_price_tier_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/catalog_product_term_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/admin/catalog_quantity_rule_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/catalog_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +3 -2
- data/app/serializers/spree/api/v3/admin/channel_serializer.rb +15 -1
- data/app/serializers/spree/api/v3/admin/claim_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/claim_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/claim_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/collection_rule_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/collection_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/commission_line_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/commission_rate_serializer.rb +69 -0
- data/app/serializers/spree/api/v3/admin/commission_rule_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/admin/company_invitation_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/company_membership_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/company_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/concerns/external_references_attribute.rb +33 -0
- data/app/serializers/spree/api/v3/admin/consent_record_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/admin/country_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/custom_field_definition_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +23 -22
- data/app/serializers/spree/api/v3/admin/dashboard_counter_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/admin/data_request_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +66 -1
- data/app/serializers/spree/api/v3/admin/delivery_method_service_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/admin/delivery_origin_group_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/delivery_profile_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/delivery_rate_serializer.rb +10 -1
- data/app/serializers/spree/api/v3/admin/delivery_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_member_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/delivery_zone_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/digital_asset_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/admin/discount_serializer.rb +3 -4
- data/app/serializers/spree/api/v3/admin/exchange_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/exchange_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/admin/export_serializer.rb +20 -1
- data/app/serializers/spree/api/v3/admin/fee_serializer.rb +14 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_line_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/freight_summary_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_item_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +31 -9
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -3
- data/app/serializers/spree/api/v3/admin/import_serializer.rb +15 -2
- data/app/serializers/spree/api/v3/admin/integration_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +4 -4
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +19 -5
- data/app/serializers/spree/api/v3/admin/market_serializer.rb +5 -1
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +50 -2
- data/app/serializers/spree/api/v3/admin/membership_product_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_cancellation_reason_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/order_group_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/admin/order_routing_rule_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +131 -19
- data/app/serializers/spree/api/v3/admin/package_type_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +8 -2
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +6 -0
- data/app/serializers/spree/api/v3/admin/payment_split_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/admin/permission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/admin/price_adjustment_tier_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/admin/price_list_product_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/price_list_serializer.rb +20 -8
- data/app/serializers/spree/api/v3/admin/price_rule_serializer.rb +2 -12
- data/app/serializers/spree/api/v3/admin/price_serializer.rb +3 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +54 -8
- data/app/serializers/spree/api/v3/admin/product_submission_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/product_type_custom_field_definition_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/admin/product_type_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/admin/promotion_action_serializer.rb +6 -12
- data/app/serializers/spree/api/v3/admin/promotion_rule_serializer.rb +17 -15
- data/app/serializers/spree/api/v3/admin/purchase_order_item_serializer.rb +80 -0
- data/app/serializers/spree/api/v3/admin/purchase_order_serializer.rb +94 -0
- data/app/serializers/spree/api/v3/admin/refund_reason_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/admin/refund_serializer.rb +0 -5
- data/app/serializers/spree/api/v3/admin/reporting_result_serializer.rb +72 -0
- data/app/serializers/spree/api/v3/admin/return_line_item_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/admin/return_reason_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/return_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/admin/role_serializer.rb +24 -6
- data/app/serializers/spree/api/v3/admin/saved_report_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/admin/seller_balance_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +46 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_serializer.rb +68 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_status_serializer.rb +48 -0
- data/app/serializers/spree/api/v3/admin/seller_requirement_submission_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/seller_serializer.rb +92 -0
- data/app/serializers/spree/api/v3/admin/seller_team_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/admin/seller_transfer_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/admin/shipping_label_serializer.rb +82 -0
- data/app/serializers/spree/api/v3/admin/state_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/stock_level_serializer.rb +65 -0
- data/app/serializers/spree/api/v3/admin/stock_location_serializer.rb +20 -4
- data/app/serializers/spree/api/v3/admin/stock_movement_serializer.rb +116 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_receipt_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/admin/stock_reservation_serializer.rb +5 -5
- data/app/serializers/spree/api/v3/admin/stock_transfer_item_serializer.rb +57 -0
- data/app/serializers/spree/api/v3/admin/stock_transfer_serializer.rb +36 -16
- data/app/serializers/spree/api/v3/admin/store_credit_event_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +42 -7
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +63 -1
- data/app/serializers/spree/api/v3/admin/supplier_serializer.rb +39 -0
- data/app/serializers/spree/api/v3/admin/tax_exemption_certificate_serializer.rb +67 -0
- data/app/serializers/spree/api/v3/admin/tax_identifier_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/admin/tax_line_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/admin/tax_rate_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +49 -8
- data/app/serializers/spree/api/v3/applied_promotion_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/base_serializer.rb +39 -2
- data/app/serializers/spree/api/v3/cart_serializer.rb +90 -12
- data/app/serializers/spree/api/v3/category_serializer.rb +3 -3
- data/app/serializers/spree/api/v3/claim_line_item_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/claim_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/claim_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/collection_serializer.rb +41 -0
- data/app/serializers/spree/api/v3/company_invitation_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_membership_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/company_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/custom_field_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/customer_serializer.rb +9 -1
- data/app/serializers/spree/api/v3/data_request_event_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/data_request_serializer.rb +40 -0
- data/app/serializers/spree/api/v3/delivery_method_serializer.rb +12 -2
- data/app/serializers/spree/api/v3/delivery_rate_serializer.rb +34 -17
- data/app/serializers/spree/api/v3/delivery_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_member_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/delivery_zone_serializer.rb +13 -0
- data/app/serializers/spree/api/v3/digital_asset_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/digital_link_serializer.rb +6 -2
- data/app/serializers/spree/api/v3/discount_serializer.rb +21 -7
- data/app/serializers/spree/api/v3/exchange_line_item_serializer.rb +53 -0
- data/app/serializers/spree/api/v3/exchange_serializer.rb +61 -0
- data/app/serializers/spree/api/v3/fee_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/freight_summary_serializer.rb +38 -0
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +28 -15
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/import_row_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/import_serializer.rb +18 -4
- data/app/serializers/spree/api/v3/invitation_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/line_item_serializer.rb +18 -1
- data/app/serializers/spree/api/v3/market_serializer.rb +2 -2
- data/app/serializers/spree/api/v3/{asset_serializer.rb → media_event_serializer.rb} +4 -4
- data/app/serializers/spree/api/v3/media_serializer.rb +48 -7
- data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/option_type_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/order_group_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/order_serializer.rb +58 -6
- data/app/serializers/spree/api/v3/payment_method_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/payment_serializer.rb +2 -6
- data/app/serializers/spree/api/v3/payment_session_serializer.rb +10 -3
- data/app/serializers/spree/api/v3/payment_setup_session_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/policy_serializer.rb +7 -2
- data/app/serializers/spree/api/v3/product_filter_option_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/product_serializer.rb +42 -10
- data/app/serializers/spree/api/v3/product_type_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/purchase_order_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/refund_serializer.rb +9 -3
- data/app/serializers/spree/api/v3/return_line_item_serializer.rb +42 -0
- data/app/serializers/spree/api/v3/return_reason_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/return_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/balance_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/claim_line_item_serializer.rb +21 -0
- data/app/serializers/spree/api/v3/seller/claim_serializer.rb +25 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_rule_serializer.rb +32 -0
- data/app/serializers/spree/api/v3/seller/delivery_method_serializer.rb +59 -0
- data/app/serializers/spree/api/v3/seller/delivery_profile_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/delivery_rate_serializer.rb +35 -0
- data/app/serializers/spree/api/v3/seller/delivery_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/delivery_zone_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/exchange_line_item_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/exchange_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/export_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_item_serializer.rb +43 -0
- data/app/serializers/spree/api/v3/seller/fulfillment_serializer.rb +76 -0
- data/app/serializers/spree/api/v3/seller/import_mapping_serializer.rb +20 -0
- data/app/serializers/spree/api/v3/seller/import_row_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/import_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/media_serializer.rb +26 -0
- data/app/serializers/spree/api/v3/seller/order_line_item_serializer.rb +44 -0
- data/app/serializers/spree/api/v3/seller/order_serializer.rb +119 -0
- data/app/serializers/spree/api/v3/seller/package_type_serializer.rb +52 -0
- data/app/serializers/spree/api/v3/seller/payment_split_serializer.rb +34 -0
- data/app/serializers/spree/api/v3/seller/payout_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/policy_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/seller/product_serializer.rb +60 -0
- data/app/serializers/spree/api/v3/seller/product_submission_serializer.rb +30 -0
- data/app/serializers/spree/api/v3/seller/product_type_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/seller/profile_serializer.rb +77 -0
- data/app/serializers/spree/api/v3/seller/reason_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/requirement_custom_field_serializer.rb +36 -0
- data/app/serializers/spree/api/v3/seller/requirement_status_serializer.rb +62 -0
- data/app/serializers/spree/api/v3/seller/requirement_submission_serializer.rb +33 -0
- data/app/serializers/spree/api/v3/seller/return_line_item_serializer.rb +24 -0
- data/app/serializers/spree/api/v3/seller/return_serializer.rb +51 -0
- data/app/serializers/spree/api/v3/seller/shipping_label_serializer.rb +23 -0
- data/app/serializers/spree/api/v3/seller/stock_level_serializer.rb +27 -0
- data/app/serializers/spree/api/v3/seller/stock_location_serializer.rb +17 -0
- data/app/serializers/spree/api/v3/seller/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/seller/team_member_serializer.rb +22 -0
- data/app/serializers/spree/api/v3/seller/transfer_serializer.rb +49 -0
- data/app/serializers/spree/api/v3/seller/variant_serializer.rb +71 -0
- data/app/serializers/spree/api/v3/seller_serializer.rb +50 -0
- data/app/serializers/spree/api/v3/shipping_label_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/{stock_item_serializer.rb → stock_level_serializer.rb} +5 -5
- data/app/serializers/spree/api/v3/stock_location_serializer.rb +11 -7
- data/app/serializers/spree/api/v3/stock_movement_serializer.rb +8 -15
- data/app/serializers/spree/api/v3/stock_receipt_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/stock_transfer_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/store_credit_event_serializer.rb +29 -0
- data/app/serializers/spree/api/v3/supplier_event_serializer.rb +11 -0
- data/app/serializers/spree/api/v3/tax_identifier_serializer.rb +15 -0
- data/app/serializers/spree/api/v3/tax_line_serializer.rb +37 -0
- data/app/serializers/spree/api/v3/variant_serializer.rb +52 -2
- data/app/serializers/spree/api/v3/wishlist_item_serializer.rb +6 -6
- data/app/serializers/spree/api/v3/wishlist_serializer.rb +1 -1
- data/app/services/spree/api/v3/filters_aggregator.rb +14 -12
- data/app/services/spree/webhooks/deliver_webhook.rb +62 -26
- data/app/subscribers/spree/webhook_event_subscriber.rb +9 -5
- data/config/brakeman.ignore +1 -1
- data/config/initializers/typelizer.rb +51 -4
- data/config/locales/en.yml +5 -0
- data/config/routes.rb +730 -22
- data/lib/spree/api/configuration.rb +2 -7
- data/lib/spree/api/dependencies.rb +173 -227
- data/lib/spree/api/openapi/schema_helper.rb +179 -13
- data/lib/spree/api/testing_support/v3/base.rb +45 -15
- data/lib/spree/api.rb +10 -4
- data/lib/typelizer/open_enums.rb +35 -0
- metadata +341 -27
- data/app/controllers/spree/api/v3/admin/orders/adjustments_controller.rb +0 -25
- data/app/controllers/spree/api/v3/admin/stock_items_controller.rb +0 -42
- data/app/controllers/spree/api/v3/admin/store_credit_categories_controller.rb +0 -21
- data/app/controllers/spree/api/v3/store/digitals_controller.rb +0 -38
- data/app/serializers/spree/api/v3/admin/adjustment_serializer.rb +0 -24
- data/app/serializers/spree/api/v3/admin/dashboard_analytics_serializer.rb +0 -143
- data/app/serializers/spree/api/v3/admin/reimbursement_serializer.rb +0 -15
- data/app/serializers/spree/api/v3/admin/return_authorization_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/admin/stock_item_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/admin/store_credit_category_serializer.rb +0 -19
- data/app/serializers/spree/api/v3/customer_return_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/digital_serializer.rb +0 -17
- data/app/serializers/spree/api/v3/reimbursement_serializer.rb +0 -27
- data/app/serializers/spree/api/v3/report_serializer.rb +0 -34
- data/app/serializers/spree/api/v3/return_authorization_serializer.rb +0 -31
- data/app/serializers/spree/api/v3/return_item_serializer.rb +0 -53
- data/app/serializers/spree/api/v3/shipping_category_serializer.rb +0 -11
|
@@ -76,16 +76,16 @@ module Spree
|
|
|
76
76
|
|
|
77
77
|
private
|
|
78
78
|
|
|
79
|
-
# Per-subclass permitted params
|
|
80
|
-
#
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
#
|
|
79
|
+
# Per-subclass permitted params: the controller's own allowlist plus
|
|
80
|
+
# whatever the concrete subclass declares through
|
|
81
|
+
# `additional_permitted_attributes`. Controllers can override this
|
|
82
|
+
# hook directly if their subclasses expose extras through a different
|
|
83
|
+
# mechanism.
|
|
84
84
|
def permitted_params_for(klass)
|
|
85
85
|
extras = klass.respond_to?(:additional_permitted_attributes) ? klass.additional_permitted_attributes : []
|
|
86
86
|
return permitted_params if extras.blank?
|
|
87
87
|
|
|
88
|
-
params.permit(:type,
|
|
88
|
+
permitted_params.merge(params.permit(:type, *extras, preferences: {}))
|
|
89
89
|
end
|
|
90
90
|
|
|
91
91
|
# Default build: top-level resource. Nested controllers (actions,
|
|
@@ -115,6 +115,12 @@ module Spree
|
|
|
115
115
|
preferences.each do |key, value|
|
|
116
116
|
pref_name = key.to_sym
|
|
117
117
|
next unless resource.has_preference?(pref_name)
|
|
118
|
+
# Internal preferences are Spree's to write — a secret a
|
|
119
|
+
# provider issued, an id it gave back. They are absent from the
|
|
120
|
+
# schema, so no form offers them; ignoring them here is what
|
|
121
|
+
# stops a client writing one anyway and breaking the signature
|
|
122
|
+
# check that depends on it.
|
|
123
|
+
next if resource.preference_internal(pref_name)
|
|
118
124
|
# Round-trip guard: clients fetching a record see masked
|
|
119
125
|
# `:password` values. Submitting the mask back unchanged
|
|
120
126
|
# must NOT overwrite the real secret with `••••cret`.
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Richer validation details for the Admin API.
|
|
6
|
+
#
|
|
7
|
+
# The dashboard renders its own copy from its own locale files, so an
|
|
8
|
+
# admin working in one language never reads a message resolved in the
|
|
9
|
+
# store's. To let it do that, every entry carries the Rails error
|
|
10
|
+
# `code` and the interpolation values that go with it; `message` stays
|
|
11
|
+
# beside it as the fallback for clients without their own translation
|
|
12
|
+
# (integrations, scripts, and the dashboard's own last resort).
|
|
13
|
+
#
|
|
14
|
+
# Store API responses keep the flat `{ attribute => [message] }` shape
|
|
15
|
+
# — this override is deliberately not in the shared error handler.
|
|
16
|
+
module ValidationDetails
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
# @param errors [ActiveModel::Errors]
|
|
20
|
+
# @return [Hash{Symbol => Array<Hash>}] per-attribute error entries
|
|
21
|
+
def format_validation_details(errors)
|
|
22
|
+
errors.messages.each_with_object({}) do |(attribute, messages), result|
|
|
23
|
+
# `details` and `messages` are populated in lockstep by
|
|
24
|
+
# ActiveModel, so the nth message describes the nth detail. A
|
|
25
|
+
# message added as a bare string has no symbol and reports a
|
|
26
|
+
# nil code, which the dashboard reads as "render the message".
|
|
27
|
+
details = errors.details[attribute] || []
|
|
28
|
+
|
|
29
|
+
result[attribute] = messages.each_with_index.map do |message, index|
|
|
30
|
+
detail = details[index] || {}
|
|
31
|
+
code = detail[:error].is_a?(Symbol) ? detail[:error] : nil
|
|
32
|
+
|
|
33
|
+
# Interpolation values first, so the keys below are the ones
|
|
34
|
+
# this formatter computed: a validation may itself carry a
|
|
35
|
+
# `code:` option, and it must not displace the Rails error.
|
|
36
|
+
detail.except(:error).merge(
|
|
37
|
+
code: code,
|
|
38
|
+
message: message,
|
|
39
|
+
specific: code.present? &&
|
|
40
|
+
specific_message?(errors, attribute, code, message, detail.except(:error))
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Whether `message` says more than its `code` alone would.
|
|
47
|
+
#
|
|
48
|
+
# A code like `:invalid` is generic, and a client holding its own
|
|
49
|
+
# translation of that code should prefer it. But a model may override
|
|
50
|
+
# the message for the same code with something far more useful — the
|
|
51
|
+
# webhook URL validation reports `:invalid` and answers "must be a
|
|
52
|
+
# valid http or https URL". Replacing that with a translated "is
|
|
53
|
+
# invalid" loses what the merchant needs.
|
|
54
|
+
#
|
|
55
|
+
# Only the server can tell the two apart: the comparison is against
|
|
56
|
+
# the code's default *in the request's locale*, so it holds for a
|
|
57
|
+
# store trading in any language. A client cannot do it — it would
|
|
58
|
+
# have to recognise the default wording in every locale it supports.
|
|
59
|
+
#
|
|
60
|
+
# `raise: true` matters. Without it a code Rails has no default for
|
|
61
|
+
# — every Spree code, whose copy lives under `spree.errors.messages`
|
|
62
|
+
# — comes back as a "Translation missing" string, which differs from
|
|
63
|
+
# the message and would mark every one of them as an override.
|
|
64
|
+
#
|
|
65
|
+
# The validation's own options come along: rebuilding the default for
|
|
66
|
+
# `greater_than` without its `count` raises on the missing value.
|
|
67
|
+
#
|
|
68
|
+
# @return [Boolean] true when the model supplied its own wording
|
|
69
|
+
def specific_message?(errors, attribute, code, message, options = {})
|
|
70
|
+
message != errors.generate_message(attribute, code, **options.symbolize_keys, raise: true)
|
|
71
|
+
rescue StandardError
|
|
72
|
+
# Rebuilding the default can fail in several ordinary ways, and none
|
|
73
|
+
# of them should turn a 422 into a 500:
|
|
74
|
+
#
|
|
75
|
+
# - `I18n::MissingTranslationData` — no Rails default at all, which
|
|
76
|
+
# is every Spree code.
|
|
77
|
+
# - `I18n::MissingInterpolationArgument` — the default interpolates
|
|
78
|
+
# (`greater_than` wants `count`) but the call site passed only a
|
|
79
|
+
# `message:`, so the value was never recorded.
|
|
80
|
+
# - `NoMethodError` — a nested attribute (`option_values.name`)
|
|
81
|
+
# names no method to read.
|
|
82
|
+
#
|
|
83
|
+
# In each case there is no default to compare against, so report no
|
|
84
|
+
# override and let the client translate the code.
|
|
85
|
+
false
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
@@ -30,9 +30,9 @@ module Spree
|
|
|
30
30
|
# Secret keys are checked first (server-to-server integrations),
|
|
31
31
|
# then JWT tokens (admin SPA sessions).
|
|
32
32
|
def authenticate_admin!
|
|
33
|
-
# Try secret API key first
|
|
34
|
-
|
|
35
|
-
@current_api_key =
|
|
33
|
+
# Try secret API key first — the key selects the request's store
|
|
34
|
+
# (Admin::StoreContext), so there is no store check to make here.
|
|
35
|
+
@current_api_key = secret_api_key
|
|
36
36
|
|
|
37
37
|
if @current_api_key
|
|
38
38
|
touch_api_key_if_needed(@current_api_key)
|
|
@@ -61,10 +61,14 @@ module Spree
|
|
|
61
61
|
false
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
# Membership is holding a role the store itself owns, mirroring
|
|
65
|
+
# Spree::Ability#staff_roles. A role belonging to another resource — a
|
|
66
|
+
# marketplace seller, say — is that panel's business and never admits
|
|
67
|
+
# its holder here.
|
|
64
68
|
def current_user_member_of_store?
|
|
65
|
-
return false unless current_user.respond_to?(:
|
|
69
|
+
return false unless current_user.respond_to?(:spree_roles)
|
|
66
70
|
|
|
67
|
-
current_user.
|
|
71
|
+
current_user.spree_roles.for_resource(current_store).exists?
|
|
68
72
|
end
|
|
69
73
|
|
|
70
74
|
def set_no_store_cache
|
|
@@ -12,11 +12,13 @@ module Spree
|
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
# Authenticates a publishable API key (pk_*) for Store API requests.
|
|
15
|
-
#
|
|
15
|
+
# The key SELECTS the store — lookup is global by token and
|
|
16
|
+
# +current_store+ derives from the key (see KeyStoreContext); the key
|
|
17
|
+
# is never validated against a host-resolved store.
|
|
16
18
|
#
|
|
17
19
|
# @return [Boolean] true if authentication succeeded, false otherwise
|
|
18
20
|
def authenticate_api_key!
|
|
19
|
-
@current_api_key =
|
|
21
|
+
@current_api_key = publishable_api_key
|
|
20
22
|
|
|
21
23
|
unless @current_api_key
|
|
22
24
|
render_error(
|
|
@@ -33,12 +35,12 @@ module Spree
|
|
|
33
35
|
|
|
34
36
|
# Authenticates a secret API key (sk_*) for Admin API requests.
|
|
35
37
|
# Computes the HMAC-SHA256 digest of the provided token and looks up
|
|
36
|
-
# by +token_digest
|
|
38
|
+
# by +token_digest+. The key is store-bound and selects the request's
|
|
39
|
+
# store (see Admin::StoreContext).
|
|
37
40
|
#
|
|
38
41
|
# @return [Boolean] true if authentication succeeded, false otherwise
|
|
39
42
|
def authenticate_secret_key!
|
|
40
|
-
@current_api_key =
|
|
41
|
-
@current_api_key = nil if @current_api_key && @current_api_key.store_id != current_store.id
|
|
43
|
+
@current_api_key = secret_api_key
|
|
42
44
|
|
|
43
45
|
unless @current_api_key
|
|
44
46
|
render_error(
|
|
@@ -55,6 +57,31 @@ module Spree
|
|
|
55
57
|
|
|
56
58
|
private
|
|
57
59
|
|
|
60
|
+
# Memoized global publishable-key lookup. Deliberately NOT scoped to
|
|
61
|
+
# +current_store+ — the store derives from the key, not the other way
|
|
62
|
+
# around. Memoizes misses too, so pre-authentication callers (store
|
|
63
|
+
# resolution) don't re-query.
|
|
64
|
+
#
|
|
65
|
+
# @return [Spree::ApiKey, nil]
|
|
66
|
+
def publishable_api_key
|
|
67
|
+
return @publishable_api_key if defined?(@publishable_api_key)
|
|
68
|
+
|
|
69
|
+
@publishable_api_key = Spree::StoreScopeGuard.skip do
|
|
70
|
+
extract_api_key ? Spree::ApiKey.active.publishable.find_by(token: extract_api_key) : nil
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# Memoized global secret-key lookup (digest-based, active keys only).
|
|
75
|
+
#
|
|
76
|
+
# @return [Spree::ApiKey, nil]
|
|
77
|
+
def secret_api_key
|
|
78
|
+
return @secret_api_key if defined?(@secret_api_key)
|
|
79
|
+
|
|
80
|
+
@secret_api_key = Spree::StoreScopeGuard.skip do
|
|
81
|
+
Spree::ApiKey.find_by_secret_token(extract_api_key)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
58
85
|
# Marks the API key as used at most once per hour
|
|
59
86
|
# to avoid unnecessary DB writes and job queue pressure on every request.
|
|
60
87
|
# This follows the same approach as GitHub's personal access tokens.
|
|
@@ -70,6 +97,15 @@ module Spree
|
|
|
70
97
|
def extract_api_key
|
|
71
98
|
request.headers['X-Spree-Api-Key'].presence
|
|
72
99
|
end
|
|
100
|
+
|
|
101
|
+
# True when the request presents a secret API key token (`sk_` prefix),
|
|
102
|
+
# regardless of whether authentication has resolved it into
|
|
103
|
+
# `current_api_key` yet. The token is unverified until
|
|
104
|
+
# `authenticate_secret_key!` resolves it, so consumers (the scope
|
|
105
|
+
# guard, rate limiting) must stay fail-closed on this signal alone.
|
|
106
|
+
def secret_key_request?
|
|
107
|
+
extract_api_key.to_s.start_with?(Spree::ApiKey::PREFIXES['secret'])
|
|
108
|
+
end
|
|
73
109
|
end
|
|
74
110
|
end
|
|
75
111
|
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Resolves the authentication strategy a login request asked for, shared by
|
|
5
|
+
# the Store and Admin auth controllers so the unsupported-provider contract
|
|
6
|
+
# (error code, status, message) has exactly one definition.
|
|
7
|
+
#
|
|
8
|
+
# Including controllers supply the registry and user class.
|
|
9
|
+
module AuthenticationStrategies
|
|
10
|
+
extend ActiveSupport::Concern
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
# @param provider [String, nil] defaults to the +provider+ param, then :email
|
|
15
|
+
# @return [Object, nil] a strategy instance, or nil after rendering an error
|
|
16
|
+
def authentication_strategy(provider = nil)
|
|
17
|
+
provider ||= params[:provider].presence || 'email'
|
|
18
|
+
|
|
19
|
+
strategy = authentication_strategies.build(
|
|
20
|
+
provider,
|
|
21
|
+
params: params,
|
|
22
|
+
request_env: request.headers.env,
|
|
23
|
+
user_class: authentication_user_class
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
return strategy if strategy
|
|
27
|
+
|
|
28
|
+
render_error(
|
|
29
|
+
code: Spree::Api::V3::ErrorHandler::ERROR_CODES[:invalid_provider],
|
|
30
|
+
message: "Unsupported authentication provider: #{provider}",
|
|
31
|
+
status: :bad_request
|
|
32
|
+
)
|
|
33
|
+
nil
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [Spree::Authentication::StrategyRegistry]
|
|
37
|
+
def authentication_strategies
|
|
38
|
+
raise NotImplementedError, "#{self.class} must implement #authentication_strategies"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [Class]
|
|
42
|
+
def authentication_user_class
|
|
43
|
+
raise NotImplementedError, "#{self.class} must implement #authentication_user_class"
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
module Spree
|
|
2
2
|
module Api
|
|
3
3
|
module V3
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
7
|
-
# search + match automatic taxons). Shape mirrors the legacy concern so
|
|
8
|
-
# the two stay easy to keep in sync.
|
|
4
|
+
# Provides the shared tag bulk actions, the `bulk_collection` relation,
|
|
5
|
+
# and the `after_bulk_tags_change` hook controllers override (e.g. to
|
|
6
|
+
# reindex search + match automatic taxons).
|
|
9
7
|
module BulkOperations
|
|
10
8
|
extend ActiveSupport::Concern
|
|
11
9
|
|
|
@@ -56,7 +54,7 @@ module Spree
|
|
|
56
54
|
|
|
57
55
|
# Hook for controllers to perform additional work after bulk tag
|
|
58
56
|
# mutations — e.g. enqueueing search reindex jobs, re-matching
|
|
59
|
-
# automatic taxons.
|
|
57
|
+
# automatic taxons.
|
|
60
58
|
def after_bulk_tags_change
|
|
61
59
|
end
|
|
62
60
|
|
|
@@ -6,33 +6,69 @@ module Spree
|
|
|
6
6
|
|
|
7
7
|
protected
|
|
8
8
|
|
|
9
|
-
# Find cart by prefixed ID and authorize access
|
|
10
|
-
#
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
# Find cart by prefixed ID and authorize read access (owner or guest
|
|
10
|
+
# token). Completed carts are not carts anymore — they 404 unless the
|
|
11
|
+
# caller opts in (idempotent completion, payment-session confirm races).
|
|
12
|
+
# @return [Spree::Cart]
|
|
13
|
+
def find_cart(include_completed: false)
|
|
14
|
+
@cart = resolve_cart(include_completed: include_completed)
|
|
15
|
+
authorize_storefront_read!(@cart, token: cart_token)
|
|
15
16
|
@cart
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
# Find the cart and authorize it for
|
|
19
|
-
#
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
# Find the cart and authorize it for mutation. A completed cart
|
|
20
|
+
# resolves only for opted-in flows, where mutation is impossible — a
|
|
21
|
+
# read check is the right bar there.
|
|
22
|
+
# @return [Spree::Cart]
|
|
23
|
+
def find_cart!(include_completed: false)
|
|
24
|
+
@cart = resolve_cart(include_completed: include_completed)
|
|
25
|
+
|
|
26
|
+
if @cart.completed?
|
|
27
|
+
authorize_storefront_read!(@cart, token: cart_token)
|
|
28
|
+
else
|
|
29
|
+
authorize_storefront_write!(@cart, token: cart_token)
|
|
30
|
+
end
|
|
31
|
+
|
|
24
32
|
@cart
|
|
25
33
|
end
|
|
26
34
|
|
|
27
|
-
|
|
35
|
+
def resolve_cart(include_completed:)
|
|
36
|
+
cart_id = params[:cart_id] || params[:id]
|
|
37
|
+
scope = current_store.carts
|
|
38
|
+
scope = scope.incomplete unless include_completed
|
|
39
|
+
scope.find_by_prefix_id!(cart_id)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Render the cart as JSON using the cart serializer. Rendering never
|
|
43
|
+
# mutates: an action that wants unbuyable lines swept calls
|
|
44
|
+
# +sweep_unbuyable_lines!+ itself first.
|
|
28
45
|
def render_cart(status: :ok)
|
|
29
|
-
@cart = @cart.remove_out_of_stock_items!
|
|
30
46
|
render json: Spree.api.cart_serializer.new(@cart, params: serializer_params).to_h, status: status
|
|
31
47
|
end
|
|
32
48
|
|
|
33
|
-
#
|
|
49
|
+
# Drops lines the customer can no longer buy — a discontinued product,
|
|
50
|
+
# or stock that ran out while the cart sat idle. For reads of a cart
|
|
51
|
+
# the customer is returning to, never for the write that just
|
|
52
|
+
# happened: an add a stock check already approved must not be
|
|
53
|
+
# second-guessed in the same request, and an external inventory
|
|
54
|
+
# provider makes that contradiction routine, since the provider
|
|
55
|
+
# answers the write while the sweep reads Spree's own rows.
|
|
56
|
+
def sweep_unbuyable_lines!
|
|
57
|
+
@cart = @cart.remove_out_of_stock_items!
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Render what the checkout produced (for the complete action).
|
|
61
|
+
#
|
|
62
|
+
# A checkout spanning several sellers produced a group of orders rather
|
|
63
|
+
# than one order, and the group is what the customer bought — so it is
|
|
64
|
+
# what comes back, with the per-seller orders nested inside it. A
|
|
65
|
+
# storefront that knows nothing about groups still finds every order it
|
|
66
|
+
# needs there.
|
|
34
67
|
def render_order(status: :ok)
|
|
35
|
-
|
|
68
|
+
record = @cart.reload
|
|
69
|
+
serializer = record.is_a?(Spree::OrderGroup) ? Spree.api.order_group_serializer : Spree.api.order_serializer
|
|
70
|
+
|
|
71
|
+
render json: serializer.new(record, params: serializer_params).to_h, status: status
|
|
36
72
|
end
|
|
37
73
|
|
|
38
74
|
# Return the cart token from the request headers.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Writing an entry in a company node's address book, on either API.
|
|
5
|
+
#
|
|
6
|
+
# An entry is an ordinary address the node owns, so the payload is
|
|
7
|
+
# address attributes plus the label it is filed under. The two defaults
|
|
8
|
+
# are not columns on the row — they are pointers on the node — so they
|
|
9
|
+
# travel to the address services as flags, which apply them once the
|
|
10
|
+
# address itself is written.
|
|
11
|
+
module CompanyAddressWrites
|
|
12
|
+
extend ActiveSupport::Concern
|
|
13
|
+
|
|
14
|
+
protected
|
|
15
|
+
|
|
16
|
+
def permitted_params
|
|
17
|
+
params.permit(:label, *Spree::Api::V3::AddressParams::ADDRESS_KEYS)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [Hash] default keywords for Spree::Addresses::Create / Update
|
|
21
|
+
def default_flags
|
|
22
|
+
{ default_billing: flag_param(:default_billing), default_shipping: flag_param(:default_shipping) }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Each flag has three meanings and they are all different: true claims
|
|
26
|
+
# the slot, false gives it up, and saying nothing leaves it alone.
|
|
27
|
+
#
|
|
28
|
+
# @return [Boolean, nil] nil when the client said nothing about it
|
|
29
|
+
def flag_param(name)
|
|
30
|
+
return nil unless params.key?(name)
|
|
31
|
+
|
|
32
|
+
ActiveModel::Type::Boolean.new.cast(params[name])
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Re-asks for the account password before something irreversible.
|
|
5
|
+
#
|
|
6
|
+
# Shared because the check must not drift: a customer class may
|
|
7
|
+
# authenticate through `valid_password?` or `authenticate` depending on
|
|
8
|
+
# what the host app swapped in, and a second copy of that ladder is a
|
|
9
|
+
# second thing to remember when it changes. One of the two call sites
|
|
10
|
+
# gates permanent erasure.
|
|
11
|
+
module CurrentPasswordConfirmation
|
|
12
|
+
extend ActiveSupport::Concern
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
# @return [Boolean] whether `current_password` matches the signed-in
|
|
17
|
+
# account. False when the parameter is missing — an absent password
|
|
18
|
+
# is not a correct one.
|
|
19
|
+
def valid_current_password?
|
|
20
|
+
return false if params[:current_password].blank?
|
|
21
|
+
|
|
22
|
+
if current_user.respond_to?(:valid_password?)
|
|
23
|
+
current_user.valid_password?(params[:current_password])
|
|
24
|
+
elsif current_user.respond_to?(:authenticate)
|
|
25
|
+
current_user.authenticate(params[:current_password]).present?
|
|
26
|
+
else
|
|
27
|
+
false
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def render_current_password_invalid
|
|
32
|
+
render_error(
|
|
33
|
+
code: ErrorHandler::ERROR_CODES[:current_password_invalid],
|
|
34
|
+
message: Spree.t(:current_password_invalid, scope: :api),
|
|
35
|
+
status: :unprocessable_content
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
# Presigning for direct-to-storage uploads: a caller exchanges blob
|
|
5
|
+
# metadata for an upload URL and gets back a signed id to reference when
|
|
6
|
+
# it creates or updates a resource.
|
|
7
|
+
#
|
|
8
|
+
# Shared by the admin and seller branches because the exchange itself is
|
|
9
|
+
# audience-neutral — a blob created here is attached to nothing. What
|
|
10
|
+
# differs is the gate each branch puts in front of it, which stays on the
|
|
11
|
+
# including controller as its `scoped_resource`.
|
|
12
|
+
module DirectUploads
|
|
13
|
+
extend ActiveSupport::Concern
|
|
14
|
+
|
|
15
|
+
def create
|
|
16
|
+
blob = ActiveStorage::Blob.create_before_direct_upload!(**blob_params)
|
|
17
|
+
|
|
18
|
+
render json: {
|
|
19
|
+
direct_upload: {
|
|
20
|
+
url: blob.service_url_for_direct_upload,
|
|
21
|
+
headers: blob.service_headers_for_direct_upload
|
|
22
|
+
},
|
|
23
|
+
signed_id: blob.signed_id
|
|
24
|
+
}, status: :created
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def blob_params
|
|
30
|
+
params.require(:blob).permit(:filename, :byte_size, :checksum, :content_type).to_h.symbolize_keys
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -13,6 +13,10 @@ module Spree
|
|
|
13
13
|
invalid_token: 'invalid_token',
|
|
14
14
|
invalid_provider: 'invalid_provider',
|
|
15
15
|
invalid_refresh_token: 'invalid_refresh_token',
|
|
16
|
+
# Distinct from authentication_failed: the person proved who they are to
|
|
17
|
+
# the identity provider, but no account here is authorized for them.
|
|
18
|
+
account_not_provisioned: 'account_not_provisioned',
|
|
19
|
+
invalid_oauth_state: 'invalid_oauth_state',
|
|
16
20
|
current_password_invalid: 'current_password_invalid',
|
|
17
21
|
password_reset_token_invalid: 'password_reset_token_invalid',
|
|
18
22
|
redirect_url_not_allowed: 'redirect_url_not_allowed',
|
|
@@ -36,12 +40,15 @@ module Spree
|
|
|
36
40
|
# Order errors
|
|
37
41
|
order_not_found: 'order_not_found',
|
|
38
42
|
order_cannot_complete: 'order_cannot_complete',
|
|
43
|
+
discount_not_editable: 'discount_not_editable',
|
|
39
44
|
|
|
40
45
|
# Line item errors
|
|
41
46
|
line_item_not_found: 'line_item_not_found',
|
|
42
47
|
variant_not_found: 'variant_not_found',
|
|
43
48
|
insufficient_stock: 'insufficient_stock',
|
|
44
49
|
invalid_quantity: 'invalid_quantity',
|
|
50
|
+
invalid_price: 'invalid_price',
|
|
51
|
+
price_override_not_allowed: 'price_override_not_allowed',
|
|
45
52
|
|
|
46
53
|
# Validation errors
|
|
47
54
|
validation_error: 'validation_error',
|
|
@@ -85,12 +92,12 @@ module Spree
|
|
|
85
92
|
# Override base controller error handlers
|
|
86
93
|
rescue_from ActiveRecord::RecordNotFound, with: :handle_record_not_found
|
|
87
94
|
rescue_from CanCan::AccessDenied, with: :handle_access_denied
|
|
95
|
+
rescue_from Spree::Storefront::AccessDenied, with: :handle_access_denied
|
|
88
96
|
rescue_from Spree::Core::GatewayError, with: :handle_gateway_error
|
|
89
97
|
rescue_from ActionController::ParameterMissing, with: :handle_parameter_missing
|
|
90
98
|
rescue_from ActiveRecord::RecordInvalid, with: :handle_record_invalid
|
|
91
99
|
rescue_from ArgumentError, with: :handle_argument_error
|
|
92
100
|
rescue_from ActionDispatch::Http::Parameters::ParseError, with: :handle_parse_error
|
|
93
|
-
rescue_from StateMachines::InvalidTransition, with: :handle_invalid_transition
|
|
94
101
|
end
|
|
95
102
|
|
|
96
103
|
protected
|
|
@@ -122,12 +129,33 @@ module Spree
|
|
|
122
129
|
)
|
|
123
130
|
end
|
|
124
131
|
|
|
132
|
+
# Maps symbolic line-item rejections onto the API error-code vocabulary.
|
|
133
|
+
#
|
|
134
|
+
# @param errors [ActiveModel::Errors, Object] structured rejection from a workflow
|
|
135
|
+
# @param default [String] fallback when no recognized symbol is present
|
|
136
|
+
# @return [String] a value from {ERROR_CODES}
|
|
137
|
+
def infer_line_item_error_code(errors, default:)
|
|
138
|
+
return default unless errors.is_a?(ActiveModel::Errors)
|
|
139
|
+
|
|
140
|
+
base_symbols = (errors.details[:base] || []).pluck(:error)
|
|
141
|
+
return ERROR_CODES[:price_override_not_allowed] if base_symbols.include?(:price_override_not_allowed)
|
|
142
|
+
return ERROR_CODES[:invalid_price] if base_symbols.include?(:invalid_price)
|
|
143
|
+
return ERROR_CODES[:invalid_quantity] if base_symbols.include?(:quantity_rule_violated)
|
|
144
|
+
|
|
145
|
+
default
|
|
146
|
+
end
|
|
147
|
+
|
|
125
148
|
# Convenience method for service result errors
|
|
126
149
|
def render_service_error(error, code: ERROR_CODES[:processing_error], status: :unprocessable_content)
|
|
127
150
|
if error.is_a?(ActiveModel::Errors)
|
|
128
151
|
render_validation_error(error, code: code)
|
|
129
152
|
elsif error.is_a?(String)
|
|
130
153
|
render_error(code: code, message: error, status: status)
|
|
154
|
+
elsif error.is_a?(Symbol)
|
|
155
|
+
# Workflows reject with a symbol naming the reason. Translate it,
|
|
156
|
+
# falling back to the symbol so a missing key is visible rather
|
|
157
|
+
# than silently blank.
|
|
158
|
+
render_error(code: code, message: Spree.t(error, default: error.to_s.humanize), status: status)
|
|
131
159
|
else
|
|
132
160
|
render_error(code: code, message: error.to_s, status: status)
|
|
133
161
|
end
|
|
@@ -161,10 +189,33 @@ module Spree
|
|
|
161
189
|
render_error(
|
|
162
190
|
code: ERROR_CODES[:access_denied],
|
|
163
191
|
message: exception.message,
|
|
164
|
-
status: :forbidden
|
|
192
|
+
status: :forbidden,
|
|
193
|
+
details: access_denied_details
|
|
165
194
|
)
|
|
166
195
|
end
|
|
167
196
|
|
|
197
|
+
# Names the catalog permission the failed request needed, derived from
|
|
198
|
+
# the controller's `scoped_resource` declaration — the JWT twin of the
|
|
199
|
+
# scope check's `required_scope` (docs/plans/6.0-admin-rbac.md). Only
|
|
200
|
+
# reported when the caller genuinely lacks the key: a denial the caller
|
|
201
|
+
# is capability-authorized for is a record- or store-level condition,
|
|
202
|
+
# and naming a permission they already hold would mislead.
|
|
203
|
+
def access_denied_details
|
|
204
|
+
return unless respond_to?(:scoped_resource_name, true)
|
|
205
|
+
|
|
206
|
+
resource = scoped_resource_name
|
|
207
|
+
return unless resource
|
|
208
|
+
|
|
209
|
+
required = "#{action_kind}_#{resource}"
|
|
210
|
+
return unless Spree.permissions.key?(required)
|
|
211
|
+
|
|
212
|
+
ability = current_ability
|
|
213
|
+
return unless ability.respond_to?(:permission_keys)
|
|
214
|
+
return if ability.permission_keys.include?(required)
|
|
215
|
+
|
|
216
|
+
{ required_permission: required }
|
|
217
|
+
end
|
|
218
|
+
|
|
168
219
|
def handle_gateway_error(exception)
|
|
169
220
|
Rails.error.report(exception, context: error_context, source: 'spree.api.v3')
|
|
170
221
|
render_error(
|
|
@@ -207,15 +258,6 @@ module Spree
|
|
|
207
258
|
)
|
|
208
259
|
end
|
|
209
260
|
|
|
210
|
-
def handle_invalid_transition(exception)
|
|
211
|
-
Rails.error.report(exception, context: error_context, source: 'spree.api.v3')
|
|
212
|
-
render_error(
|
|
213
|
-
code: ERROR_CODES[:cart_cannot_transition],
|
|
214
|
-
message: exception.message,
|
|
215
|
-
status: :unprocessable_content
|
|
216
|
-
)
|
|
217
|
-
end
|
|
218
|
-
|
|
219
261
|
|
|
220
262
|
private
|
|
221
263
|
|
|
@@ -67,10 +67,16 @@ module Spree
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
def idempotency_cache_key(key)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
70
|
+
credential = request.headers['X-Spree-Api-Key'].presence ||
|
|
71
|
+
spree_current_user&.id ||
|
|
72
|
+
request.remote_ip
|
|
73
|
+
# The resolved store partitions the namespace: a staff JWT spans
|
|
74
|
+
# stores, and replaying one store's cached response for a request
|
|
75
|
+
# aimed at another would cross store boundaries. The resolved
|
|
76
|
+
# store — not the raw header — so a header naming the default store
|
|
77
|
+
# and no header at all land in the same partition, as they resolve
|
|
78
|
+
# to the same store.
|
|
79
|
+
"spree:idempotency:#{Digest::SHA256.hexdigest("#{credential}\0#{current_store&.id}\0#{key}")}"
|
|
74
80
|
end
|
|
75
81
|
|
|
76
82
|
def request_fingerprint
|