fix: make storefront API referer extraction platform-aware and fix script loading
Some checks failed
Some checks failed
Two bugs causing "Program Not Available" on storefront enrollment: 1. extract_store_from_referer() was not platform-aware — used settings.main_domain (wizard.lu) instead of platform.domain (rewardflow.lu) for subdomain detection, and restricted path-based extraction to localhost only. Now mirrors the platform-aware logic from _detect_store_from_host_and_path(): checks platform.domain for subdomain detection (fashionhub.rewardflow.lu → fashionhub) and allows path-based extraction on platform domains (rewardflow.lu/storefront/FASHIONHUB/... → FASHIONHUB). 2. Storefront JS scripts (enroll, dashboard, history) were missing defer attribute, causing them to execute before log-config.js and crash on window.LogConfig access. Also fix quote escaping in server-side rendered x-text expressions for French translations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -230,5 +230,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script src="{{ url_for('loyalty_static', path='storefront/js/loyalty-dashboard.js') }}"></script>
|
||||
<script defer src="{{ url_for('loyalty_static', path='storefront/js/loyalty-dashboard.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -119,7 +119,7 @@
|
||||
class="w-full py-3 px-4 text-white font-semibold rounded-lg transition-colors disabled:opacity-50"
|
||||
:style="'background-color: ' + (program?.card_color || 'var(--color-primary)')">
|
||||
<span x-show="enrolling" x-html="$icon('spinner', 'w-5 h-5 inline animate-spin mr-2')"></span>
|
||||
<span x-text="enrolling ? '{{ _('loyalty.enrollment.form.joining') }}' : '{{ _('loyalty.enrollment.form.join_button', points=program.welcome_bonus_points if program else 0) }}'"></span>
|
||||
<span x-text="enrolling ? '{{ _('loyalty.enrollment.form.joining')|replace("'", "\\'") }}' : '{{ _('loyalty.enrollment.form.join_button', points=program.welcome_bonus_points if program else 0)|replace("'", "\\'") }}'"></span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
@@ -170,5 +170,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script src="{{ url_for('loyalty_static', path='storefront/js/loyalty-enroll.js') }}"></script>
|
||||
<script defer src="{{ url_for('loyalty_static', path='storefront/js/loyalty-enroll.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -105,5 +105,5 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_scripts %}
|
||||
<script src="{{ url_for('loyalty_static', path='storefront/js/loyalty-history.js') }}"></script>
|
||||
<script defer src="{{ url_for('loyalty_static', path='storefront/js/loyalty-history.js') }}"></script>
|
||||
{% endblock %}
|
||||
|
||||
@@ -295,13 +295,17 @@ class StoreContextManager:
|
||||
Extract store context from Referer header.
|
||||
|
||||
Used for storefront API requests where store context comes from the page
|
||||
that made the API call (e.g., JavaScript on /stores/orion/storefront/products
|
||||
calling /api/v1/storefront/products).
|
||||
that made the API call (e.g., JavaScript on /storefront/FASHIONHUB/loyalty/join
|
||||
calling /api/v1/storefront/loyalty/program).
|
||||
|
||||
Platform-aware: uses request.state.platform.domain (e.g. rewardflow.lu)
|
||||
for subdomain detection, not just settings.main_domain (wizard.lu).
|
||||
|
||||
Extracts store from Referer URL patterns:
|
||||
- http://localhost:8000/stores/orion/storefront/... → orion
|
||||
- http://orion.platform.com/storefront/... → orion (subdomain) # noqa
|
||||
- http://custom-domain.com/storefront/... → custom-domain.com # noqa
|
||||
- localhost:8000/platforms/loyalty/storefront/FASHIONHUB/... → FASHIONHUB (dev path)
|
||||
- rewardflow.lu/storefront/FASHIONHUB/... → FASHIONHUB (prod platform domain path)
|
||||
- fashionhub.rewardflow.lu/... → fashionhub (prod platform subdomain)
|
||||
- custom-domain.com/... → custom-domain.com (prod custom domain)
|
||||
|
||||
Returns store context dict or None if unable to extract.
|
||||
"""
|
||||
@@ -331,20 +335,34 @@ class StoreContextManager:
|
||||
},
|
||||
)
|
||||
|
||||
# Method 1: Path-based detection from referer path (local hosts only)
|
||||
# /platforms/oms/storefront/WIZATECH/products → WIZATECH
|
||||
# /stores/orion/storefront/products → orion
|
||||
# /storefront/WIZATECH/products → WIZATECH
|
||||
# Note: For subdomain/custom domain hosts, the store code is NOT in the path
|
||||
# (e.g., orion.platform.com/storefront/products — "products" is a page, not a store)
|
||||
# Determine platform domain for platform-aware detection
|
||||
# (e.g. rewardflow.lu from the loyalty platform object)
|
||||
platform = getattr(request.state, "platform", None)
|
||||
platform_own_domain = getattr(platform, "domain", None) if platform else None
|
||||
is_platform_domain = (
|
||||
platform_own_domain and referer_host == platform_own_domain
|
||||
)
|
||||
is_subdomain_of_platform = (
|
||||
platform_own_domain
|
||||
and referer_host != platform_own_domain
|
||||
and referer_host.endswith(f".{platform_own_domain}")
|
||||
)
|
||||
|
||||
# Method 1: Path-based detection from referer path
|
||||
# Works on localhost (dev) AND on platform domains (prod path-based routing)
|
||||
# /platforms/oms/storefront/WIZATECH/products → WIZATECH (dev)
|
||||
# /storefront/FASHIONHUB/loyalty/join → FASHIONHUB (prod platform domain)
|
||||
# Note: For subdomain hosts, path segments after /storefront/ are pages, not store codes
|
||||
is_local_referer = referer_host in ("localhost", "127.0.0.1", "testserver")
|
||||
if is_local_referer and referer_path.startswith("/platforms/"):
|
||||
use_path_detection = is_local_referer or is_platform_domain
|
||||
|
||||
if use_path_detection and referer_path.startswith("/platforms/"):
|
||||
# Strip /platforms/{code}/ to get clean path
|
||||
after_platforms = referer_path[11:] # Remove "/platforms/"
|
||||
parts = after_platforms.split("/", 1)
|
||||
referer_path = "/" + parts[1] if len(parts) > 1 and parts[1] else "/"
|
||||
|
||||
if is_local_referer and referer_path.startswith(("/stores/", "/store/", "/storefront/")):
|
||||
if use_path_detection and referer_path.startswith(("/stores/", "/store/", "/storefront/")):
|
||||
if referer_path.startswith("/storefront/"):
|
||||
prefix = "/storefront/"
|
||||
elif referer_path.startswith("/stores/"):
|
||||
@@ -371,7 +389,25 @@ class StoreContextManager:
|
||||
}
|
||||
|
||||
# Method 2: Subdomain detection from referer host
|
||||
# orion.platform.com → orion
|
||||
# fashionhub.rewardflow.lu → fashionhub (platform subdomain)
|
||||
# store1.wizard.lu → store1 (main domain subdomain)
|
||||
if is_subdomain_of_platform:
|
||||
subdomain = referer_host.split(".")[0]
|
||||
logger.debug(
|
||||
f"[STORE] Extracted store from Referer platform subdomain: {subdomain}",
|
||||
extra={
|
||||
"subdomain": subdomain,
|
||||
"method": "referer_platform_subdomain",
|
||||
"platform_domain": platform_own_domain,
|
||||
},
|
||||
)
|
||||
return {
|
||||
"subdomain": subdomain,
|
||||
"detection_method": "referer_subdomain",
|
||||
"host": referer_host,
|
||||
"referer": referer,
|
||||
}
|
||||
|
||||
main_domain = getattr(settings, "main_domain", "platform.com")
|
||||
if "." in referer_host:
|
||||
parts = referer_host.split(".")
|
||||
@@ -397,6 +433,8 @@ class StoreContextManager:
|
||||
# custom-shop.com → custom-shop.com
|
||||
is_custom_domain = (
|
||||
referer_host
|
||||
and not is_platform_domain
|
||||
and not is_subdomain_of_platform
|
||||
and not referer_host.endswith(f".{main_domain}")
|
||||
and referer_host != main_domain
|
||||
and referer_host not in ["localhost", "127.0.0.1"]
|
||||
|
||||
Reference in New Issue
Block a user