feat: multi-module improvements across merchant, store, i18n, and customer systems
All checks were successful
All checks were successful
- Fix platform-grouped merchant sidebar menu with core items at root level - Add merchant store management (detail page, create store, team page) - Fix store settings 500 error by removing dead stripe/API tab - Move onboarding translations to module-owned locale files - Fix onboarding banner i18n with server-side rendering + context inheritance - Refactor login language selectors to use languageSelector() function (LANG-002) - Move HTTPException handling to global exception handler in merchant routes (API-003) - Add language selector to all login pages and portal headers - Fix customer module: drop order stats from customer model, add to orders module - Fix admin menu config visibility for super admin platform context - Fix storefront auth and layout issues - Add missing i18n translations for onboarding steps (en/fr/de/lb) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -164,6 +164,7 @@ def get_accessible_platforms(
|
||||
],
|
||||
"is_super_admin": current_user.is_super_admin,
|
||||
"requires_platform_selection": not current_user.is_super_admin and len(platforms) > 0,
|
||||
"current_platform_id": current_user.token_platform_id,
|
||||
}
|
||||
|
||||
|
||||
@@ -175,10 +176,10 @@ def select_platform(
|
||||
current_user: UserContext = Depends(get_current_admin_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Select platform context for platform admin.
|
||||
Select platform context for an admin.
|
||||
|
||||
Issues a new JWT token with platform context.
|
||||
Super admins skip this step (they have global access).
|
||||
Available to both platform admins and super admins.
|
||||
|
||||
Args:
|
||||
platform_id: Platform ID to select
|
||||
@@ -186,13 +187,9 @@ def select_platform(
|
||||
Returns:
|
||||
PlatformSelectResponse with new token and platform info
|
||||
"""
|
||||
if current_user.is_super_admin:
|
||||
raise InvalidCredentialsException(
|
||||
"Super admins don't need platform selection - they have global access"
|
||||
)
|
||||
|
||||
# Verify admin has access to this platform (raises exception if not)
|
||||
admin_platform_service.validate_admin_platform_access(current_user, platform_id)
|
||||
# Platform admins must have access; super admins can access any platform
|
||||
if not current_user.is_super_admin:
|
||||
admin_platform_service.validate_admin_platform_access(current_user, platform_id)
|
||||
|
||||
# Load platform
|
||||
platform = admin_platform_service.get_platform_by_id(db, platform_id)
|
||||
@@ -227,3 +224,45 @@ def select_platform(
|
||||
platform_id=platform.id,
|
||||
platform_code=platform.code,
|
||||
)
|
||||
|
||||
|
||||
@admin_auth_router.post("/deselect-platform")
|
||||
def deselect_platform(
|
||||
response: Response,
|
||||
current_user: UserContext = Depends(get_current_admin_from_cookie_or_header),
|
||||
):
|
||||
"""
|
||||
Deselect platform context (return to global mode).
|
||||
|
||||
Only available to super admins. Issues a new JWT without platform context.
|
||||
|
||||
Returns:
|
||||
New token without platform context
|
||||
"""
|
||||
if not current_user.is_super_admin:
|
||||
raise InvalidCredentialsException(
|
||||
"Only super admins can deselect platform (platform admins must always have a platform)"
|
||||
)
|
||||
|
||||
# Issue new token without platform context
|
||||
auth_manager = AuthManager()
|
||||
token_data = auth_manager.create_access_token(user=current_user)
|
||||
|
||||
# Set cookie with new token
|
||||
response.set_cookie(
|
||||
key="admin_token",
|
||||
value=token_data["access_token"],
|
||||
httponly=True,
|
||||
secure=should_use_secure_cookies(),
|
||||
samesite="lax",
|
||||
max_age=token_data["expires_in"],
|
||||
path="/admin",
|
||||
)
|
||||
|
||||
logger.info(f"Super admin {current_user.username} deselected platform (global mode)")
|
||||
|
||||
return {
|
||||
"access_token": token_data["access_token"],
|
||||
"token_type": token_data["token_type"],
|
||||
"expires_in": token_data["expires_in"],
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user