# CSRF Protection Module

This module provides comprehensive Cross-Site Request Forgery (CSRF) protection for OrdoJS
applications. It implements both session-based token validation and the double-submit cookie pattern
to protect against CSRF attacks.

## Features

- **Session-based CSRF tokens**: Secure token generation and validation tied to user sessions
- **Double-submit cookie pattern**: Alternative protection method using matching cookie and header
  tokens
- **Automatic token injection**: Client-side JavaScript for automatic form and AJAX request
  protection
- **Flexible configuration**: Customizable token expiry, cookie settings, and header names
- **Express.js integration**: Ready-to-use middleware for Express applications
- **TypeScript support**: Full type safety with comprehensive interfaces

## Quick Start

```typescript
import { CSRFManager } from '@ordojs/security';

// Initialize CSRF protection
const csrfManager = new CSRFManager({
  secret: 'your-secret-key-here',
  tokenExpiry: 60 * 60 * 1000, // 1 hour
});

// Generate a token for a user session
const sessionId = 'user-session-123';
const token = csrfManager.generateToken(sessionId);

// Validate the token
const isValid = csrfManager.validateToken(token.value, sessionId);
console.log('Token valid:', isValid.valid);
```

## Configuration

```typescript
interface CSRFConfig {
  secret: string; // Required: Secret key for token signing
  tokenExpiry?: number; // Token expiration (default: 1 hour)
  cookieName?: string; // Cookie name (default: '__csrf-token')
  headerName?: string; // Header name (default: 'X-CSRF-Token')
  fieldName?: string; // Form field name (default: '_csrf')
  secureCookie?: boolean; // Use secure cookies (default: true)
  httpOnlyCookie?: boolean; // Use httpOnly cookies (default: true)
  sameSite?: 'strict' | 'lax' | 'none'; // SameSite attribute (default: 'strict')
}
```

## Usage Patterns

### 1. Session-based Protection

Best for traditional server-rendered applications with user sessions:

```typescript
// Generate token for user session
const token = csrfManager.generateToken(sessionId);

// Add to form
const formHTML = `
  <form method="POST" action="/submit">
    ${csrfManager.generateFormField(sessionId)}
    <input type="text" name="data" />
    <button type="submit">Submit</button>
  </form>
`;

// Validate on form submission
const request = {
  headers: { 'X-CSRF-Token': tokenFromRequest },
  sessionId: userSessionId,
};

const validation = csrfManager.validateRequest(request);
if (!validation.valid) {
  throw new Error('CSRF validation failed');
}
```

### 2. Double-Submit Cookie Pattern

Best for stateless applications or APIs:

```typescript
// Set up double-submit protection
const response = csrfManager.setupDoubleSubmitProtection(sessionId);

// Send cookie and header to client
res.cookie(response.cookies[0].name, response.cookies[0].value, response.cookies[0].options);
res.header('X-CSRF-Token', response.headers['X-CSRF-Token']);

// Validate matching tokens
const request = {
  headers: { 'X-CSRF-Token': headerToken },
  cookies: { '__csrf-token': cookieToken },
};

const validation = csrfManager.validateDoubleSubmit(request);
```

### 3. Client-side Integration

Automatic protection for forms and AJAX requests:

```html
<!DOCTYPE html>
<html>
  <head>
    <meta name="csrf-token" content="your-token-here" />
  </head>
  <body>
    <!-- Forms will automatically get CSRF tokens -->
    <form method="POST" action="/api/data">
      <input type="text" name="value" />
      <button type="submit">Submit</button>
    </form>

    <script>
      // Include the generated client script
      ${csrfManager.generateClientScript(sessionId)}
    </script>
  </body>
</html>
```

### 4. Express.js Middleware

```typescript
import express from 'express';
import { CSRFManager } from '@ordojs/security';

const app = express();
const csrfManager = new CSRFManager({ secret: 'your-secret' });

// CSRF protection middleware
app.use((req, res, next) => {
  if (req.method === 'GET') return next();

  const validation = csrfManager.validateRequest({
    headers: req.headers,
    body: req.body,
    cookies: req.cookies,
    sessionId: req.session.id,
  });

  if (!validation.valid) {
    return res.status(403).json({ error: validation.error });
  }

  next();
});

// Generate token endpoint
app.get('/csrf-token', (req, res) => {
  const token = csrfManager.generateToken(req.session.id);
  res.json({ token: token.value });
});
```

## Security Considerations

### Token Security

- Tokens are cryptographically signed using HMAC-SHA256
- Constant-time comparison prevents timing attacks
- Tokens include expiration timestamps
- Random data prevents token prediction

### Session Management

- Tokens are tied to specific sessions
- Automatic cleanup of expired tokens
- Session isolation prevents cross-session attacks

### Cookie Security

- Secure flag for HTTPS-only transmission
- HttpOnly flag prevents JavaScript access
- SameSite attribute prevents cross-site requests
- Configurable expiration times

## Best Practices

1. **Use HTTPS**: Always use HTTPS in production to protect tokens in transit
2. **Rotate secrets**: Regularly rotate your secret keys
3. **Short expiry**: Use reasonable token expiration times (1-2 hours)
4. **Validate origin**: Consider additional origin/referer validation
5. **Monitor failures**: Log and monitor CSRF validation failures

## API Reference

### CSRFManager

#### Methods

- `generateToken(sessionId: string): CSRFToken`
- `validateToken(tokenValue: string, sessionId: string): CSRFValidationResult`
- `setupDoubleSubmitProtection(sessionId: string): CSRFResponse`
- `validateDoubleSubmit(request: CSRFRequest): CSRFValidationResult`
- `validateRequest(request: CSRFRequest): CSRFValidationResult`
- `generateFormField(sessionId: string): string`
- `generateClientScript(sessionId?: string): string`
- `consumeToken(sessionId: string, tokenValue: string): boolean`
- `removeSession(sessionId: string): boolean`
- `getStats(): { totalSessions: number; totalTokens: number; activeSessions: number }`
- `destroy(): void`

### Types

See `types.ts` for complete type definitions including:

- `CSRFConfig`
- `CSRFToken`
- `CSRFRequest`
- `CSRFResponse`
- `CSRFValidationResult`
- `CSRFSession`

## Testing

The module includes comprehensive tests covering:

- Token generation and validation
- Session management
- Double-submit cookie pattern
- Request validation
- Client script generation
- Error handling
- Configuration options

Run tests with:

```bash
npm test src/csrf/csrf-manager.test.ts
```

## Performance

- Efficient in-memory token storage
- Automatic cleanup of expired tokens
- Constant-time cryptographic operations
- Minimal overhead for validation
- Configurable cleanup intervals

## Compatibility

- Node.js 16+
- Express.js 4+
- Modern browsers (ES2018+)
- TypeScript 4.5+
