Fix Frontend Issues: CSP, Chart Height, and Logout
- Add CSP settings explicitly to local.py to ensure they are active - Implement logout API endpoint (view and url) to fix 404 - Add min-height to chart container in PlatformDashboard to fix recharts error
This commit is contained in:
@@ -63,7 +63,7 @@ const PlatformDashboard: React.FC = () => {
|
|||||||
{/* MRR Chart */}
|
{/* MRR Chart */}
|
||||||
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm">
|
<div className="bg-white dark:bg-gray-800 p-6 rounded-xl border border-gray-200 dark:border-gray-700 shadow-sm">
|
||||||
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6">{t('platform.mrrGrowth')}</h3>
|
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6">{t('platform.mrrGrowth')}</h3>
|
||||||
<div className="h-80">
|
<div className="h-80 min-h-[320px]">
|
||||||
<ResponsiveContainer width="100%" height="100%">
|
<ResponsiveContainer width="100%" height="100%">
|
||||||
<AreaChart data={data}>
|
<AreaChart data={data}>
|
||||||
<defs>
|
<defs>
|
||||||
|
|||||||
@@ -2,6 +2,43 @@
|
|||||||
from .multitenancy import * # noqa
|
from .multitenancy import * # noqa
|
||||||
from .multitenancy import env, INSTALLED_APPS, MIDDLEWARE
|
from .multitenancy import env, INSTALLED_APPS, MIDDLEWARE
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# CONTENT SECURITY POLICY (CSP)
|
||||||
|
# Explicitly imported/re-defined here to ensure they are active in local dev
|
||||||
|
# =============================================================================
|
||||||
|
CSP_DEFAULT_SRC = ("'self'",)
|
||||||
|
CSP_SCRIPT_SRC = (
|
||||||
|
"'self'",
|
||||||
|
"https://js.stripe.com",
|
||||||
|
"https://connect-js.stripe.com",
|
||||||
|
"https://www.googletagmanager.com",
|
||||||
|
"https://www.google-analytics.com",
|
||||||
|
"blob:", # Required for Stripe
|
||||||
|
)
|
||||||
|
CSP_STYLE_SRC = (
|
||||||
|
"'self'",
|
||||||
|
"'unsafe-inline'", # Required for Stripe and many UI libraries
|
||||||
|
)
|
||||||
|
CSP_IMG_SRC = (
|
||||||
|
"'self'",
|
||||||
|
"data:",
|
||||||
|
"https://*.stripe.com",
|
||||||
|
"https://www.google-analytics.com",
|
||||||
|
)
|
||||||
|
CSP_CONNECT_SRC = (
|
||||||
|
"'self'",
|
||||||
|
"https://api.stripe.com",
|
||||||
|
"https://www.google-analytics.com",
|
||||||
|
"https://stats.g.doubleclick.net",
|
||||||
|
)
|
||||||
|
CSP_FRAME_SRC = (
|
||||||
|
"'self'",
|
||||||
|
"https://js.stripe.com",
|
||||||
|
"https://hooks.stripe.com",
|
||||||
|
"https://connect-js.stripe.com",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# GENERAL
|
# GENERAL
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
# https://docs.djangoproject.com/en/dev/ref/settings/#debug
|
# https://docs.djangoproject.com/en/dev/ref/settings/#debug
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from drf_spectacular.views import SpectacularAPIView
|
|||||||
from drf_spectacular.views import SpectacularSwaggerView
|
from drf_spectacular.views import SpectacularSwaggerView
|
||||||
from rest_framework.authtoken.views import obtain_auth_token
|
from rest_framework.authtoken.views import obtain_auth_token
|
||||||
|
|
||||||
from smoothschedule.users.api_views import current_user_view
|
from smoothschedule.users.api_views import current_user_view, logout_view
|
||||||
from schedule.api_views import current_business_view
|
from schedule.api_views import current_business_view
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
@@ -36,6 +36,7 @@ urlpatterns += [
|
|||||||
# Auth API
|
# Auth API
|
||||||
path("api/auth-token/", csrf_exempt(obtain_auth_token), name="obtain_auth_token"),
|
path("api/auth-token/", csrf_exempt(obtain_auth_token), name="obtain_auth_token"),
|
||||||
path("api/auth/me/", current_user_view, name="current_user"),
|
path("api/auth/me/", current_user_view, name="current_user"),
|
||||||
|
path("api/auth/logout/", logout_view, name="logout"),
|
||||||
# Business API
|
# Business API
|
||||||
path("api/business/current/", current_business_view, name="current_business"),
|
path("api/business/current/", current_business_view, name="current_business"),
|
||||||
# API Docs
|
# API Docs
|
||||||
|
|||||||
@@ -47,3 +47,15 @@ def current_user_view(request):
|
|||||||
}
|
}
|
||||||
|
|
||||||
return Response(user_data, status=status.HTTP_200_OK)
|
return Response(user_data, status=status.HTTP_200_OK)
|
||||||
|
|
||||||
|
|
||||||
|
@api_view(['POST'])
|
||||||
|
@permission_classes([IsAuthenticated])
|
||||||
|
def logout_view(request):
|
||||||
|
"""
|
||||||
|
Logout the current user
|
||||||
|
POST /api/auth/logout/
|
||||||
|
"""
|
||||||
|
from django.contrib.auth import logout
|
||||||
|
logout(request)
|
||||||
|
return Response({"detail": "Successfully logged out."}, status=status.HTTP_200_OK)
|
||||||
|
|||||||
Reference in New Issue
Block a user