mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-01-16 14:12:10 +01:00
fix: resolve all Biome linting errors and Prettier formatting issues
- Reduce cognitive complexity in lib/api/handler.ts (23 → 15) - Reduce cognitive complexity in lib/config/provider.ts (38 → 15) - Fix TypeScript any type violations in multiple files - Remove unused variable in lib/batchSchedulerOptimized.ts - Add prettier-ignore comments to documentation with intentional syntax errors - Resolve Prettier/Biome formatting conflicts with targeted ignores - Create .prettierignore for build artifacts and dependencies All linting checks now pass and build completes successfully (47/47 pages).
This commit is contained in:
@ -6,10 +6,10 @@ This document describes the comprehensive CSRF (Cross-Site Request Forgery) prot
|
||||
|
||||
CSRF protection has been implemented to prevent cross-site request forgery attacks on state-changing operations. The implementation follows industry best practices and provides protection at multiple layers:
|
||||
|
||||
- **Middleware Level**: Automatic CSRF validation for protected endpoints
|
||||
- **tRPC Level**: CSRF protection for all state-changing tRPC procedures
|
||||
- **Client Level**: Automatic token management and inclusion in requests
|
||||
- **Component Level**: React components and hooks for easy integration
|
||||
- **Middleware Level**: Automatic CSRF validation for protected endpoints
|
||||
- **tRPC Level**: CSRF protection for all state-changing tRPC procedures
|
||||
- **Client Level**: Automatic token management and inclusion in requests
|
||||
- **Component Level**: React components and hooks for easy integration
|
||||
|
||||
## Implementation Components
|
||||
|
||||
@ -17,17 +17,17 @@ CSRF protection has been implemented to prevent cross-site request forgery attac
|
||||
|
||||
The core CSRF functionality includes:
|
||||
|
||||
- **Token Generation**: Cryptographically secure token generation using the `csrf` library
|
||||
- **Token Verification**: Server-side token validation
|
||||
- **Request Parsing**: Support for tokens in headers, JSON bodies, and form data
|
||||
- **Client Utilities**: Browser-side token management and request enhancement
|
||||
- **Token Generation**: Cryptographically secure token generation using the `csrf` library
|
||||
- **Token Verification**: Server-side token validation
|
||||
- **Request Parsing**: Support for tokens in headers, JSON bodies, and form data
|
||||
- **Client Utilities**: Browser-side token management and request enhancement
|
||||
|
||||
**Key Functions:**
|
||||
|
||||
- `generateCSRFToken()` - Creates new CSRF tokens
|
||||
- `verifyCSRFToken()` - Validates tokens server-side
|
||||
- `CSRFProtection.validateRequest()` - Request validation middleware
|
||||
- `CSRFClient.*` - Client-side utilities
|
||||
- `generateCSRFToken()` - Creates new CSRF tokens
|
||||
- `verifyCSRFToken()` - Validates tokens server-side
|
||||
- `CSRFProtection.validateRequest()` - Request validation middleware
|
||||
- `CSRFClient.*` - Client-side utilities
|
||||
|
||||
### 2. Middleware Protection (`middleware/csrfProtection.ts`)
|
||||
|
||||
@ -35,26 +35,26 @@ Provides automatic CSRF protection for API endpoints:
|
||||
|
||||
**Protected Endpoints:**
|
||||
|
||||
- `/api/auth/*` - Authentication endpoints
|
||||
- `/api/register` - User registration
|
||||
- `/api/forgot-password` - Password reset requests
|
||||
- `/api/reset-password` - Password reset completion
|
||||
- `/api/dashboard/*` - Dashboard API endpoints
|
||||
- `/api/platform/*` - Platform admin endpoints
|
||||
- `/api/trpc/*` - All tRPC endpoints
|
||||
- `/api/auth/*` - Authentication endpoints
|
||||
- `/api/register` - User registration
|
||||
- `/api/forgot-password` - Password reset requests
|
||||
- `/api/reset-password` - Password reset completion
|
||||
- `/api/dashboard/*` - Dashboard API endpoints
|
||||
- `/api/platform/*` - Platform admin endpoints
|
||||
- `/api/trpc/*` - All tRPC endpoints
|
||||
|
||||
**Protected Methods:**
|
||||
|
||||
- `POST` - Create operations
|
||||
- `PUT` - Update operations
|
||||
- `DELETE` - Delete operations
|
||||
- `PATCH` - Partial update operations
|
||||
- `POST` - Create operations
|
||||
- `PUT` - Update operations
|
||||
- `DELETE` - Delete operations
|
||||
- `PATCH` - Partial update operations
|
||||
|
||||
**Safe Methods (Not Protected):**
|
||||
|
||||
- `GET` - Read operations
|
||||
- `HEAD` - Metadata requests
|
||||
- `OPTIONS` - CORS preflight requests
|
||||
- `GET` - Read operations
|
||||
- `HEAD` - Metadata requests
|
||||
- `OPTIONS` - CORS preflight requests
|
||||
|
||||
### 3. tRPC Integration (`lib/trpc.ts`)
|
||||
|
||||
@ -62,57 +62,57 @@ CSRF protection integrated into tRPC procedures:
|
||||
|
||||
**New Procedure Types:**
|
||||
|
||||
- `csrfProtectedProcedure` - Basic CSRF protection
|
||||
- `csrfProtectedAuthProcedure` - CSRF + authentication protection
|
||||
- `csrfProtectedCompanyProcedure` - CSRF + company access protection
|
||||
- `csrfProtectedAdminProcedure` - CSRF + admin access protection
|
||||
- `csrfProtectedProcedure` - Basic CSRF protection
|
||||
- `csrfProtectedAuthProcedure` - CSRF + authentication protection
|
||||
- `csrfProtectedCompanyProcedure` - CSRF + company access protection
|
||||
- `csrfProtectedAdminProcedure` - CSRF + admin access protection
|
||||
|
||||
**Updated Router Example:**
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
register: rateLimitedProcedure
|
||||
.input(registerSchema)
|
||||
.mutation(async ({ input, ctx }) => { /* ... */ });
|
||||
register: rateLimitedProcedure.input(registerSchema).mutation(async ({ input, ctx }) => {
|
||||
/* ... */
|
||||
});
|
||||
|
||||
// After
|
||||
register: csrfProtectedProcedure
|
||||
.input(registerSchema)
|
||||
.mutation(async ({ input, ctx }) => { /* ... */ });
|
||||
register: csrfProtectedProcedure.input(registerSchema).mutation(async ({ input, ctx }) => {
|
||||
/* ... */
|
||||
});
|
||||
```
|
||||
|
||||
### 4. Client-Side Integration
|
||||
|
||||
#### tRPC Client (`lib/trpc-client.ts`)
|
||||
|
||||
- Automatic CSRF token inclusion in tRPC requests
|
||||
- Token extracted from cookies and added to request headers
|
||||
- Automatic CSRF token inclusion in tRPC requests
|
||||
- Token extracted from cookies and added to request headers
|
||||
|
||||
#### React Hooks (`lib/hooks/useCSRF.ts`)
|
||||
|
||||
- `useCSRF()` - Basic token management
|
||||
- `useCSRFFetch()` - Enhanced fetch with automatic CSRF tokens
|
||||
- `useCSRFForm()` - Form submission with CSRF protection
|
||||
- `useCSRF()` - Basic token management
|
||||
- `useCSRFFetch()` - Enhanced fetch with automatic CSRF tokens
|
||||
- `useCSRFForm()` - Form submission with CSRF protection
|
||||
|
||||
#### Provider Component (`components/providers/CSRFProvider.tsx`)
|
||||
|
||||
- Application-wide CSRF token management
|
||||
- Automatic token fetching and refresh
|
||||
- Context-based token sharing
|
||||
- Application-wide CSRF token management
|
||||
- Automatic token fetching and refresh
|
||||
- Context-based token sharing
|
||||
|
||||
#### Protected Form Component (`components/forms/CSRFProtectedForm.tsx`)
|
||||
|
||||
- Ready-to-use form component with CSRF protection
|
||||
- Automatic token inclusion in form submissions
|
||||
- Graceful fallback for non-JavaScript environments
|
||||
- Ready-to-use form component with CSRF protection
|
||||
- Automatic token inclusion in form submissions
|
||||
- Graceful fallback for non-JavaScript environments
|
||||
|
||||
### 5. API Endpoint (`app/api/csrf-token/route.ts`)
|
||||
|
||||
Provides CSRF tokens to client applications:
|
||||
|
||||
- `GET /api/csrf-token` - Returns new CSRF token
|
||||
- Sets HTTP-only cookie for automatic inclusion
|
||||
- Used by client-side hooks and components
|
||||
- `GET /api/csrf-token` - Returns new CSRF token
|
||||
- Sets HTTP-only cookie for automatic inclusion
|
||||
- Used by client-side hooks and components
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -144,17 +144,17 @@ export const CSRF_CONFIG = {
|
||||
### 1. Using CSRF in React Components
|
||||
|
||||
```tsx
|
||||
import { useCSRFFetch } from '@/lib/hooks/useCSRF';
|
||||
import { useCSRFFetch } from "@/lib/hooks/useCSRF";
|
||||
|
||||
function MyComponent() {
|
||||
const { csrfFetch } = useCSRFFetch();
|
||||
|
||||
const handleSubmit = async () => {
|
||||
// CSRF token automatically included
|
||||
const response = await csrfFetch('/api/dashboard/sessions', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ data: 'example' }),
|
||||
const response = await csrfFetch("/api/dashboard/sessions", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ data: "example" }),
|
||||
});
|
||||
};
|
||||
}
|
||||
@ -163,7 +163,7 @@ function MyComponent() {
|
||||
### 2. Using CSRF Protected Forms
|
||||
|
||||
```tsx
|
||||
import { CSRFProtectedForm } from '@/components/forms/CSRFProtectedForm';
|
||||
import { CSRFProtectedForm } from "@/components/forms/CSRFProtectedForm";
|
||||
|
||||
function RegistrationForm() {
|
||||
return (
|
||||
@ -194,15 +194,15 @@ export const userRouter = router({
|
||||
### 4. Manual CSRF Token Handling
|
||||
|
||||
```typescript
|
||||
import { CSRFClient } from '@/lib/csrf';
|
||||
import { CSRFClient } from "@/lib/csrf";
|
||||
|
||||
// Get token from cookies
|
||||
const token = CSRFClient.getToken();
|
||||
|
||||
// Add to fetch options
|
||||
const options = CSRFClient.addTokenToFetch({
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
@ -211,17 +211,17 @@ const formData = new FormData();
|
||||
CSRFClient.addTokenToFormData(formData);
|
||||
|
||||
// Add to object
|
||||
const dataWithToken = CSRFClient.addTokenToObject({ data: 'example' });
|
||||
const dataWithToken = CSRFClient.addTokenToObject({ data: "example" });
|
||||
```
|
||||
|
||||
## Security Features
|
||||
|
||||
### 1. Token Properties
|
||||
|
||||
- **Cryptographically Secure**: Uses the `csrf` library with secure random generation
|
||||
- **Short-Lived**: 24-hour expiration by default
|
||||
- **HTTP-Only Cookies**: Prevents XSS-based token theft
|
||||
- **SameSite Protection**: Reduces CSRF attack surface
|
||||
- **Cryptographically Secure**: Uses the `csrf` library with secure random generation
|
||||
- **Short-Lived**: 24-hour expiration by default
|
||||
- **HTTP-Only Cookies**: Prevents XSS-based token theft
|
||||
- **SameSite Protection**: Reduces CSRF attack surface
|
||||
|
||||
### 2. Validation Process
|
||||
|
||||
@ -233,19 +233,19 @@ const dataWithToken = CSRFClient.addTokenToObject({ data: 'example' });
|
||||
|
||||
### 3. Error Handling
|
||||
|
||||
- **Graceful Degradation**: Form fallbacks for JavaScript-disabled browsers
|
||||
- **Clear Error Messages**: Specific error codes for debugging
|
||||
- **Rate Limiting Integration**: Works with existing auth rate limiting
|
||||
- **Logging**: Comprehensive logging for security monitoring
|
||||
- **Graceful Degradation**: Form fallbacks for JavaScript-disabled browsers
|
||||
- **Clear Error Messages**: Specific error codes for debugging
|
||||
- **Rate Limiting Integration**: Works with existing auth rate limiting
|
||||
- **Logging**: Comprehensive logging for security monitoring
|
||||
|
||||
## Testing
|
||||
|
||||
### Test Coverage
|
||||
|
||||
- **Unit Tests**: Token generation, validation, and client utilities
|
||||
- **Integration Tests**: Middleware behavior and endpoint protection
|
||||
- **Component Tests**: React hooks and form components
|
||||
- **End-to-End**: Full request/response cycle testing
|
||||
- **Unit Tests**: Token generation, validation, and client utilities
|
||||
- **Integration Tests**: Middleware behavior and endpoint protection
|
||||
- **Component Tests**: React hooks and form components
|
||||
- **End-to-End**: Full request/response cycle testing
|
||||
|
||||
### Running Tests
|
||||
|
||||
@ -272,19 +272,22 @@ CSRF validation failed for POST /api/dashboard/sessions: CSRF token missing from
|
||||
### Common Issues and Solutions
|
||||
|
||||
1. **Token Missing from Request**
|
||||
- Ensure CSRFProvider is wrapping your app
|
||||
- Check that hooks are being used correctly
|
||||
- Verify network requests include credentials
|
||||
|
||||
- Ensure CSRFProvider is wrapping your app
|
||||
- Check that hooks are being used correctly
|
||||
- Verify network requests include credentials
|
||||
|
||||
2. **Token Mismatch**
|
||||
- Clear browser cookies and refresh
|
||||
- Check for multiple token sources conflicting
|
||||
- Verify server and client time synchronization
|
||||
|
||||
- Clear browser cookies and refresh
|
||||
- Check for multiple token sources conflicting
|
||||
- Verify server and client time synchronization
|
||||
|
||||
3. **Integration Issues**
|
||||
- Ensure middleware is properly configured
|
||||
- Check tRPC client configuration
|
||||
- Verify protected procedures are using correct types
|
||||
|
||||
- Ensure middleware is properly configured
|
||||
- Check tRPC client configuration
|
||||
- Verify protected procedures are using correct types
|
||||
|
||||
## Migration Guide
|
||||
|
||||
@ -292,41 +295,47 @@ CSRF validation failed for POST /api/dashboard/sessions: CSRF token missing from
|
||||
|
||||
1. Update tRPC procedures to use CSRF-protected variants:
|
||||
|
||||
```typescript
|
||||
// Old
|
||||
someAction: protectedProcedure.mutation(...)
|
||||
|
||||
// New
|
||||
someAction: csrfProtectedAuthProcedure.mutation(...)
|
||||
```
|
||||
```typescript
|
||||
// Old
|
||||
someAction: protectedProcedure.mutation(async ({ ctx, input }) => {
|
||||
// mutation logic
|
||||
});
|
||||
|
||||
// New
|
||||
someAction: csrfProtectedAuthProcedure.mutation(async ({ ctx, input }) => {
|
||||
// mutation logic
|
||||
});
|
||||
```
|
||||
|
||||
2. Update client components to use CSRF hooks:
|
||||
|
||||
```tsx
|
||||
// Old
|
||||
const { data, mutate } = trpc.user.update.useMutation();
|
||||
|
||||
// New - no changes needed, CSRF automatically handled
|
||||
const { data, mutate } = trpc.user.update.useMutation();
|
||||
```
|
||||
```tsx
|
||||
// Old
|
||||
const { data, mutate } = trpc.user.update.useMutation();
|
||||
|
||||
// New - no changes needed, CSRF automatically handled
|
||||
const { data, mutate } = trpc.user.update.useMutation();
|
||||
```
|
||||
|
||||
3. Update manual API calls to include CSRF tokens:
|
||||
|
||||
```typescript
|
||||
// Old
|
||||
fetch('/api/endpoint', { method: 'POST', ... });
|
||||
|
||||
// New
|
||||
const { csrfFetch } = useCSRFFetch();
|
||||
csrfFetch('/api/endpoint', { method: 'POST', ... });
|
||||
```
|
||||
<!-- prettier-ignore -->
|
||||
|
||||
```typescript
|
||||
// Old
|
||||
fetch("/api/endpoint", { method: "POST", body: data });
|
||||
|
||||
// New
|
||||
const { csrfFetch } = useCSRFFetch();
|
||||
csrfFetch("/api/endpoint", { method: "POST", body: data });
|
||||
```
|
||||
|
||||
## Performance Considerations
|
||||
|
||||
- **Minimal Overhead**: Token validation adds ~1ms per request
|
||||
- **Efficient Caching**: Tokens cached in memory and cookies
|
||||
- **Selective Protection**: Only state-changing operations protected
|
||||
- **Optimized Parsing**: Smart content-type detection for token extraction
|
||||
- **Minimal Overhead**: Token validation adds ~1ms per request
|
||||
- **Efficient Caching**: Tokens cached in memory and cookies
|
||||
- **Selective Protection**: Only state-changing operations protected
|
||||
- **Optimized Parsing**: Smart content-type detection for token extraction
|
||||
|
||||
## Security Best Practices
|
||||
|
||||
|
||||
Reference in New Issue
Block a user