feat: add 403 handling and role-based route guard support
ProtectedRoute now accepts an optional requiredRole prop for role-based route guards. When specified, users below the required role level are redirected to /trees. 403 responses already pass through to components for inline error display. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,13 +1,16 @@
|
|||||||
import { Navigate, useLocation } from 'react-router-dom'
|
import { Navigate, useLocation } from 'react-router-dom'
|
||||||
import { useAuthStore } from '@/store/authStore'
|
import { useAuthStore } from '@/store/authStore'
|
||||||
|
import { usePermissions, type EffectiveRole } from '@/hooks/usePermissions'
|
||||||
|
|
||||||
interface ProtectedRouteProps {
|
interface ProtectedRouteProps {
|
||||||
|
requiredRole?: EffectiveRole
|
||||||
children: React.ReactNode
|
children: React.ReactNode
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProtectedRoute({ children }: ProtectedRouteProps) {
|
export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps) {
|
||||||
const { isAuthenticated, isLoading } = useAuthStore()
|
const { isAuthenticated, isLoading } = useAuthStore()
|
||||||
const location = useLocation()
|
const location = useLocation()
|
||||||
|
const { effectiveRole } = usePermissions()
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
return (
|
return (
|
||||||
@@ -21,6 +24,18 @@ export function ProtectedRoute({ children }: ProtectedRouteProps) {
|
|||||||
return <Navigate to="/login" state={{ from: location }} replace />
|
return <Navigate to="/login" state={{ from: location }} replace />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (requiredRole) {
|
||||||
|
const ROLE_HIERARCHY: Record<EffectiveRole, number> = {
|
||||||
|
super_admin: 4,
|
||||||
|
team_admin: 3,
|
||||||
|
engineer: 2,
|
||||||
|
viewer: 1,
|
||||||
|
}
|
||||||
|
if (ROLE_HIERARCHY[effectiveRole] < ROLE_HIERARCHY[requiredRole]) {
|
||||||
|
return <Navigate to="/trees" replace />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return <>{children}</>
|
return <>{children}</>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user