spree_api 6.0.0.rc7 → 6.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/concerns/spree/api/v3/admin/maintenance_tasks_switch.rb +35 -0
- data/app/controllers/spree/api/v3/admin/invitation_acceptances_controller.rb +8 -4
- data/app/controllers/spree/api/v3/admin/maintenance_task_runs/cancellations_controller.rb +42 -0
- data/app/controllers/spree/api/v3/admin/maintenance_task_runs_controller.rb +92 -0
- data/app/controllers/spree/api/v3/admin/sellers_controller.rb +1 -1
- data/app/controllers/spree/api/v3/admin/store_controller.rb +23 -7
- data/app/controllers/spree/api/v3/admin/upgrade_steps_controller.rb +114 -0
- data/app/controllers/spree/api/v3/seller/invitation_acceptances_controller.rb +15 -5
- data/app/controllers/spree/api/v3/store/customers_controller.rb +1 -0
- data/app/controllers/spree/api/v3/store/store_controller.rb +25 -0
- data/app/serializers/spree/api/v3/address_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/address_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/category_serializer.rb +1 -3
- data/app/serializers/spree/api/v3/admin/claim_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/collection_serializer.rb +1 -4
- data/app/serializers/spree/api/v3/admin/company_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/credit_card_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/customer_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/delivery_method_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/fulfillment_serializer.rb +1 -0
- data/app/serializers/spree/api/v3/admin/gift_card_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/invitation_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/admin/line_item_serializer.rb +1 -0
- data/app/serializers/spree/api/v3/admin/maintenance_task_run_serializer.rb +72 -0
- data/app/serializers/spree/api/v3/admin/media_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/newsletter_subscriber_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/option_type_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/option_value_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/order_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/payment_method_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/payment_serializer.rb +3 -1
- data/app/serializers/spree/api/v3/admin/payment_source_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/product_serializer.rb +1 -3
- data/app/serializers/spree/api/v3/admin/return_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/seller_payout_serializer.rb +2 -1
- data/app/serializers/spree/api/v3/admin/seller_serializer.rb +4 -0
- data/app/serializers/spree/api/v3/admin/store_credit_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/admin/store_serializer.rb +3 -4
- data/app/serializers/spree/api/v3/admin/variant_serializer.rb +1 -3
- data/app/serializers/spree/api/v3/base_serializer.rb +28 -0
- data/app/serializers/spree/api/v3/category_serializer.rb +1 -4
- data/app/serializers/spree/api/v3/claim_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/collection_serializer.rb +1 -4
- data/app/serializers/spree/api/v3/company_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/credit_card_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/customer_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/delivery_method_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/fulfillment_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/gift_card_serializer.rb +1 -0
- data/app/serializers/spree/api/v3/line_item_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/media_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/newsletter_subscriber_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/option_type_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/option_value_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/order_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/payment_method_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/payment_serializer.rb +3 -1
- data/app/serializers/spree/api/v3/payment_source_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/product_serializer.rb +1 -4
- data/app/serializers/spree/api/v3/return_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/seller/invitation_serializer.rb +22 -1
- data/app/serializers/spree/api/v3/seller/profile_serializer.rb +1 -1
- data/app/serializers/spree/api/v3/seller_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/store_credit_serializer.rb +2 -0
- data/app/serializers/spree/api/v3/store_serializer.rb +16 -0
- data/app/serializers/spree/api/v3/variant_serializer.rb +1 -4
- data/app/services/spree/api/v3/request_schema.rb +15 -7
- data/config/routes.rb +14 -2
- data/lib/spree/api/dependencies.rb +2 -1
- data/lib/spree/api/enum_types.rb +2 -1
- data/lib/typelizer/open_enums.rb +21 -2
- metadata +13 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 88513caab1df4ae8256a450d38b98601d724763697f75cd6bbe92f20986fac7c
|
|
4
|
+
data.tar.gz: 87742481e6e84a33e11080d3c830ca960eb692a243fb6d1b6c926a43f7d951e0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 10e0aa59755c08b5d83f12080be796d2a4a8cd3cbb70e77a47d369853385dc78f3583296534b0482dc76816396a285f6b476c12cc0c1863eac45defedc646f71
|
|
7
|
+
data.tar.gz: fd76b27f733d1acf21c0deb06341cf2cde81de862dc1d1eaaefcb91f2ffb216bafd3c2f24d4f7a09f1a6dbe39d31f66b9e37584561c26e64563099c67a3592bb
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Refuses every maintenance task endpoint when the installation has
|
|
6
|
+
# turned them off (Spree::Config.maintenance_tasks_dashboard_enabled).
|
|
7
|
+
# The ability already withholds them from signed-in staff; this also
|
|
8
|
+
# covers secret API keys, which are authorized by scope instead.
|
|
9
|
+
#
|
|
10
|
+
# Runs ahead of every other callback, so the caller learns the feature
|
|
11
|
+
# is off rather than a lookup or permission failure that no grant could
|
|
12
|
+
# fix — whether the caller is signed in does not change that answer.
|
|
13
|
+
module MaintenanceTasksSwitch
|
|
14
|
+
extend ActiveSupport::Concern
|
|
15
|
+
|
|
16
|
+
included do
|
|
17
|
+
before_action :ensure_maintenance_tasks_enabled, prepend: true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def ensure_maintenance_tasks_enabled
|
|
23
|
+
return if Spree::Config.maintenance_tasks_dashboard_enabled
|
|
24
|
+
|
|
25
|
+
render_error(
|
|
26
|
+
code: ErrorHandler::ERROR_CODES[:access_denied],
|
|
27
|
+
message: I18n.t('spree.maintenance_tasks_turned_off'),
|
|
28
|
+
status: :forbidden
|
|
29
|
+
)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -12,7 +12,7 @@ module Spree
|
|
|
12
12
|
|
|
13
13
|
request_params 'InvitationAcceptParams', action: :accept do |body|
|
|
14
14
|
body.attribute :password, :string,
|
|
15
|
-
description: '
|
|
15
|
+
description: 'Creates the account when the invitee has none yet. An existing account confirms it is theirs with it, unless the request is already signed in as that account.'
|
|
16
16
|
body.attribute :password_confirmation, :string
|
|
17
17
|
body.attribute :first_name, :string
|
|
18
18
|
body.attribute :last_name, :string
|
|
@@ -74,10 +74,14 @@ module Spree
|
|
|
74
74
|
# implicit: we look the user up by `invitation.email`, never by a
|
|
75
75
|
# client-supplied email. The token is the credential.
|
|
76
76
|
def resolve_or_create_invitee(invitation)
|
|
77
|
-
existing =
|
|
78
|
-
return
|
|
77
|
+
existing = invitation.invitee_account
|
|
78
|
+
return create_new_invitee(invitation) unless existing
|
|
79
79
|
|
|
80
|
-
|
|
80
|
+
# Someone already signed in as the invitee has proven who they are.
|
|
81
|
+
authenticate_user
|
|
82
|
+
return existing if current_user == existing
|
|
83
|
+
|
|
84
|
+
authenticate_existing(existing)
|
|
81
85
|
end
|
|
82
86
|
|
|
83
87
|
def authenticate_existing(user)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
module MaintenanceTaskRuns
|
|
6
|
+
# POST /api/v3/admin/maintenance_task_runs/:maintenance_task_run_id/cancellation
|
|
7
|
+
#
|
|
8
|
+
# Stops a run for good. Work already committed stays committed; the
|
|
9
|
+
# runner records the outcome (docs/plans/6.0-maintenance-tasks.md).
|
|
10
|
+
class CancellationsController < Admin::BaseController
|
|
11
|
+
include MaintenanceTasksSwitch
|
|
12
|
+
|
|
13
|
+
scoped_resource :maintenance_tasks
|
|
14
|
+
|
|
15
|
+
def create
|
|
16
|
+
run = Spree::MaintenanceTaskRun.find_by_prefix_id!(params[:maintenance_task_run_id])
|
|
17
|
+
authorize! :update, run
|
|
18
|
+
|
|
19
|
+
result = Spree::MaintenanceTasks::Cancel.call(run: run)
|
|
20
|
+
|
|
21
|
+
if result.success?
|
|
22
|
+
render json: serialize_resource(result.value)
|
|
23
|
+
else
|
|
24
|
+
render_validation_error(result.error)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
protected
|
|
29
|
+
|
|
30
|
+
def serializer_class
|
|
31
|
+
Spree.api.admin_maintenance_task_run_serializer
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def serializer_params
|
|
35
|
+
super.merge(show_backtrace: true)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# Firing a maintenance task and steering the run it creates
|
|
6
|
+
# (docs/plans/6.0-maintenance-tasks.md).
|
|
7
|
+
#
|
|
8
|
+
# No destroy: a run is the audit record of work that touched merchant
|
|
9
|
+
# data, so it is never removed through the API. Stopping one is a
|
|
10
|
+
# cancellation (MaintenanceTaskRuns::CancellationsController).
|
|
11
|
+
class MaintenanceTaskRunsController < ResourceController
|
|
12
|
+
include ActiveStorage::SetCurrent
|
|
13
|
+
|
|
14
|
+
include MaintenanceTasksSwitch
|
|
15
|
+
|
|
16
|
+
scoped_resource :maintenance_tasks
|
|
17
|
+
|
|
18
|
+
request_params :maintenance_task_run do |body|
|
|
19
|
+
body.attribute :task_name, :string,
|
|
20
|
+
required: true, on: :create,
|
|
21
|
+
example: 'capture_methods',
|
|
22
|
+
description: 'The task to run, as `task_name` from `GET /upgrade_steps`.'
|
|
23
|
+
body.attribute :arguments, :hash,
|
|
24
|
+
description: "Values for the task's declared parameters, keyed by parameter name. " \
|
|
25
|
+
'A key the task does not declare is rejected.'
|
|
26
|
+
body.attribute :dry_run, :boolean,
|
|
27
|
+
description: 'Report what would change without writing. Ignored by tasks that do not support a dry run, which run for real.'
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# POST /api/v3/admin/maintenance_task_runs
|
|
31
|
+
def create
|
|
32
|
+
authorize! :create, Spree::MaintenanceTaskRun
|
|
33
|
+
|
|
34
|
+
# Not normalized: a task argument holding a prefixed id is the
|
|
35
|
+
# task's to resolve, and decoding it here would hand it a raw key.
|
|
36
|
+
body = params.permit(*declared_permitted_attributes)
|
|
37
|
+
|
|
38
|
+
result = Spree::MaintenanceTasks::Start.call(
|
|
39
|
+
api_type: body[:task_name].to_s,
|
|
40
|
+
arguments: body[:arguments]&.to_h || {},
|
|
41
|
+
dry_run: ActiveModel::Type::Boolean.new.cast(body[:dry_run]) || false,
|
|
42
|
+
admin_user: try_spree_current_user,
|
|
43
|
+
api_key: current_api_key,
|
|
44
|
+
initiated_via: initiated_via
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
if result.success?
|
|
48
|
+
render json: serialize_resource(result.value), status: :created
|
|
49
|
+
else
|
|
50
|
+
render_validation_error(result.error)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
protected
|
|
55
|
+
|
|
56
|
+
def model_class
|
|
57
|
+
Spree::MaintenanceTaskRun
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def serializer_class
|
|
61
|
+
Spree.api.admin_maintenance_task_run_serializer
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Runs are installation-wide: an upgrade step converts every store's
|
|
65
|
+
# data, so a run belongs to no store.
|
|
66
|
+
def scope
|
|
67
|
+
model_class.all
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def collection_includes
|
|
71
|
+
[{ admin_user: [{ spree_roles: :resource }, { avatar_attachment: :blob }] }]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# A backtrace names internal paths and class names, so it rides with
|
|
75
|
+
# the permission to act on runs rather than the one to read them.
|
|
76
|
+
def serializer_params
|
|
77
|
+
super.merge(show_backtrace: holds_permission?('write_maintenance_tasks'))
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# A secret key belongs to an integration rather than a person, so the
|
|
83
|
+
# two are recorded distinctly — "who ran this" has a different answer
|
|
84
|
+
# for each.
|
|
85
|
+
def initiated_via
|
|
86
|
+
try_spree_current_user ? 'dashboard' : 'api'
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
@@ -195,7 +195,7 @@ module Spree
|
|
|
195
195
|
# every seller on the page, so it loads once. Applied to the scope
|
|
196
196
|
# rather than the collection so a single-seller read gets it too.
|
|
197
197
|
def scope_includes
|
|
198
|
-
[:billing_address, :requirement_submissions, { stock_locations: [] },
|
|
198
|
+
[:billing_address, :requirement_submissions, :external_references, { stock_locations: [] },
|
|
199
199
|
{ store: :seller_requirements, logo_attachment: :blob, cover_photo_attachment: :blob }]
|
|
200
200
|
end
|
|
201
201
|
|
|
@@ -7,8 +7,15 @@ module Spree
|
|
|
7
7
|
|
|
8
8
|
request_params :store do |body|
|
|
9
9
|
body.attribute :name, :string, example: 'My Store'
|
|
10
|
-
body.attribute :
|
|
11
|
-
|
|
10
|
+
body.attribute :seo_title, :string,
|
|
11
|
+
nullable: true,
|
|
12
|
+
description: "The storefront's default page title, in the store's default language. Translate it through the translations endpoints."
|
|
13
|
+
body.attribute :meta_description, :string,
|
|
14
|
+
nullable: true,
|
|
15
|
+
description: "The storefront's default meta description, in the store's default language."
|
|
16
|
+
body.attribute :admin_locale, :locale, nullable: true, example: 'en',
|
|
17
|
+
description: 'The language the dashboard opens in for every staff member; null lets each use their own.'
|
|
18
|
+
body.attribute :timezone, :time_zone, example: 'Europe/Berlin'
|
|
12
19
|
body.attribute :weight_unit, :weight_unit
|
|
13
20
|
body.attribute :unit_system, :string, choices: Spree::Store::UNIT_SYSTEMS
|
|
14
21
|
body.attribute :storefront_access, :string,
|
|
@@ -143,17 +150,19 @@ module Spree
|
|
|
143
150
|
# GET /api/v3/admin/store
|
|
144
151
|
def show
|
|
145
152
|
authorize! :show, current_store
|
|
146
|
-
render json: serialize_store
|
|
153
|
+
render json: in_default_locale { serialize_store }
|
|
147
154
|
end
|
|
148
155
|
|
|
149
156
|
# PATCH /api/v3/admin/store
|
|
150
157
|
def update
|
|
151
158
|
authorize! :update, current_store
|
|
152
159
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
160
|
+
in_default_locale do
|
|
161
|
+
if current_store.update(permitted_params)
|
|
162
|
+
render json: serialize_store
|
|
163
|
+
else
|
|
164
|
+
render_validation_error(current_store.errors)
|
|
165
|
+
end
|
|
157
166
|
end
|
|
158
167
|
end
|
|
159
168
|
|
|
@@ -177,6 +186,13 @@ module Spree
|
|
|
177
186
|
|
|
178
187
|
private
|
|
179
188
|
|
|
189
|
+
# Settings hold the store's default-language values, whatever locale
|
|
190
|
+
# the request resolved to. Other languages are written through the
|
|
191
|
+
# translations endpoints.
|
|
192
|
+
def in_default_locale(&)
|
|
193
|
+
Mobility.with_locale(current_store.default_locale, &)
|
|
194
|
+
end
|
|
195
|
+
|
|
180
196
|
def describe(provider_classes)
|
|
181
197
|
provider_classes.map do |provider_class|
|
|
182
198
|
{
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Admin
|
|
5
|
+
# The upgrade manifest as an ordered checklist, so the dashboard can
|
|
6
|
+
# show what a release still needs and how far an operator has got
|
|
7
|
+
# (docs/plans/6.0-maintenance-tasks.md).
|
|
8
|
+
#
|
|
9
|
+
# Read-only: running a step is starting the maintenance task it names,
|
|
10
|
+
# which is what the runs endpoint already does. This exists to supply
|
|
11
|
+
# the order and the operator notes, neither of which a task knows about
|
|
12
|
+
# itself — a step's position in the manifest is a property of the
|
|
13
|
+
# upgrade, not of the class.
|
|
14
|
+
class UpgradeStepsController < BaseController
|
|
15
|
+
include MaintenanceTasksSwitch
|
|
16
|
+
|
|
17
|
+
scoped_resource :maintenance_tasks
|
|
18
|
+
|
|
19
|
+
# GET /api/v3/admin/upgrade_steps
|
|
20
|
+
#
|
|
21
|
+
# Every step of every manifest this installation has reached, from
|
|
22
|
+
# the first release whose runs are recorded, each marked pending or
|
|
23
|
+
# superseded. Superseded steps are the releases it has already been
|
|
24
|
+
# through: shown as history rather than hidden, but never runnable,
|
|
25
|
+
# since re-running a completed conversion is how an upgrade does
|
|
26
|
+
# damage. Earlier releases are left to the command line.
|
|
27
|
+
def index
|
|
28
|
+
authorize! :read, :maintenance_task
|
|
29
|
+
|
|
30
|
+
# A store installed fresh at this release has no upgrade to show —
|
|
31
|
+
# not the outstanding steps, and not the history of releases it was
|
|
32
|
+
# never on.
|
|
33
|
+
return render json: { data: [], meta: meta } unless Spree::Upgrade.relevant?
|
|
34
|
+
|
|
35
|
+
render json: {
|
|
36
|
+
data: steps.map { |step| present(step) },
|
|
37
|
+
meta: meta
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def meta
|
|
44
|
+
{ completed_version: Spree::Upgrade.completed_boundary }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Superseded first: they are the earlier releases, so listing them
|
|
48
|
+
# above what is outstanding keeps the whole thing in release order.
|
|
49
|
+
def steps
|
|
50
|
+
@steps ||= (superseded_steps + Spree::Upgrade.pending_steps).select { |step| Spree::Upgrade.tracked?(step) }
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def superseded_steps
|
|
54
|
+
@superseded_steps ||= Spree::Upgrade.superseded_steps
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def superseded_ids
|
|
58
|
+
@superseded_ids ||= superseded_steps.map { |step| step['id'] }.to_set
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def present(step)
|
|
62
|
+
task_name = Spree::Upgrade.task_class_name(step)
|
|
63
|
+
run = latest_runs[run_key(step, task_name)]
|
|
64
|
+
|
|
65
|
+
{
|
|
66
|
+
# A boundary this installation has already crossed. The dashboard
|
|
67
|
+
# shows these as done and refuses to run them.
|
|
68
|
+
superseded: superseded_ids.include?(step['id']),
|
|
69
|
+
id: step['id'],
|
|
70
|
+
name: step['name'],
|
|
71
|
+
notes: step['notes'],
|
|
72
|
+
from: step['from'],
|
|
73
|
+
to: step['to'],
|
|
74
|
+
docs: step['docs'],
|
|
75
|
+
task_name: Spree::MaintenanceTask.api_type_for(task_name),
|
|
76
|
+
# A rake-backed step runs inside the shared runner, so the id it
|
|
77
|
+
# was invoked with is what distinguishes one run from another.
|
|
78
|
+
arguments: Spree::Upgrade.task_arguments(step),
|
|
79
|
+
last_run: run && Spree.api.admin_maintenance_task_run_serializer.new(
|
|
80
|
+
run, params: { show_backtrace: holds_permission?('write_maintenance_tasks') }
|
|
81
|
+
).to_h
|
|
82
|
+
}
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# The most recent run per step. Reduced in Ruby rather than grouped
|
|
86
|
+
# in SQL: rake-backed runs are told apart by the step id inside their
|
|
87
|
+
# `arguments` JSON, and grouping on a JSON column is not portable
|
|
88
|
+
# across the adapters Spree supports. Only the three columns that
|
|
89
|
+
# pick the latest run are read for the whole history; the runs kept
|
|
90
|
+
# are then loaded in full.
|
|
91
|
+
def latest_runs
|
|
92
|
+
@latest_runs ||= begin
|
|
93
|
+
latest_ids = Spree::MaintenanceTaskRun.where(task_name: manifest_task_names).order(:id).
|
|
94
|
+
pluck(:id, :task_name, :arguments).
|
|
95
|
+
each_with_object({}) do |(id, task_name, arguments), result|
|
|
96
|
+
result[[task_name, arguments&.dig('step_id')]] = id
|
|
97
|
+
end
|
|
98
|
+
runs = Spree::MaintenanceTaskRun.includes(:admin_user).where(id: latest_ids.values).index_by(&:id)
|
|
99
|
+
latest_ids.transform_values { |id| runs[id] }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def manifest_task_names
|
|
104
|
+
steps.map { |step| Spree::Upgrade.task_class_name(step) }.uniq
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def run_key(step, task_name)
|
|
108
|
+
[task_name, step['task_class'] ? nil : step['id']]
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -24,7 +24,7 @@ module Spree
|
|
|
24
24
|
|
|
25
25
|
request_params 'InvitationAcceptParams', action: :accept do |body|
|
|
26
26
|
body.attribute :password, :string,
|
|
27
|
-
description: 'Sets the password of a new account, or confirms the password of an existing one.'
|
|
27
|
+
description: 'Sets the password of a new account, or confirms the password of an existing one, unless the request is already signed in as that account.'
|
|
28
28
|
body.attribute :password_confirmation, :string
|
|
29
29
|
body.attribute :first_name, :string, description: 'Used only when the invitation creates a new account.'
|
|
30
30
|
body.attribute :last_name, :string, description: 'Used only when the invitation creates a new account.'
|
|
@@ -35,7 +35,7 @@ module Spree
|
|
|
35
35
|
return unless load_invitation
|
|
36
36
|
|
|
37
37
|
render json: Spree.api.seller_invitation_serializer.new(
|
|
38
|
-
@invitation, params: { store: @invitation.store }
|
|
38
|
+
@invitation, params: { store: @invitation.store, acceptance: true }
|
|
39
39
|
).serializable_hash
|
|
40
40
|
end
|
|
41
41
|
|
|
@@ -97,10 +97,14 @@ module Spree
|
|
|
97
97
|
# implicit: we look the user up by `invitation.email`, never by a
|
|
98
98
|
# client-supplied email. The token is the credential.
|
|
99
99
|
def resolve_or_create_invitee(invitation)
|
|
100
|
-
existing =
|
|
101
|
-
return
|
|
100
|
+
existing = invitation.invitee_account
|
|
101
|
+
return create_new_invitee(invitation) unless existing
|
|
102
102
|
|
|
103
|
-
|
|
103
|
+
# Someone already signed in as the invitee has proven who they are.
|
|
104
|
+
authenticate_user
|
|
105
|
+
return existing if current_user == existing
|
|
106
|
+
|
|
107
|
+
authenticate_existing(existing)
|
|
104
108
|
end
|
|
105
109
|
|
|
106
110
|
def authenticate_existing(user)
|
|
@@ -151,6 +155,12 @@ module Spree
|
|
|
151
155
|
user.sellers.map { |seller| { id: seller.prefixed_id, name: seller.name, status: seller.status } }
|
|
152
156
|
end
|
|
153
157
|
|
|
158
|
+
# The plain v3 base expects a storefront token; the session this
|
|
159
|
+
# page may carry is a seller panel one.
|
|
160
|
+
def expected_audience
|
|
161
|
+
Spree::Api::V3::JwtAuthentication::JWT_AUDIENCE_SELLER
|
|
162
|
+
end
|
|
163
|
+
|
|
154
164
|
def request_env_for_token
|
|
155
165
|
{ ip_address: request.remote_ip, user_agent: request.user_agent&.truncate(255) }
|
|
156
166
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V3
|
|
4
|
+
module Store
|
|
5
|
+
# Exposes the store the request resolved to, so a storefront can render
|
|
6
|
+
# its name and default SEO metadata in the requested locale.
|
|
7
|
+
class StoreController < Store::BaseController
|
|
8
|
+
# A gated storefront still needs a page title on its sign-in wall.
|
|
9
|
+
allow_guest_storefront_access!
|
|
10
|
+
|
|
11
|
+
# GET /api/v3/store/store
|
|
12
|
+
def show
|
|
13
|
+
render json: serialize_resource(current_store)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
protected
|
|
17
|
+
|
|
18
|
+
def serializer_class
|
|
19
|
+
Spree.api.store_serializer
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -35,6 +35,8 @@ module Spree
|
|
|
35
35
|
# The address book the entry belongs to. Null for an address in no
|
|
36
36
|
# book: one a guest typed in, or the copy a placed order keeps.
|
|
37
37
|
one :owner, resource: proc { Spree.api.address_owner_serializer }
|
|
38
|
+
|
|
39
|
+
expandable_custom_fields
|
|
38
40
|
end
|
|
39
41
|
end
|
|
40
42
|
end
|
|
@@ -28,9 +28,7 @@ module Spree
|
|
|
28
28
|
resource: proc { Spree.api.admin_category_serializer },
|
|
29
29
|
if: proc { expand?('ancestors') }
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
resource: proc { Spree.api.admin_custom_field_serializer },
|
|
33
|
-
if: proc { expand?('custom_fields') }
|
|
31
|
+
expandable_custom_fields admin: true
|
|
34
32
|
end
|
|
35
33
|
end
|
|
36
34
|
end
|
|
@@ -26,6 +26,8 @@ module Spree
|
|
|
26
26
|
one :reason, resource: proc { Spree.api.admin_claim_reason_serializer }, if: proc { expand?('reason') }
|
|
27
27
|
one :order, resource: proc { Spree.api.admin_order_serializer }, if: proc { expand?('order') }
|
|
28
28
|
many :refunds, resource: proc { Spree.api.admin_refund_serializer }, if: proc { expand?('refunds') }
|
|
29
|
+
|
|
30
|
+
expandable_custom_fields admin: true
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -18,10 +18,7 @@ module Spree
|
|
|
18
18
|
resource: proc { Spree.api.admin_collection_rule_serializer },
|
|
19
19
|
if: proc { expand?('rules') }
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
many :custom_fields,
|
|
23
|
-
resource: proc { Spree.api.admin_custom_field_serializer },
|
|
24
|
-
if: proc { expand?('custom_fields') }
|
|
21
|
+
expandable_custom_fields admin: true
|
|
25
22
|
end
|
|
26
23
|
end
|
|
27
24
|
end
|
|
@@ -37,7 +37,7 @@ module Spree
|
|
|
37
37
|
# Looked up by email so an admin who's already on another store sees
|
|
38
38
|
# the password prompt, not a fresh account form.
|
|
39
39
|
attribute :invitee_exists do |invitation|
|
|
40
|
-
|
|
40
|
+
invitation.invitee_account.present?
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
# Minimal store identity for the unauthenticated acceptance page's
|