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:
chihlasm
2026-02-05 23:34:00 -05:00
parent 33368688b2
commit 2ee549bfbc

View File

@@ -1,13 +1,16 @@
import { Navigate, useLocation } from 'react-router-dom'
import { useAuthStore } from '@/store/authStore'
import { usePermissions, type EffectiveRole } from '@/hooks/usePermissions'
interface ProtectedRouteProps {
requiredRole?: EffectiveRole
children: React.ReactNode
}
export function ProtectedRoute({ children }: ProtectedRouteProps) {
export function ProtectedRoute({ requiredRole, children }: ProtectedRouteProps) {
const { isAuthenticated, isLoading } = useAuthStore()
const location = useLocation()
const { effectiveRole } = usePermissions()
if (isLoading) {
return (
@@ -21,6 +24,18 @@ export function ProtectedRoute({ children }: ProtectedRouteProps) {
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}</>
}