hotfix: ProtectedRoute allows access for system_admin + empty permissions + /kein-zugriff route + NoAccessPage
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { Navigate } from 'react-router-dom';
|
||||
import { usePermission } from '@/hooks/usePermission';
|
||||
import { useAuthStore } from '@/store/authStore';
|
||||
|
||||
interface ProtectedRouteProps {
|
||||
permission: string;
|
||||
@@ -9,6 +10,19 @@ interface ProtectedRouteProps {
|
||||
|
||||
export function ProtectedRoute({ permission, children }: ProtectedRouteProps) {
|
||||
const { hasPermission } = usePermission();
|
||||
const user = useAuthStore((state) => state.user);
|
||||
|
||||
// If user is system admin, always allow
|
||||
if (user?.is_system_admin) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
// If permissions array is empty or not loaded yet, allow access
|
||||
// (better to show page and let backend 403 handle it than block everything)
|
||||
const perms = user?.permissions || [];
|
||||
if (perms.length === 0) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
|
||||
if (!hasPermission(permission)) {
|
||||
return <Navigate to="/kein-zugriff" replace />;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { ShieldX } from 'lucide-react';
|
||||
|
||||
export default function NoAccessPage() {
|
||||
return (
|
||||
<div className="flex flex-col items-center justify-center min-h-screen bg-secondary-50 p-4">
|
||||
<ShieldX className="w-16 h-16 text-secondary-400 mb-4" strokeWidth={1.5} />
|
||||
<h1 className="text-2xl font-bold text-secondary-700 mb-2">Kein Zugriff</h1>
|
||||
<p className="text-secondary-500 mb-6 text-center max-w-md">
|
||||
Sie haben keine Berechtigung, auf diese Seite zuzugreifen.
|
||||
Bitte wenden Sie sich an einen Administrator, falls Sie Zugriff benötigen.
|
||||
</p>
|
||||
<Link
|
||||
to="/dashboard"
|
||||
className="px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700 transition-colors"
|
||||
>
|
||||
Zum Dashboard
|
||||
</Link>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -64,6 +64,7 @@ const ActivityTimelinePage = React.lazy(() => import('@/pages/ActivityTimeline')
|
||||
const SettingsWebhooksPage = React.lazy(() => import('@/pages/SettingsWebhooks').then(m => ({ default: m.SettingsWebhooksPage })));
|
||||
const SettingsBackupPage = React.lazy(() => import('@/pages/SettingsBackup').then(m => ({ default: m.SettingsBackupPage })));
|
||||
const SettingsRechtePage = React.lazy(() => import('@/pages/SettingsRechte').then(m => ({ default: m.SettingsRechtePage })));
|
||||
const NoAccessPage = React.lazy(() => import('@/pages/NoAccessPage').then(m => ({ default: m.NoAccessPage })));
|
||||
|
||||
/** Centered spinner fallback for lazy-loaded routes */
|
||||
function PageLoader() {
|
||||
@@ -120,6 +121,10 @@ const router = createBrowserRouter([
|
||||
path: '/guest/contacts',
|
||||
element: <GuestContactsPage />,
|
||||
},
|
||||
{
|
||||
path: '/kein-zugriff',
|
||||
element: <ErrorBoundary>{withSuspense(<NoAccessPage />)}</ErrorBoundary>,
|
||||
},
|
||||
{
|
||||
element: (
|
||||
<ProtectedRoute>
|
||||
|
||||
Reference in New Issue
Block a user