From f47c680cb86de1980f8094367ea63fb313149491 Mon Sep 17 00:00:00 2001 From: Samir Boulahtit Date: Tue, 24 Feb 2026 12:29:52 +0100 Subject: [PATCH] fix: storefront login 403, cookie path, double-storefront URLs, and auth redirects - Extract store/platform context from Referer header for storefront API requests (StoreContextMiddleware and PlatformContextMiddleware) so login POST works in dev mode where API paths lack /platforms/{code}/ prefix - Set customer token cookie path to "/" for cross-route compatibility - Fix double storefront in URLs: replace {{ base_url }}storefront/ with {{ base_url }} across all 24 storefront templates - Fix auth error redirect to include platform prefix and use store_code - Update seed script to output correct storefront login URLs - Add 20 new unit tests covering all fixes; fix 9 pre-existing test failures Co-Authored-By: Claude Opus 4.6 --- app/exceptions/handler.py | 19 ++- .../billing/admin/subscription-tiers.html | 2 +- .../cart/templates/cart/storefront/cart.html | 10 +- .../catalog/storefront/category.html | 8 +- .../templates/catalog/storefront/product.html | 8 +- .../catalog/storefront/products.html | 4 +- .../templates/catalog/storefront/search.html | 4 +- .../catalog/storefront/wishlist.html | 10 +- .../checkout/storefront/checkout.html | 8 +- .../cms/storefront/landing-default.html | 10 +- .../cms/storefront/landing-full.html | 12 +- .../cms/storefront/landing-minimal.html | 6 +- .../cms/storefront/landing-modern.html | 4 +- .../customers/routes/api/storefront.py | 43 +----- .../customers/routes/pages/storefront.py | 19 ++- .../customers/storefront/addresses.html | 2 +- .../customers/storefront/dashboard.html | 14 +- .../customers/storefront/forgot-password.html | 4 +- .../templates/customers/storefront/login.html | 8 +- .../customers/storefront/profile.html | 12 +- .../customers/storefront/register.html | 4 +- .../customers/storefront/reset-password.html | 8 +- .../loyalty/storefront/dashboard.html | 6 +- .../loyalty/storefront/enroll-success.html | 4 +- .../templates/loyalty/storefront/history.html | 2 +- .../messaging/storefront/messages.html | 14 +- .../orders/storefront/order-detail.html | 18 +-- .../templates/orders/storefront/orders.html | 10 +- middleware/platform_context.py | 58 ++++++- middleware/store_context.py | 36 ++++- scripts/seed/seed_demo.py | 9 +- tests/unit/api/test_storefront_auth.py | 44 ++++++ tests/unit/middleware/test_frontend_type.py | 34 ++-- tests/unit/middleware/test_language.py | 5 +- .../unit/middleware/test_platform_context.py | 85 ++++++++++ tests/unit/middleware/test_store_context.py | 109 +++++++++++++ tests/unit/test_exception_handler.py | 125 +++++++++++++++ tests/unit/utils/test_page_context.py | 146 ++++++++++++++++++ 38 files changed, 759 insertions(+), 165 deletions(-) create mode 100644 tests/unit/api/test_storefront_auth.py create mode 100644 tests/unit/test_exception_handler.py create mode 100644 tests/unit/utils/test_page_context.py diff --git a/app/exceptions/handler.py b/app/exceptions/handler.py index 84fbbee4..3ef58ac0 100644 --- a/app/exceptions/handler.py +++ b/app/exceptions/handler.py @@ -434,14 +434,19 @@ def _redirect_to_login(request: Request) -> RedirectResponse: base_url = "/" if access_method == "path" and store: - full_prefix = ( - store_context.get("full_prefix", "/store/") - if store_context - else "/store/" - ) - base_url = f"{full_prefix}{store.subdomain}/" + platform = getattr(request.state, "platform", None) + platform_original_path = getattr(request.state, "platform_original_path", None) + if platform and platform_original_path and platform_original_path.startswith("/platforms/"): + base_url = f"/platforms/{platform.code}/storefront/{store.store_code}/" + else: + full_prefix = ( + store_context.get("full_prefix", "/storefront/") + if store_context + else "/storefront/" + ) + base_url = f"{full_prefix}{store.store_code}/" - login_url = f"{base_url}storefront/account/login" + login_url = f"{base_url}account/login" logger.debug(f"Redirecting to {login_url}") return RedirectResponse(url=login_url, status_code=302) # Fallback to root for unknown contexts (PLATFORM) diff --git a/app/modules/billing/templates/billing/admin/subscription-tiers.html b/app/modules/billing/templates/billing/admin/subscription-tiers.html index cf8f891d..8d87d375 100644 --- a/app/modules/billing/templates/billing/admin/subscription-tiers.html +++ b/app/modules/billing/templates/billing/admin/subscription-tiers.html @@ -352,7 +352,7 @@ x-transition:leave="transform transition ease-in-out duration-300" x-transition:leave-start="translate-x-0" x-transition:leave-end="translate-x-full" - class="w-screen max-w-lg" + class="w-screen max-w-lg h-full" >
diff --git a/app/modules/cart/templates/cart/storefront/cart.html b/app/modules/cart/templates/cart/storefront/cart.html index 6f7e2efd..917cce93 100644 --- a/app/modules/cart/templates/cart/storefront/cart.html +++ b/app/modules/cart/templates/cart/storefront/cart.html @@ -14,7 +14,7 @@ @@ -40,7 +40,7 @@

Add some products to get started!

- + Browse Products
@@ -154,7 +154,7 @@ Proceed to Checkout - + Continue Shopping @@ -309,9 +309,9 @@ document.addEventListener('alpine:init', () => { if (!token) { // Redirect to login with return URL - window.location.href = '{{ base_url }}storefront/account/login?return={{ base_url }}storefront/checkout'; + window.location.href = '{{ base_url }}account/login?return={{ base_url }}checkout'; } else { - window.location.href = '{{ base_url }}storefront/checkout'; + window.location.href = '{{ base_url }}checkout'; } } }; diff --git a/app/modules/catalog/templates/catalog/storefront/category.html b/app/modules/catalog/templates/catalog/storefront/category.html index cad1237f..84451a46 100644 --- a/app/modules/catalog/templates/catalog/storefront/category.html +++ b/app/modules/catalog/templates/catalog/storefront/category.html @@ -13,7 +13,7 @@ @@ -61,14 +61,14 @@