feat: implement security, error resilience, and query optimization proposals
Security Validation (enhance-security-validation): - JWT secret validation with entropy checking and pattern detection - CSRF protection middleware with token generation/validation - Frontend CSRF token auto-injection for DELETE/PUT/PATCH requests - MIME type validation with magic bytes detection for file uploads Error Resilience (add-error-resilience): - React ErrorBoundary component with fallback UI and retry functionality - ErrorBoundaryWithI18n wrapper for internationalization support - Page-level and section-level error boundaries in App.tsx Query Performance (optimize-query-performance): - Query monitoring utility with threshold warnings - N+1 query fixes using joinedload/selectinload - Optimized project members, tasks, and subtasks endpoints Bug Fixes: - WebSocket session management (P0): Return primitives instead of ORM objects - LIKE query injection (P1): Escape special characters in search queries Tests: 543 backend tests, 56 frontend tests passing Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import { Routes, Route, Navigate } from 'react-router-dom'
|
||||
import { useAuth } from './contexts/AuthContext'
|
||||
import { Skeleton } from './components/Skeleton'
|
||||
import { ErrorBoundary } from './components/ErrorBoundary'
|
||||
import { SectionErrorBoundary } from './components/ErrorBoundaryWithI18n'
|
||||
import Login from './pages/Login'
|
||||
import Dashboard from './pages/Dashboard'
|
||||
import Spaces from './pages/Spaces'
|
||||
@@ -27,102 +29,122 @@ function App() {
|
||||
}
|
||||
|
||||
return (
|
||||
<Routes>
|
||||
<Route
|
||||
path="/login"
|
||||
element={isAuthenticated ? <Navigate to="/" /> : <Login />}
|
||||
/>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<Dashboard />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/spaces"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<Spaces />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/spaces/:spaceId"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<Projects />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/projects/:projectId"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<Tasks />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/projects/:projectId/settings"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<ProjectSettings />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/audit"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<AuditPage />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workload"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<WorkloadPage />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/project-health"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<ProjectHealthPage />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/my-settings"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<MySettings />
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
<ErrorBoundary variant="page">
|
||||
<Routes>
|
||||
<Route
|
||||
path="/login"
|
||||
element={isAuthenticated ? <Navigate to="/" /> : <Login />}
|
||||
/>
|
||||
<Route
|
||||
path="/"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Dashboard">
|
||||
<Dashboard />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/spaces"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Spaces">
|
||||
<Spaces />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/spaces/:spaceId"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Projects">
|
||||
<Projects />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/projects/:projectId"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Tasks">
|
||||
<Tasks />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/projects/:projectId/settings"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Project Settings">
|
||||
<ProjectSettings />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/audit"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Audit">
|
||||
<AuditPage />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/workload"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Workload">
|
||||
<WorkloadPage />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/project-health"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Project Health">
|
||||
<ProjectHealthPage />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
<Route
|
||||
path="/my-settings"
|
||||
element={
|
||||
<ProtectedRoute>
|
||||
<Layout>
|
||||
<SectionErrorBoundary sectionName="Settings">
|
||||
<MySettings />
|
||||
</SectionErrorBoundary>
|
||||
</Layout>
|
||||
</ProtectedRoute>
|
||||
}
|
||||
/>
|
||||
</Routes>
|
||||
</ErrorBoundary>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user