spree_cm_commissioner 2.9.8 → 2.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.env.example +0 -5
- data/Gemfile.lock +1 -1
- data/app/controllers/concerns/spree_cm_commissioner/content_cachable.rb +1 -0
- data/app/controllers/spree/admin/users_controller_decorator.rb +36 -0
- data/app/controllers/spree/api/v2/base_controller_decorator.rb +41 -0
- data/app/controllers/spree/api/v2/storefront/payment_methods_controller.rb +40 -0
- data/app/controllers/spree/api/v2/storefront/telegram_oauth_tokens_controller.rb +8 -22
- data/app/controllers/spree/api/v2/tenant/payment_methods_controller.rb +54 -0
- data/app/controllers/spree/api/v2/tenant/telegram_oauth_tokens_controller.rb +48 -0
- data/app/finders/spree_cm_commissioner/payment_methods/find.rb +59 -0
- data/app/interactors/spree_cm_commissioner/base_interactor.rb +10 -0
- data/app/interactors/spree_cm_commissioner/user_fb_token_authenticator.rb +1 -1
- data/app/interactors/spree_cm_commissioner/user_id_token_authenticator.rb +1 -1
- data/app/interactors/spree_cm_commissioner/user_password_authenticator.rb +1 -1
- data/app/interactors/spree_cm_commissioner/user_telegram_oauth_authenticator.rb +4 -4
- data/app/interactors/spree_cm_commissioner/user_telegram_web_app_authenticator.rb +4 -0
- data/app/interactors/spree_cm_commissioner/user_vattanac_bank_web_app_authenticator.rb +4 -0
- data/app/interactors/spree_cm_commissioner/waiting_guests_caller.rb +94 -67
- data/app/interactors/spree_cm_commissioner/waiting_room_latest_system_metadata_puller.rb +20 -6
- data/app/interactors/spree_cm_commissioner/waiting_room_session_creator.rb +83 -20
- data/app/jobs/spree_cm_commissioner/waiting_guests_caller_job.rb +0 -4
- data/app/models/spree_cm_commissioner/guest.rb +5 -3
- data/app/models/spree_cm_commissioner/user_decorator.rb +19 -1
- data/app/models/spree_cm_commissioner/waiting_room_session.rb +9 -2
- data/app/overrides/spree/admin/stores/_form/telegram_auth.html.erb.deface +1 -1
- data/app/overrides/spree/admin/users/edit/account_status.html.erb.deface +42 -0
- data/app/overrides/spree/admin/users/index/body.html.erb.deface +25 -0
- data/app/overrides/spree/admin/users/index/ransack.html.erb.deface +12 -0
- data/app/serializers/spree/v2/storefront/user_serializer_decorator.rb +2 -1
- data/app/serializers/spree/v2/tenant/user_serializer.rb +1 -1
- data/app/serializers/spree/v2/tenant/waiting_room_session_serializer.rb +1 -1
- data/app/serializers/spree_cm_commissioner/v2/storefront/waiting_room_session_serializer.rb +1 -1
- data/app/services/spree_cm_commissioner/api_caches/invalidate.rb +29 -14
- data/app/services/spree_cm_commissioner/draft_order/create.rb +14 -0
- data/app/services/spree_cm_commissioner/telegram/check_id_token.rb +33 -0
- data/app/services/spree_cm_commissioner/telegram/exchange_oauth_token.rb +81 -0
- data/app/services/spree_cm_commissioner/telegram/verify_oauth_id_token.rb +98 -0
- data/app/services/spree_cm_commissioner/ticket_transfers/initiate.rb +1 -1
- data/app/services/spree_cm_commissioner/transit_order/create.rb +15 -1
- data/app/services/spree_cm_commissioner/users/block.rb +29 -0
- data/app/services/spree_cm_commissioner/users/unblock.rb +18 -0
- data/app/services/spree_cm_commissioner/waiting_room/publish_lobby_path.rb +7 -11
- data/app/services/spree_cm_commissioner/waiting_room/stamp_queue_positions.rb +94 -95
- data/app/views/spree/admin/tenants/form/_telegram_auth.html.erb +1 -1
- data/config/locales/en.yml +16 -1
- data/config/locales/km.yml +1 -1
- data/config/routes.rb +8 -0
- data/db/migrate/20260723083947_add_max_expired_at_to_cm_waiting_room_sessions.rb +9 -0
- data/db/migrate/20260805000000_add_blocked_at_to_spree_users.rb +6 -0
- data/lib/spree_cm_commissioner/version.rb +1 -1
- metadata +15 -6
- data/app/interactors/spree_cm_commissioner/telegram_oauth_id_token_provider.rb +0 -99
- data/app/interactors/spree_cm_commissioner/telegram_oauth_token_exchanger.rb +0 -71
- data/app/interactors/spree_cm_commissioner/waiting_room_session_firebase_logger.rb +0 -30
- data/app/jobs/spree_cm_commissioner/waiting_room_session_firebase_logger_job.rb +0 -36
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d59a44e1e25ec19ab8c634622f91006ea28bec265ea877dad8565cffa54bad3
|
|
4
|
+
data.tar.gz: 43415e8984f459f0387e110707963f4685c92251f589a2301342f82783c4e714
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1fbfc67d4bc18eb071d854b643ef3bfbaf1312b75f5c241020d58b09855ee234a58064ce08a104ee856b48dec25ce8547ad9c442cbd2648c83ad350c04fec3e1
|
|
7
|
+
data.tar.gz: 53317e748ac053ed6b60ec7e9accdd915266aa6b3e547692865191868d6051693dcad05dee73bed5e196b027fc27436e72fba2c62e05b3b33f806a7558618cf9
|
data/.env.example
CHANGED
|
@@ -22,11 +22,6 @@ WAITING_ROOM_MIN_SESSIONS_COUNT=5
|
|
|
22
22
|
WAITING_ROOM_DISABLED=no
|
|
23
23
|
WAITING_ROOM_POSITION_STAMP_LIMIT=1000
|
|
24
24
|
WAITING_ROOM_FIRESTORE_BATCH_SIZE=500
|
|
25
|
-
WAITING_ROOM_MIN_WAIT_TO_ENTER_SECONDS=600 # Waiting Room step floor (10 min)
|
|
26
|
-
WAITING_ROOM_MIN_QUEUE_TO_ENTER_SECONDS=300 # Queue step floor (5 min)
|
|
27
|
-
WAITING_ROOM_MAX_WAIT_TO_DISPLAY_SECONDS=3600 # above this the ETA is hidden (1 h)
|
|
28
|
-
WAITING_ROOM_CALLER_INTERVAL_SECONDS=60 # how often the caller runs; match the waiting_guests_caller cron
|
|
29
|
-
WAITING_ROOM_MAX_ETA_BATCH_SIZE=50 # cap on batch size assumed when estimating the ETA
|
|
30
25
|
|
|
31
26
|
# Vattanac Bank
|
|
32
27
|
VATTANAC_AES_SECRET_KEY= ""
|
data/Gemfile.lock
CHANGED
|
@@ -26,8 +26,44 @@ module Spree
|
|
|
26
26
|
super
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
def block
|
|
30
|
+
return redirect_back_to_user(I18n.t('spree_user.cannot_block_yourself'), :error) if own_account?
|
|
31
|
+
return redirect_back_to_user(I18n.t('spree_user.cannot_block_super_admin'), :error) if @user.super_admin?
|
|
32
|
+
|
|
33
|
+
result = SpreeCmCommissioner::Users::Block.call(user: @user, reason: params[:blocked_reason])
|
|
34
|
+
|
|
35
|
+
if result.success?
|
|
36
|
+
redirect_back_to_user(I18n.t('spree_user.successfully_blocked'), :success)
|
|
37
|
+
else
|
|
38
|
+
redirect_back_to_user(result.error.to_s, :error)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def unblock
|
|
43
|
+
result = SpreeCmCommissioner::Users::Unblock.call(user: @user)
|
|
44
|
+
|
|
45
|
+
if result.success?
|
|
46
|
+
redirect_back_to_user(I18n.t('spree_user.successfully_unblocked'), :success)
|
|
47
|
+
else
|
|
48
|
+
redirect_back_to_user(result.error.to_s, :error)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
29
52
|
private
|
|
30
53
|
|
|
54
|
+
# An admin who blocks themselves would be locked out with no way back in through the UI.
|
|
55
|
+
def own_account?
|
|
56
|
+
@user.id == try_spree_current_user&.id
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Blocking is triggered from two places — the row action on the users list and the account
|
|
60
|
+
# status card on the edit page — so return to whichever one the admin came from instead of
|
|
61
|
+
# always landing them on the edit page.
|
|
62
|
+
def redirect_back_to_user(message, type)
|
|
63
|
+
flash[type] = message
|
|
64
|
+
redirect_back fallback_location: spree.edit_admin_user_path(@user)
|
|
65
|
+
end
|
|
66
|
+
|
|
31
67
|
# Role types the user form doesn't render (assigned in organizer dashboards), e.g. check-in groups and preview.
|
|
32
68
|
NON_FORM_ROLE_TYPES = %i[check_in preview].freeze
|
|
33
69
|
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
# Single enforcement point for blocked users on the API. Every authenticated v2 endpoint -
|
|
5
|
+
# storefront, tenant, organizer, platform - resolves its user through
|
|
6
|
+
# Spree::Api::V2::BaseController#spree_current_user, so guarding here covers them all,
|
|
7
|
+
# including the controllers that inherit BaseController directly rather than
|
|
8
|
+
# ResourceController.
|
|
9
|
+
#
|
|
10
|
+
# 403 rather than 401: the token is valid and the caller is authenticated, they are simply not
|
|
11
|
+
# allowed anymore. A 401 would tell clients to refresh the token, which would loop.
|
|
12
|
+
module BaseControllerDecorator
|
|
13
|
+
# Machine-readable, not translated, so clients can branch on it the same way they already
|
|
14
|
+
# branch on the authenticators' `account_temporarily_deleted`.
|
|
15
|
+
BLOCKED_ERROR = 'account_blocked'.freeze
|
|
16
|
+
|
|
17
|
+
def self.prepended(base)
|
|
18
|
+
base.before_action :reject_blocked_user
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def reject_blocked_user
|
|
24
|
+
return unless blocked_token_owner?
|
|
25
|
+
|
|
26
|
+
render_error_payload(BLOCKED_ERROR, 403)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Deliberately reads the owner off the token instead of calling spree_current_user: that
|
|
30
|
+
# helper runs doorkeeper_authorize!, which would start rejecting invalid tokens on public
|
|
31
|
+
# endpoints that today ignore them. No token (anonymous request) costs nothing.
|
|
32
|
+
def blocked_token_owner?
|
|
33
|
+
owner = doorkeeper_token&.resource_owner
|
|
34
|
+
owner.respond_to?(:blocked?) && owner.blocked?
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
Spree::Api::V2::BaseController.prepend(Spree::Api::V2::BaseControllerDecorator)
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Storefront
|
|
5
|
+
# Order & user independent catalog of the payment methods a vendor accepts.
|
|
6
|
+
# Takes vendor_id as a required query param. See
|
|
7
|
+
# Spree::Api::V2::Tenant::PaymentMethodsController for the caching caveat
|
|
8
|
+
# that comes with that, and for what this deliberately leaves out.
|
|
9
|
+
class PaymentMethodsController < Spree::Api::V2::ResourceController
|
|
10
|
+
# override
|
|
11
|
+
def index
|
|
12
|
+
render_serialized_payload do
|
|
13
|
+
collection_serializer.new(collection).serializable_hash
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# override
|
|
18
|
+
def collection
|
|
19
|
+
@collection ||= SpreeCmCommissioner::PaymentMethods::Find.new(
|
|
20
|
+
vendor: vendor,
|
|
21
|
+
store: current_store,
|
|
22
|
+
type: params[:type]
|
|
23
|
+
).execute
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# override
|
|
27
|
+
def collection_serializer
|
|
28
|
+
::Spree::V2::Storefront::PaymentMethodSerializer
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def vendor
|
|
34
|
+
@vendor ||= ::Spree::Vendor.active.find(params[:vendor_id])
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -11,13 +11,13 @@ module Spree
|
|
|
11
11
|
def create
|
|
12
12
|
return render_error_payload(credential_mismatch_message) if credential_mismatch_message
|
|
13
13
|
|
|
14
|
-
result = SpreeCmCommissioner::
|
|
14
|
+
result = SpreeCmCommissioner::Telegram::ExchangeOauthToken.call(
|
|
15
15
|
exchange_params.merge(client_secret: resolved_client_secret)
|
|
16
16
|
)
|
|
17
17
|
|
|
18
|
-
return render_error_payload(result.
|
|
18
|
+
return render_error_payload(result.error) unless result.success?
|
|
19
19
|
|
|
20
|
-
render json: result.body, status: result.status, content_type: 'application/json'
|
|
20
|
+
render json: result.value[:body], status: result.value[:status], content_type: 'application/json'
|
|
21
21
|
end
|
|
22
22
|
|
|
23
23
|
private
|
|
@@ -26,33 +26,19 @@ module Spree
|
|
|
26
26
|
params.permit(:client_id, :code, :redirect_uri, :code_verifier).to_h.symbolize_keys
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
# `tenant_id` scopes which tenant's bot this login belongs to; with none
|
|
30
|
-
# given, the default store's bot is used. Distinguished from
|
|
31
|
-
# telegram_oauth_client_secret_not_configured (raised by the exchanger
|
|
32
|
-
# when the owner has no secret set) so a caller can tell "wrong
|
|
33
|
-
# tenant/client_id" apart from "correct tenant, nothing configured yet".
|
|
34
29
|
def credential_mismatch_message
|
|
35
|
-
return
|
|
36
|
-
return
|
|
37
|
-
return 'telegram_oauth_client_id_mismatch' unless client_id_matches_owner?
|
|
30
|
+
return nil if current_store.preferred_telegram_oauth_client_id.blank?
|
|
31
|
+
return 'telegram_oauth_client_id_mismatch' unless client_id_matches_store?
|
|
38
32
|
|
|
39
33
|
nil
|
|
40
34
|
end
|
|
41
35
|
|
|
42
|
-
def
|
|
43
|
-
|
|
36
|
+
def client_id_matches_store?
|
|
37
|
+
current_store.preferred_telegram_oauth_client_id == exchange_params[:client_id]
|
|
44
38
|
end
|
|
45
39
|
|
|
46
40
|
def resolved_client_secret
|
|
47
|
-
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def credential_owner
|
|
51
|
-
@credential_owner ||= if params[:tenant_id].present?
|
|
52
|
-
SpreeCmCommissioner::Tenant.find_by(id: params[:tenant_id])
|
|
53
|
-
else
|
|
54
|
-
Spree::Store.default
|
|
55
|
-
end
|
|
41
|
+
current_store.preferred_telegram_oauth_client_secret.presence
|
|
56
42
|
end
|
|
57
43
|
end
|
|
58
44
|
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
# Order & user independent catalog of the payment methods a vendor accepts.
|
|
6
|
+
#
|
|
7
|
+
# vendor_id is a required query param. A vendor id is globally unique and
|
|
8
|
+
# belongs to exactly one tenant, so it is what identifies tenant, vendor and
|
|
9
|
+
# store here — the tenant itself comes from the Doorkeeper token, not the URL.
|
|
10
|
+
#
|
|
11
|
+
# IMPORTANT for caching (see SpreeCmCommissioner::ContentCachable): the CDN
|
|
12
|
+
# must include vendor_id in its cache key. If query strings are stripped,
|
|
13
|
+
# every vendor collapses into one cache entry and the wrong payment methods
|
|
14
|
+
# are served. Moving to /vendors/:vendor_id/payment_methods would remove that
|
|
15
|
+
# dependency — tracked as a follow-up.
|
|
16
|
+
#
|
|
17
|
+
# For the per-order truth (store credit, early adopter, payout filtering)
|
|
18
|
+
# use CartPaymentMethodGroupsController instead.
|
|
19
|
+
class PaymentMethodsController < BaseController
|
|
20
|
+
# override
|
|
21
|
+
def index
|
|
22
|
+
render_serialized_payload do
|
|
23
|
+
collection_serializer.new(collection).serializable_hash
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# override
|
|
28
|
+
def collection
|
|
29
|
+
@collection ||= SpreeCmCommissioner::PaymentMethods::Find.new(
|
|
30
|
+
vendor: vendor,
|
|
31
|
+
store: current_store,
|
|
32
|
+
type: params[:type]
|
|
33
|
+
).execute
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# override
|
|
37
|
+
def collection_serializer
|
|
38
|
+
Spree::V2::Tenant::PaymentMethodSerializer
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
# Scoped to the token's tenant, so a token from another tenant gets a 404
|
|
44
|
+
# rather than a cache hit on someone else's vendor.
|
|
45
|
+
def vendor
|
|
46
|
+
@vendor ||= MultiTenant.with(@tenant) do
|
|
47
|
+
::Spree::Vendor.active.find(params[:vendor_id])
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module Spree
|
|
2
|
+
module Api
|
|
3
|
+
module V2
|
|
4
|
+
module Tenant
|
|
5
|
+
# Identical PKCE code->id_token relay as Storefront::TelegramOauthTokensController,
|
|
6
|
+
# but scoped to the tenant behind the Doorkeeper app access token (see
|
|
7
|
+
# Tenant::BaseController#require_tenant), exposed under /api/v2/tenant so
|
|
8
|
+
# tenant-scoped clients can call it alongside /api/v2/tenant/token
|
|
9
|
+
class TelegramOauthTokensController < BaseController
|
|
10
|
+
def create
|
|
11
|
+
return render_error_payload(credential_mismatch_message) if credential_mismatch_message
|
|
12
|
+
|
|
13
|
+
result = SpreeCmCommissioner::Telegram::ExchangeOauthToken.call(
|
|
14
|
+
exchange_params.merge(client_secret: resolved_client_secret)
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
return render_error_payload(result.error) unless result.success?
|
|
18
|
+
|
|
19
|
+
render json: result.value[:body], status: result.value[:status], content_type: 'application/json'
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def exchange_params
|
|
25
|
+
params.permit(:client_id, :code, :redirect_uri, :code_verifier).to_h.symbolize_keys
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# @tenant is already resolved from the Doorkeeper app (see BaseController#require_tenant),
|
|
29
|
+
# so unlike the storefront endpoint there's no separate tenant_id param to validate.
|
|
30
|
+
def credential_mismatch_message
|
|
31
|
+
return nil if @tenant.preferred_telegram_oauth_client_id.blank?
|
|
32
|
+
return 'telegram_oauth_client_id_mismatch' unless client_id_matches_tenant?
|
|
33
|
+
|
|
34
|
+
nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def client_id_matches_tenant?
|
|
38
|
+
@tenant.preferred_telegram_oauth_client_id == exchange_params[:client_id]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def resolved_client_secret
|
|
42
|
+
@tenant.preferred_telegram_oauth_client_secret.presence
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
module SpreeCmCommissioner
|
|
2
|
+
module PaymentMethods
|
|
3
|
+
# Order & user independent lookup of the payment methods a vendor accepts.
|
|
4
|
+
#
|
|
5
|
+
# Mirrors the scope selection of Vpago::OrderDecorator#available_payment_methods,
|
|
6
|
+
# minus everything that depends on the order or the current user, so the result
|
|
7
|
+
# is safe to cache on the vendor id alone:
|
|
8
|
+
#
|
|
9
|
+
# - available_for_order? (only Spree::PaymentMethod::StoreCredit varies, on user balance)
|
|
10
|
+
# - available_on_frontend_for_early_adopter (user attribute)
|
|
11
|
+
# - support_payout? (order line items)
|
|
12
|
+
# - preferred_payment_method_id (user, affects sort only)
|
|
13
|
+
#
|
|
14
|
+
# Callers needing the per-order truth must keep using
|
|
15
|
+
# Spree::Api::V2::*::CartPaymentMethodGroupsController.
|
|
16
|
+
class Find
|
|
17
|
+
attr_reader :vendor, :store, :type
|
|
18
|
+
|
|
19
|
+
def initialize(vendor:, store: nil, type: nil)
|
|
20
|
+
@vendor = vendor
|
|
21
|
+
@store = store
|
|
22
|
+
@type = type
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def execute
|
|
26
|
+
return mini_app_scope if type.present?
|
|
27
|
+
|
|
28
|
+
scope.reject(&:mini_app?)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def scope
|
|
34
|
+
@scope ||= source.available_on_front_end.order(:position).to_a
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Vendors without their own payment methods fall back to the store's,
|
|
38
|
+
# same as Vpago::OrderDecorator#available_payment_methods.
|
|
39
|
+
def source
|
|
40
|
+
vendor_payment_methods.exists? ? vendor_payment_methods : store_payment_methods
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def vendor_payment_methods
|
|
44
|
+
@vendor_payment_methods ||= vendor&.payment_methods || Spree::PaymentMethod.none
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def store_payment_methods
|
|
48
|
+
(store || Spree::Store.default).payment_methods
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def mini_app_scope
|
|
52
|
+
mapped_type = SpreeCmCommissioner::PaymentMethodTypeMapper.call(type)
|
|
53
|
+
return [] if mapped_type.blank?
|
|
54
|
+
|
|
55
|
+
scope.select { |payment_method| payment_method.mini_app? && payment_method.type == mapped_type }
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
module SpreeCmCommissioner
|
|
2
2
|
class BaseInteractor
|
|
3
3
|
include Interactor
|
|
4
|
+
|
|
5
|
+
private
|
|
6
|
+
|
|
7
|
+
# Shared tail guard for the authenticators: an account can be resolved and hold a valid
|
|
8
|
+
# credential and still not be allowed to authenticate. Both messages are error_description values
|
|
9
|
+
# the mobile/web clients branch on, so they stay raw strings rather than translations.
|
|
10
|
+
def reject_unauthenticatable_user!(user)
|
|
11
|
+
context.fail!(message: 'account_temporarily_deleted') if user.soft_deleted?
|
|
12
|
+
context.fail!(message: 'account_blocked') if user.blocked?
|
|
13
|
+
end
|
|
4
14
|
end
|
|
5
15
|
end
|
|
@@ -16,7 +16,7 @@ module SpreeCmCommissioner
|
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
context.fail!(message: I18n.t('authenticator.incorrect_password')) unless validate_password(context.user)
|
|
19
|
-
|
|
19
|
+
reject_unauthenticatable_user!(context.user)
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
private
|
|
@@ -13,16 +13,16 @@ module SpreeCmCommissioner
|
|
|
13
13
|
provider = verified_provider
|
|
14
14
|
context.user = find_or_register_user(provider)
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
reject_unauthenticatable_user!(context.user)
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
private
|
|
20
20
|
|
|
21
21
|
def verified_provider
|
|
22
|
-
result = SpreeCmCommissioner::
|
|
23
|
-
context.fail!(message: result.
|
|
22
|
+
result = SpreeCmCommissioner::Telegram::VerifyOauthIdToken.call(id_token: id_token, client_id: telegram_client_id)
|
|
23
|
+
context.fail!(message: result.error.to_s) unless result.success?
|
|
24
24
|
|
|
25
|
-
result.provider
|
|
25
|
+
result.value[:provider]
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
# Each tenant runs its own Telegram bot, so the audience an id_token must
|
|
@@ -8,6 +8,10 @@ module SpreeCmCommissioner
|
|
|
8
8
|
|
|
9
9
|
context.telegram_user = ActiveSupport::JSON.decode(checker_context.decoded_telegram_init_data['user'])
|
|
10
10
|
context.user = find_or_create_telegram_user
|
|
11
|
+
|
|
12
|
+
# Block check only — this flow has never rejected soft-deleted accounts and this change is not
|
|
13
|
+
# the place to start.
|
|
14
|
+
context.fail!(message: 'account_blocked') if context.user.blocked?
|
|
11
15
|
end
|
|
12
16
|
|
|
13
17
|
def find_or_create_telegram_user
|
|
@@ -8,6 +8,10 @@ module SpreeCmCommissioner
|
|
|
8
8
|
|
|
9
9
|
verify_token!
|
|
10
10
|
|
|
11
|
+
# Block check only — this flow has never rejected soft-deleted accounts and this change is not
|
|
12
|
+
# the place to start.
|
|
13
|
+
return context.fail!(message: 'account_blocked') if user.blocked?
|
|
14
|
+
|
|
11
15
|
context.user = user
|
|
12
16
|
rescue JWT::DecodeError => e
|
|
13
17
|
context.fail!(message: "Decode error: #{e.message}")
|